Vaadin 24.4 integrates with React, unifies Flow and Hilla development, and more!

Request for Comments - Lazy Data Binding Improvements

Matti Tahvonen
Matti Tahvonen
On Aug 19, 2019 8:25:00 AM
In Product

Vaadin 14 is finally out, but we still have miles to walk on our mission to simplify developer experience. Vaadin shines when it comes to data binding.  Mostly due to the architecture that allows you to put the Java UI code to the same execution environment as your services. But there are things we can do to improve this further. 

I have a couple of improvement ideas I’d like to present, to make connecting data to Vaadin components both easier and better performing. If we can get the ideas and prototypes validated, I hope these will appear in some upcoming Vaadin version in the near future.

What is lazy data binding in Vaadin?

In a server-centric Vaadin code, the easiest way to populate data to components like Grid or ComboBox is to use setItems method with a java.util.List of your entities.  This is a fast and straightforward method, but if you have a lot of data in your components and a lot of users, your server’s memory consumption skyrockets.

To save memory on the server,  Vaadin components like Grid and ComboBox support lazy data binding. It is done using interface called DataProvider or a pair of lambda expressions: the first allows component to request a range of rows from your backend and the other tells how many rows there are in total. 

With lazy data binding, the framework needs to load only a minimal amount of data to the server memory. You can display tens of thousands of rows in your application for many concurrent users without running out of memory. But the system has a couple of annoyances that we could maybe get rid of in the future.

Improvement idea 1: No need to calculate the size of the dataset

Grid and ComboBox components in Vaadin both need to get the number of rows there are in the data set. For a developer, this is an extra method to implement, and for many databases, an expensive operation. Although the count query may be easy to write with SQL, it often forces the database to scroll through all tables. If a Vaadin component would make a minor reduction in UX, we could significantly improve database performance and DX (developer experience).

Together with our framework engineers, I wrote a prototype of this to my Vaadin 8 add-on called Viritin. The prototype appears to work rather well, but the UX drawbacks are there. When you scroll towards the end of the Grid, the scrollbar may make an odd jump as the component notices that more rows are arriving from the database than expected. Also, you can’t scroll directly to the last row, but often one can do that by sorting the Grid. To feel how it could work in real life, try out the live demo

The code difference is visualized below.

On the performance side, the improvement depends on your database and dataset, but in specific scenarios, we can even talk of minutes getting down to milliseconds. Indexes can help database to get the first results quickly, but all rows need to be traversed to count the number of results. Those users who have had this performance issue will remember if for life.

If we end up developing this feature to an upcoming Vaadin version, we will probably make both configurations possible: if you’d need a best possible UX, you’ll need to cope with the count query.

Improvement idea 2: Paged requests

Another improvement idea relates to how Vaadin components access your backend. Currently, the API allows components to access data sets from an arbitrary index with any limit the component decides. The behavior is easy for the component developer and in many cases for you too. But it is a horror for caching (in all levels of your architecture) and for certain backends. For example, the popular Spring Data project gives you “paged access” to your data, which makes the data binding code really complex.

For the same Viritin add-ons LazyGrid, I wrote a prototype that buffers requests inside the grid so that calls to the backend happens in a paged manner, with a page size defined by you. This way the binding code doesn’t require a masters degree in mathematics and is easier for your stack to optimize.

From the before-after code snippets below, you’ll see how much simpler things can get with this change - even though the framework doesn't yet calculate the page number. The limit parameter in the “after” code example will always be 100 as we configure it using the setPageSize method.

Note that both examples above already avoid reporting the size (~ Improvement idea 1), so you can’t write either of with default Vaadin releases today.

Insights appreciated

So, what do you think? Has the lazy data binding been an issue for you? Would these make you more productive? Before we get from prototyping to actual implementation, I want to hear your war stories and ideas about the subject. All channels accepted: fill in the anonymous survey about this topic or write comments to this blog. Or ping me directly with email or twitter and let's chat more!

Lazy data binding survey

Matti Tahvonen
Matti Tahvonen
Matti Tahvonen has a long history in Vaadin R&D: developing the core framework from the dark ages of pure JS client side to the GWT era and creating number of official and unofficial Vaadin add-ons. His current responsibility is to keep you up to date with latest and greatest Vaadin related technologies. You can follow him on Twitter – @MattiTahvonen
Other posts by Matti Tahvonen