Vaadin Application Performance Issues and Solutions
Learn about the challenges that come with building a high-performance and scalable enterprise application as well as how to overcome those challenges.
Join the DZone community and get the full member experience.
Join For FreeThis article is an overview of performance for Vaadin-based web applications. It explains the challenges that come with building a high-performance and scalable enterprise application, and also suggests how to overcome those challenges.
Introduction
Vaadin is a framework for building rich internet applications. According to the official Vaadin book:
“Vaadin is an AJAX web application development framework that enables developers to build high-quality user interfaces with Java, both on the server- and client-side. It provides a set of libraries of ready-to-use user interface components and a clean framework for creating your own components. The focus is on ease of use, re-usability, extensibility, and meeting the requirements of large enterprise applications.”
Vaadin-based applications feel like rich desktop applications with great UI and less page reloads, as they are AJAX-based. The advantage of Vaadin is that developers need to know only Java, as all other things are taken care of by the Vaadin framework itself — so, the development time is faster and no knowledge of other web-related technologies (like JavaScript, CSS, and HTML) is needed.
But when it comes to performance, it poses challenges in certain cases — particularly in enterprise-level applications where the UI is not very simple. We’ll talk about them and find solutions to address those concerns.
Vaadin Architecture
Vaadin provides two development models for web applications: for the client-side (the browser) and for the server-side (web container).
Performance Issues and Solutions for the Client Side
Vaadin client-side framework is based on GWT. The client-Side Engine of Vaadin manages the rendering of the UI in the web browser by employing various client-side widgets. For a simple UI with not many components and layouts involved, there won’t be much performance bottleneck. The problem will be prominent when the page contains multiple layouts, components, tables, etc. For the simplest of components, Vaadin creates a division (<div>
) in DOM with many nested nodes adds extra overhead to that. The problem becomes worse when heavy tables containing multiple components are used.
Considering the performance problems, below are a few suggestions and guidelines that can be followed while designing a page in Vaadin.
Check If It's Really Required to Show Everything in One Page/View
Going by simple calculation, the more loads we add to DOM, the more sluggish the rendering will be. While designing a page, it is very important to think about how much load can be added to a page without compromising the requirement and usability. Yes, it is absolutely mandatory to design the UI as per the end-user — but because of technical limitations, sometimes we need to weigh the trade-off between usability and performance. Sometimes, from the user point of view, it may be better to interact with the application in multiple pages rather than waiting long for unresponsive pages. How can this be done? There could be many lazy-loading techniques one can utilize, like:
Click an icon to show the data lazily in a pop-up instead of showing on page load.
Show/hide the information (columns in a table, any layouts/sections, etc.).
Logically split the information into multiple pages instead of one page.
If possible, show the information as plain text and on demand, show the actual components.
Optimize the Layout and Component Usage
Utmost care should be taken when designing the layouts of a page, as more layouts means performance overhead.
Check and remove any unnecessary and extra layouts added to a page.
Use CSS layout wherever possible to achieve maximum performance compared to other layouts like horizontal layouts and vertical layouts.
Avoid using vertical layouts inside another vertical layout when possible.
Use vertical or horizontal layouts instead of grid layouts, but use a single grid layout instead of multiple nested vertical and horizontal layouts.
Consider using one component instead of many (i.e., instead of using one label per line, use a label with multiple lines using HTML —
label.setContentMode(Label.CONTENT_XHTML
).
Usage of Images
In many web applications, images play an important role because of business requirements. But while designing the UI, we need to ask ourselves whether the images are of very high resolution on all the pages. If not, then we need to optimize the usage.
Use images of different resolutions on different pages based on the requirements. For example, lower-resolution and smaller images can be used on pages where it is not required to show them as full-blown images.
Use Text-Based Icons Instead of Images
As text-based icons are lightweight; it is better to use them against the images.
Use Grids Instead of Tables
Grids are a more optimized component compared to the old table component. Also, there will be more enhanced features coming up for grids, and tables will no more be enhanced and supported. There are certain issues in the table component — for example, it regenerates the complete table even if it is not required in certain cases, which adds to performance overhead.
Optimize the Usage of Tables
Usage of many components inside tables will certainly take a toll on performance. Try avoiding adding more components to a table. Instead, inline editing mode can render the components lazily as text and based on clicking, we can render the actual components of a row.
Additionally, instead of loading hundreds of rows at once, it is better to use pagination to load the data.
Performance Issues and Solutions for the Server Side
The server-side framework holds the UI logic and state of every client within a Vaadin Session. UI is a viewport to a Vaadin application running on a web page. Each and every component, event listener, layout, data model, etc. that is part of one UI instance is stored in session. As many browser tab/window instances the web application is accessed on is how many UI instances will be created and added to the session. If the UI is heavy, then there will be server-side performance overhead, as the memory will be occupied with Vaadin sessions containing multiple UI instances. Moreover, for every user interaction, a request has to be sent to the server to let the client know how it should react. This increases network traffic and CPU usage. So, Vaadin architecture is not very scalable compared to other client-side frameworks (i.e. AngularJS).
To solve this problem, we can think of the below guidelines when implementing server-side components.
Use Fewer Components and Make the UI Simple
While designing front-end web pages using Vaadin, we should consider using fewer components and avoid using heavy components like combo-boxes inside tables and grids. Components such as combo-boxes are like containers that hold the references of POJOs used to represent data fetched from the back-end. It is very important to de-reference the objects from UI after use so that heap memory will be able to accommodate space for newer objects. For example, if the UI requirement is to show many components in a table, then we can use inline editing option (as mentioned previously) and the objects of the previously selected row can be de-referenced to improve server side performance.
Use the Right Container
There are many containers available in Vaadin, like BeanItemContainer
, IndexedContainer
, etc., but they should be judiciously chosen based on the requirement.
Though BeanItemContainer
is probably the easiest one to use when Java beans are used as models, it comes at a performance cost. For each property of the bean, the container creates MethodProperty
, and if the data set is huge, then the heap memory gets bloated. In that case, we should opt for an alternative container like IndexedContainer
, which increases the performance.
Also, it is better to share containers between combo-boxes or any container-based components in which the same data can be shared as a source, which will improve performance. For example, if any particular combo-box needs to be present for each row of a table, then instead of assigning separate containers to all those combo-boxes, we can use one shared container.
Caution: Adding items to a shared container will reflect in all combo-boxes using that container. Based on the business needs, this approach can be taken.
Use the Right Data Model
Sometimes, the data models or beans contain many unwanted and unnecessary properties (which may come from a super class) that make them heavy. So, we structure our models in such a way that only required fields are present.
Remove Event Listeners If They're Not Required
We should clean up the event listeners explicitly after closing the UI,as Vaadin doesn’t instantly remove them. If we are adding ValueChangeListners
to generated columns in a table, then such listeners should be removed when the generated components are detached from the UI. Otherwise, the listeners will accumulate in the container when the table is scrolled back and forth, causing a possibly severe memory leak.
Opinions expressed by DZone contributors are their own.
Comments