22

I have a grid with a large but reasonable amount of data (approx 12,000 cells... 340 columns and 34 rows). I know that seems like a sideways table but it just happens that for our application, it's more likely to have tons of columns and fewer rows.

When the data was about 2300 cells (68 columns and 34 rows), it was fast enough that I could call it "immediate". Nothing I'd worry about.

enter image description here

Increasing it 5x has caused an exponential increase in initial render time. Specifically, the creation of the columns takes forever, within the recursivelyCreateColumns method.

enter image description here

Going to 10x causes it to take a few minutes to complete. Going to 20, it didn't crash but after 5 minutes it was still going and I suspect it was going to take an hour or more.

My question is, even though my code to create the grid column/row/data for AG-Grid to process runs in the 20ms range, is there something I can do to make it easier for AG-Grid to create the columns? Maybe have it only create the columns when necessary?

My grid setup is as follows:

var gridOptions = {
    enableCellExpressions: true,
    columnDefs: data.header,
    rowData: data.body.data,
    floatingTopRowData: data.body.floatingTopData,
    rowHeight: 25,
    headerHeight: 25,
    enableColResize: true,
    enableSorting: true,
    enableFilter: true,
    getNodeChildDetails: function(rowItem) {
        if(rowItem.items) {
            return {
                expanded: scope.gridOptions.rowData[0].something === rowItem.something,
                group: true,
                field: "something",
                key: rowItem.something,
                children: rowItem.items
            };
        }
        return null;
    }
};
oooyaya
  • 1,773
  • 1
  • 15
  • 39
  • What version of ag-Grid are you using? From your config you should have column virtualisation on, which would mean that the only cols rendered are the ones visible. The volumes you're talking about shouldnt be a problem here – Sean Landsman Oct 21 '16 at 18:56
  • Version 6.1.0. Specifically the minified version. I'm plugging it in to Angular 1.4.7 (can't upgrade Angular) but my testing shows it seems related only to AG-Grid so I'm not too worried about the Angular part. – oooyaya Oct 24 '16 at 13:06
  • Also, if it matters, each column is a 5-tier group. Meaning `column = {headerName: "something", children: [{headerName: "something2", children: [{headerName: "something3"....` – oooyaya Oct 24 '16 at 13:19
  • If I make it a single tiered column (no Column Grouping) then it remains nearly immediate, even if I go to 50x the data (3303 columns!). Problem is, I absolutely need this tiering. Previous experiments using a separate header table as a slave were not going to solve other problems. – oooyaya Oct 24 '16 at 14:28
  • do you have a plunker I can take a look at? I can take a look and see if I can identify the problem. I'm sure we can find out whats going on here and resolve it for you – Sean Landsman Oct 24 '16 at 19:55

4 Answers4

7

Check ag-grid Performance documentation

I copied it here for quick access:

Performance

ag-Grid is fast. However ag-Grid can also be configured and extended in many ways.

Often people come to the ag-Grid forum and ask 'why is the grid in my application not that fast?'.

This page explains how you can make the grid go faster.

1. Setting Expectations ag-Grid can be as fast as demonstrated in the demo application Demo Application. You can resize the demo application to the same size as the grid in your application by resizing the browser, then navigate around the grid (scroll, filter etc) and see how fast the demo grid is compared to your own implementation. If the demo grid is going faster, then there is room for performance improvements.

2. Check Cell Renderers ag-Grid can be slowed down by your custom cell renderers. To test this, remove all cell renderers from your grid and compare the speed again. If the grid does improve it's speed by removing cell renderers, try to introduce the cell renderers one by one to find out which ones are adding the most overhead.

3. Create Fast Cell Renderers The fastest cell renderers have the following properties:

The grid rendering is highly customised and plain JavaScript cell renderers will work faster than framework equivalents. It is still fine to use the framework version of ag-Grid (eg for setting ag-Grid properties etc) however because there are so many cells getting created and destroyed, the additional layer the frameworks add do not help performance. Plain JavaScript cell renderers should be considered if you are having performance concerns.

Not everyone needs blazing fast cell renderers (eg maybe you have users on fast machines with fast browsers, or maybe your grids have few columns) in which case framework cell renderers may work fine. The suggestion of not using frameworks for cells is only applicable when you are looking to squeeze performance gains.

