Since many of our clients are quite busy and have lots and lots of data - I thought I should ask about performance.
How is data loaded by the various components of the UI? For example, we’re using a Calendar control for our scheduling - how does it load data? Is it going to try to load all tens of thousands of records, or does it load as it needs to display? Ditto for the browse screens, lookup/picker fields, and so on.
Some of our clients have data back to 1994 and we intend to do a full load for them when the CUBA version is done, so…
You always have control over what will be loaded in your application screens. Screen Dataloaders will define how data is loaded (and when). It is not the same for cuba screens and components like generic filter, for example.
I’ll share some tips related to performance based on my experience. It should help you in both cases (your screens and cuba screens and components).
Enable debug for SQL queries for local development (tomcat/conf/logback.xml or app_home/logback.xml file, depending on which version you are using)
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<!-- End CUBA -->
<logger name="eclipselink" level="WARN"/>
<logger name="eclipselink.sql" level="DEBUG"/>
After enabling, inspect the screens that you think will need a better performance. That’s the way I started identifying most of the problems related to SQL performance (tips below).
Create specific views for each need, loading only the required data. Avoid using the same view for browse and edit screens, for example. Edit screens almost always needs to load more data than browse screens.
Use Screen instead of Dropdown for selecting entities with a lot of records. If you have already generated the screens, remove the generated collections and change the components in the form from lookupPickerField to pickerField. When using Dropdown, cuba will load all records and filter the results in memory based on user input.
Enable entity statistics. Based on statistics data, cuba defines which UI component to use to select a given entity (screen or dropdown). When dropdown is used (default, when entity cache is not used) all the instances are loaded in memory when the screen is opened. This feature is very useful to control which component is used in generic filter.
Consider using Entity Cache when items 3 and/or 4 is not an option (usability).
Complex screens sometimes need to load a lot of data. Try to load data on demand when possible (when switching tabs, for example).
Neither Calendar nor any other UI components load data directly - they display what is loaded in data containers, normally using data loaders. For example, here in the screen XML descriptor you can see the JPQL query that is used to load calendar events. You can restrict the query however you want.
Ok - so how do data containers/data loaders handle data? Do they load in pages, or do they simply load everything in the database all at once? I’m talking about just a normal, Studio-generated screen - will that simply load the entire database, or does it do some kind of paging or similar for performance?
Data loaders just execute the query and also take into account their firstResult / maxResults properties (see XML attributes and corresponding methods of the CollectionLoader interface). These methods are used for paging by the RowsCount component which is the part of tables. So normally your browse screens load only one page at a time.
Calendar doesn’t control loading like table does, so you are right - it may cause performance problems. We will prepare an example of how to control the loader paging properties according to calendar switching events.
Just to follow-up with this, I implemented loading by displayed dates in the scheduler. In day view, it only loads data for that day; week view, the week; month view, the month. It works quite well and was extremely easy to set up.