Performances in displaying a thumbnail view

Hi,

I am using Vaadin 7 to create a prototype application to evaluate if Vaadin is the right framework for a large scale application.
We already successfully use Vaadin for another product and we are happy with it.

I am trying to display a thumbnail view of several (about 100-400) dynamic loaded images (see attachment).
I achieve this doing the following:

for (Item item : collection.getItems ())
{
CssLayout itemView = new CssLayout ();
itemView.setWidth (“120px”);
itemView.setHeight (“120px”);

        StreamResource.StreamSource streamSource = new StreamResource.StreamSource ()
        {
            public InputStream getStream ()
            {
                return new ByteArrayInputStream (item.getBytesAsJPEG (120));
            }
        };
        Embedded embedded = new Embedded ("", new StreamResource (streamSource, "record-" + item.getID () + ".png"));
        itemView.addComponent (embedded);

        thumbnailView.addComponent (itemView);

}

I use CssLayout because should be the fastest layout available but when the number of elements is > 200 I am getting a very slow and not responsive UI.
I logged the time spent on this loop and is in the order of 300ms; the building of the thumbnail view needs a couple of seconds and this is currently not enough performing for our needs.

Do you have any suggestions to improve the performances?

Thanks in advance,
Christian
12632.jpg

Have you already measured the time it takes for the browser to load the bulk of all the individual images? You have to keep in mind, that a browser can only have a limited amount of parallel server connections open at the same time. So, a large number of images will be loaded more or less sequentially by the browser. If this is the source of your performance issue you could consider to put all your thumbnails into one large image and have that separated again by the browser using CSS image clipping (the way it is done by GWT’s ImageBundle).

As per Roland’s response, it’d be interesting to see what happens if you exclude the “image loading” time.

What happens (for test purposes, obviously) if you make all of the images the same image - so that the browser caching means the image is only loaded once?

Cheers,

Charles.

ps: do you actually need the CSSLayout at all? Why not add the Embedded for the image directly to the thumbnailView?

If you go to hundreds of thumbnails and performance turns out to be a problem, I would suggest considering to implement a custom Vaadin widget for that view. This requires learning some client side programming (GWT), but would enable the client side widget to request only the currently visible thumbnails from the server (based on scroll position). That way, you can scale as high as you want without visible degradation of performance. Using a custom widget also enables doing other optimizations if necessary.

If you want to cache the thumbnails currently not on screen, the client side widget could request them after getting the visible ones.

I would recommend developing the widget as a separate add-on, whether you plan to publish it to others or not. This way, you can make the code more modular and cleanly separated from the application. Of course, contributions from the community are always welcome.

There are some add-ons such as the one-dimensional
ImageStrip
that you could use as a starting point. It also supports animations, automatic scaling on the server side etc, so the code could be simplified in your case.

First of all thanks for the fast replies.

I use nested CssLayouts because I want actually add some metadata to image that I want to deliver but I removed them from the example code.

I tried some time measuring and seems that the loop itself that adds (addComponent call) the inner CssLayouts to the main layout take several seconds (about 8-15 s) for something like 100 thumbnails!
For something like 30 elements needs some hundreds milliseconds and the browser refreshs the view really quickly. Over 100 the application is really not usable anymore.

I tried even eliminating the Embedded class and using just one label for every CssLayout but it didn’t really helped.

It seems that the time the frameworks needs to add components is not scalable.
Probably the adding of components produces a lot of dimensioning calculation with the sibling components that causes this not linear overhead?

I already thought to building a GWT widget for the view that does the lazy loading of the data following the scroll (like the Vaadin table does) but I am afraid would be quite complicate and I have no experience with the Vaadin 7 widget building.

I was hoping to build a fast prototype to compare different frameworks/approaches but I already smashed on this performance problem :frowning:
If there are no other suggestions I will try to have a look to the ImageStrip addon and the Table source code and I will try to build a lazy loading flow layout component.

Thanks,
Christian

That sounds very strange - adding the components should be quick.

What is the top-level layout into which you are adding the CssLayouts? If it is a GridLayout, maybe there is a problem in the scalability of the code that checks for overlaps (it does a full check for every component added, which gets progressively more expensive) - there shouldn’t be any size calculations etc. on the server side at that point.

Maybe you could try using a CssLayout also on the top level, using CSS to make the thumbnails flow to the next row. If the problem is indeed in the overlap check of GridLayout, this should be orders of magnitude faster.

I am using a CssLayout to wrap the thumbnails (I know this suggestions: https://vaadin.com/wiki/-/wiki/Main/Optimizing%20Sluggish%20UI)

I am currently loading just 20 thumbnails per page to have a quite fast user experience.

Now I am facing an additional problem with the Embedded class, I use:
final Pixmap thumbnail = item.getPicture();
StreamResource.StreamSource streamSource = new StreamResource.StreamSource ()
{
public InputStream getStream ()
{
return new ByteArrayInputStream (thumbnail.getAsJPEG (120));
}
};
StreamResource resource = new StreamResource (streamSource, “record” + item.getCatalogID () + item.getID () + “.png”);
resource.setCacheTime (36000);
Embedded embedded = new Embedded (“”, resource);

But occasionally I get the following warnings:
WARNING: Global resource legacy/2/recordXXXX.png not found

In these cases I get a 404 in retrieving the thumbnail… Do you know what it could be the cause?

Thanks,
Christian

Hello everyone
I am using the ImageStrip to display a thumbnail in my page footer, this works great and is fast, thanks for this widget.
My requirement is to automatically scroll the images at some set interval, something like a rotating banner. Is there a way to do this ? Also, I would like to hide the navigation buttons since I would like to auto scroll without users having to click the nav buttons to scroll the images.
Is there a way to do this or another widget I can use to accommodate this functionality?

Thanks