Using frameworks for cell renderers can be slower because of the large number of cells getting created and destroyed. Most of the time a cell will not have complex features in it, so using plain JavaScript should not be a problem. For all other components (filters, editors etc) using the frameworks won't make much noticeable difference as these components are not created and destroyed as often as cell renderers.

4. Turn Off Animations Row and column animations make for a great user experience. However not all browsers are as good at animations as others. Consider checking the client's browser and turning off row and column animation for slower browsers.

5. Configure Row Buffer The rowBuffer property sets the number of rows the grid renders outside of the viewable area. The default is 10. For example, if your grid is showing 50 rows (as that's all the fits on your screen without scrolling), then the grid will actually render 70 in total (10 extra above and 10 extra below). Then when you scroll the grid will already have 10 rows ready waiting to show so the user will not see a redraw (not all browsers show the redraw, only the slower ones).

Setting a low row buffer will make initial draws of the grid faster (eg when data is first loaded, or after filtering, grouping etc). Setting a high row buffer will reduce the redraw visible vertically scrolling.

6. Use Chrome The grid works fastest on Google Chrome. If you can, tell your users.

7. Understand Data Updates For fast changing data, consider using Batch Update Transactions which allows the grid to take very large amounts of updates without bringing the browser to a crawl. This is also demonstrated in the blog Streaming Updates in JavaScript Datagrids that shows hundreds of thousands of updates per second.

8. See Also Read the article 8 Performance Hacks for JavaScript so you know what the grid is doing, that way you will be able to reason with it.

9. Debounce Vertical Scroll By default, there is no debouncing of the vertical scroll. However on slow browsers, especially IE, depending on your application, you may wish to debounce the vertical scroll.

To debounce the vertical scroll, set grid property debounceVerticalScrollbar=true.

Salma Tofaily
  • 113
  • 1
  • 5
4

Not sure if it's directly related to OP's question, but there is a general performance issue in ag-grid, which seems like a massive engineering oversight - even simply hovering the rows at a rate of approximately 10 rows per second eats 33% of the JS thread resources.

enter image description here

Issue can be reproduced on their main page, ag-grid.com.

If you compare it with other grids, you'll see no performance hit when hovering the rows. For example, this grid:

Same hover pattern results in only <3% of JS thread usage.

enter image description here

Why is this important? Because users will be hovering a lot more than clicking.

Victor Zakharov
  • 25,801
  • 18
  • 85
  • 151
  • The example you are linking is 12 lines per 3 columns. Do you have a bigger example? – Artur Carvalho Feb 22 '23 at 08:40
  • @ArturCarvalho Check Devexpress https://js.devexpress.com/Demos/WidgetsGallery/Demo/DataGrid/Overview/Angular/Light/ – Victor Zakharov Feb 22 '23 at 13:18
  • Aggrid events use too much memory. After changing my callback from aggrid to js click event, it stopped causing a ram usage spike. Much faster as well. I tried doing my tab from js keydown event as well but sadly there is no way to suppress the default tabbing behaviour of aggrid without a callback returning null, which would eat the ram anyway. – SpicyCatGames Jul 22 '23 at 05:53
2

Row Virtualisation

Row virtualization means that we only render rows that are visible on the screen. For example, if the grid has 10,000 rows but only 40 can fit inside the screen, the grid will only render 40 rows (each row represented by a DIV element). As the user scrolls up and down, the grid will create new DIV elements for the newly visible rows on the fly.

If the grid was to render 10,000 rows, it would probably crash the browser as too many DOM elements are getting created. Row virtualization allows the display of a very large number of rows by only rendering what is currently visible to the user.

The image below shows row virtualization - notice how the DOM only has 5 or 6 rows rendered, matching the number of rows the user actually sees.

enter image description here

Column Virtualisation

Column virtualization does for columns what row virtualization does for rows. In other words, column virtualization only renders the columns that are currently visible and the grid will render more columns as the user scrolls horizontally.

Column virtualization allows the grid to display large numbers of columns without degrading the performance of the grid.

Performance Hacks For Javascript

AG-Grid Row Models

Hariom Mangal
  • 55
  • 1
  • 9
2

I know most people won't experience this but it can definitely save someone time - make sure you check the performance with dev tools closed. I found out that when dev tools were open the UI was stuck, but when closed it was fast.

You can also manually give the gridOptions rowBuffer which can help too.

Yair Cohen
  • 2,032
  • 7
  • 13