Gridx in XPages – 20: Improving Memory Management with Virtual Scrolling

Gridx will render DOM elements for every row in the data store by default, but this can be a very inefficient use of memory and can hurt performance. In this post, I’ll show how to add virtual scrolling to the grid in order to minimize the number of DOM elements required at any given point for displaying the data.

Gridx Series

Gridx in XPages — Entire Series

VirtualVScroller

As the number of rows in the data store increases, you may start to notice more of a lag in rendering the grid. This is because it renders every row in the store. This generates far more DOM elements than you could see on the page at one time, so it’s highly inefficient.

Fortunately, there is an extremely simple way to streamline the amount of rows that are rendered — the VirtualVScroller module.

All you have to do is add it to the grid and it does the work automatically.

1. Require Module

The first thing you need to do is include the VirtualVScroller module in the require statement.

"gridx/modules/VirtualVScroller"

2. Include Module in Grid

To make it available to the grid, add it to the grid’s modules list.

modules: [  
  Resizer,
  NestedSort,
  Filter,
  FilterBar,
  QuickFilter,
  VirtualVScroller
]

3. Define the Buffer Size

Next, you need to define the size of the buffer to maintain in memory. This is specified in the vScrollerBuffSize attribute of the grid.

The buffer size is the amount of rows it will render before and after the rows that you can see in the grid. It defaults to 5, but the documentation says to increase it to 10 or 20 if scrolling isn’t smooth enough. The tradeoff is scrolling smoothness vs the number of rows to render each time.

grid = new Grid(
{
  id: "my_gridX",
  cacheClass: Cache,
  store: store,
  structure: columns,
  vScrollerBuffSize:10,
  modules: [
    Resizer,
    NestedSort,
    Filter,
    FilterBar,
    QuickFilter,
    VirtualVScroller
  ]
});

Results

In my sample grid (with a data store of about 1,300 rows), it was rendering 13,160 DOM elements before the virtual scrolling and only 313 DOM elements after scrolling! It is clear to see how this is a significant boost in efficiency for the grid.

If you want to perform a similar test, you can determine the number of elements by using this statement in the browser console:

document.getElementsByTagName("*").length

Advertisements

5 responses to “Gridx in XPages – 20: Improving Memory Management with Virtual Scrolling”

  1. Petter Kjeilen says :

    Hi Brad! Thanks for these great articles. How big datasets can this new grid handle ? Would it handle 100000 records with sorting (json comming via RESTService) ? Will the grid render before all records are loaded ? Thanks !

    • Brad Balassaitis says :

      Thank you very much!

      I have not tested a data set that large, but this feature comparison page says that it’s been tested with over 1 million records and performs fine with the virtual scrolling enabled.

      Of course, the main challenge at that point would just be the time it takes to load all of that data into memory, but if that’s efficient enough for you, then it should work well.

      The way my examples (like this one https://xcellerant.net/gridx-in-xpages-8-column-sorting-with-a-local-data-store/) have it set up is that it waits for the REST call to be completed and return data before proceeding to instantiate the grid.

      • Petter Kjeilen says :

        I remember when working with extjs grids that it was possible to spesify how many records to fetch pr request. E.g if you’d spesify 1000 records pr requests and there were 25000 records, extjs store would automatically send 25 requests with parameters start=0&stop=1000 , start=1001&stop=2000 etc.. The grid displaying data from the grid would render as soon as the first 1000 records were fetched. This means you could load really large datasets quite fast. Anything similar possible with gridx ?

      • Brad Balassaitis says :

        I haven’t seen a built-in attribute for it, but a few things come to mind that may work. You could set up paging module of the grid and specify the page size. The JSON REST data store allows you to write queries and specify the starting position and count, so you may be able to use that to get the same effect, but I haven’t tried it.

        http://dojotoolkit.org/reference-guide/1.8/dojo/store/JsonRest.html

  2. wasjavaguy says :

    Hi Brad,

    Great article – thanks for your efforts!

    I’m using gridx with virtual scrolling and I have an example of a grid with 162 rows x 30 columns with a lot of in-cell renderers as well as hierarchical view with Tree. For the most part it is working good, but I have a use case where I’m looping through all 162 lines, doing some calculations and calling setRawData for each row. For all visible rows, this ‘setRawData’ call is taking about 150-400ms per row, then for rows not currently buffered (buffer is default of visible + 5), those take 0-1ms to call ‘setRawData’. I’m wondering if there’s another approach to this? Maybe I can do something to tell the grid not to render rows immediately when calling setRawData, but instead, render them all at the end of the loop? Do you think this will even help? Have you dealt with this issue before?

    Thanks,
    Steve

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: