JavaScript performance with layouts.

Hello guys,

I’ve some performance issue with a simple page.

Server side goes fast, and network traffic is minimal (according to firebug).
But it’s so slow that Firefox proposes me to “stop the non responsive script”. I press continue and it works.
Resizing the browser width is not fast.

Here is the screen.

http://screencast.com/t/FdS9E8m3jfeg

Here is how I construct it:

Both columns are placed in an Horizontal Layout.
Each column is a VerticalLayout.
A list is a vertical layout with a title (i.e. “Alphabatical”) and many HorizontalLayouts (one per line).
In each line we have a topic name (i.e. “Swing LayoutMaff ffnagers”),
then a VerticalLayout with 0 or more courses (i.e. “Workshop”, “Course”, “Course”),
then a VerticalLayout with 1 or more exams (i.e. “Swing”, “Aspect”, “Algorit” on the screenshot).

Each item (topic title, course name, exam name) is a link.
The width is per pixel in my code.

Here is the code.

public class TopicListScreen extends HorizontalLayout {

	@Autowired TopicDao topicDao;
	
	
	public TopicListScreen() {
		setSpacing(true);

		VerticalLayout col1 = new VerticalLayout();
		this.addComponent(col1);
		TopicList mostPopular = new TopicList("10 Most Popular", topicDao.getMostRecent(10));   // TODO: get the list or most active from topicDao or topicService. We need first to define what is an "active" topic. We cannot do complex queries for the home page. Maybe a batch?
		mostPopular.setStyleName("black");
		col1.addComponent( mostPopular ); 
		col1.addComponent( new TopicList("Alphabetical", topicDao.getAllTopicsByName() ) );

		VerticalLayout col2 = new VerticalLayout();
		this.addComponent(col2);
		col2.addComponent( new TopicList("By group", topicDao.getAllTopicsByName() ) );
		col2.setMargin(false);
	}


	class TopicList extends VerticalLayout {
		TopicList(String caption,List<Topic> topicList) {
			setWidth("400px");
			setMargin(true);
			
			addComponent(ComponentFactory.createTitle(caption, 2));
			
			int row = 0;
			for (Topic topic : topicList) {
				HorizontalLayout hLayout = new HorizontalLayout();  // one topic row
				hLayout.setWidth("100%");
				addComponent(hLayout);
				
				// Topic title
				Link topicTitle = new ScreenLink(topic.getName(), ScreenName.TOPIC, topic);
				topicTitle.setWidth("240px");
				hLayout.addComponent(topicTitle);

				// Courses
				VerticalLayout courseLayout = new VerticalLayout();
				courseLayout.setWidth("80px");
				hLayout.addComponent(courseLayout);
				for (Course course : topic.getCourses()) {
					Link courseTitle = new ScreenLink(course.getPostFixName(), ScreenName.COURSE, course);
					courseLayout.addComponent(courseTitle);
				}

				// Exams
				VerticalLayout examLayout = new VerticalLayout();
				examLayout.setWidth("80px");
				hLayout.addComponent(examLayout);
				for (TestDef testDef : topic.getTestDefs()) {
					String linkName;
					if (topic.getTestDefs().size() == 1) {  // Most cases: we just write "exam" (next to the topic name).
						linkName = "exam";
					} else {
						linkName = testDef.getLabel();
					}
					Link courseTitle = new StrutsLink(linkName, testDef);
					examLayout.addComponent(courseTitle);
				}
				row++;
			}
		}

	}

I probably break some sanity rule. I guess the page does not have too much text. I must probably do something wrong with layouts. Do you have any advice?

Thanks.
John.

I’m not sure about the real problem here, but you could try to change some of the smaller layouts (e.g. VerticalLayouts with only a couple of components) to
CssLayout

While HorizontalLayout and VerticalLayout are very flexible, nesting a large number of them in each other can cause performance issues. Unfortunately, your layout seems to be hitting the limits already. As mentioned by Risto, CssLayout can help here.

For an example of the use of CssLayout with the CSS in your theme, see e.g.

Sampler CssLayout example
.

By moving the sizes to CSS and eliminating unnecessary higher level layouts you can optimize this even further.

Here is a sample CSS for using CssLayout in your case:


.topiclabel,
.courselayout,
.examlayout {
    /* both are needed for this to work both on IE and other browsers */
    display:inline;
    float:left;
}

.topiclabel {
    width: 240px;
}

.courselayout,
.examlayout {
    width: 80px;
}

.courselayout .v-label,
.examlayout .v-label {
    float: none;
    display: block;
}

You can find some more optimization hints in
this blog post
and
this wiki page
.

Thank you guys.

The blog/wiki article is very helpful. I’ll try that later in the day and it’ll probably fix the problem.

These tips have been helpful, thank you again guys.

Thanks to using a GridLayout for the 3 columns list (topic name, courses, exams), it runs in 5 seconds. It is still much but it’s ok.
The grid layout replaces the HorizontalLayouts (one per topic).

I’ve replaced classic layouts by CssLayouts in some other pages and it helped greatly.

John.

If you still feel the need to optimize, you could try replacing GridLayout with a FastGrid from the FastLayouts incubator-project. The FlowLayout from that project already (if I understood correctly) transferred to trunk as CssLayout, so FastGrid should be pretty stable.