Learn what a render does, which cells it covers, what it costs, and when you need to call render() yourself.
Background
Handsontable does not keep every cell of your data set in the DOM. It renders only the part of the grid that you can see, plus a small buffer around it. As you scroll, it reuses the same DOM elements for new cells. This is called row virtualization and column virtualization, and it is what lets the grid hold hundreds of thousands of records without freezing the browser.
A render is the step that brings those DOM elements back in sync with your data and your configuration. Handsontable runs it for you at the right moments, so most applications never call render() at all. You need it when you change something that Handsontable cannot detect on its own — cell metadata, or a value outside the grid that one of your renderers reads.
How it works
What a render does
A render recalculates the grid’s layout, redraws its cells, and applies the result to the DOM. For every cell it draws, Handsontable:
Resets the cell’s td element to a blank state.
Resolves the cell’s metadata, which includes running the cells function if you defined one.
Runs the cell’s renderer, which writes the value, the CSS classes, and any other markup.
A render redraws the grid in place. It does not change your data, your selection, or your scroll position.
So on a grid of 100,000 rows showing 30 of them, a render redraws those 30 rows and the buffer around them. It does not touch the other 99,970.
Two options change this. If you set renderAllRows or renderAllColumns to true, you turn virtualization off on that axis, every row or column lives in the DOM, and a render then covers all of them.
What a render costs
The cost of a render scales with the number of cells it draws, multiplied by the work your renderers and your cells function do for each of them. The number of records you hold is not what drives it.
This has two consequences:
A render on a grid with 1,000,000 records costs about the same as a render on a grid with 100 records, as long as both show the same number of cells. (Handsontable still keeps some per-record caches, such as row heights, so a render that has to rebuild one of them costs more.)
Work you put inside a renderer or inside the cells function runs again on every render, for every drawn cell. A small cost there adds up quickly. See Avoid the cells option when possible.
What makes an application slow is rarely one render. It is many renders in a row, which is what batching exists to prevent.
When Handsontable renders on its own
Handsontable picks the moments for you. It renders after every CRUD operation, while you scroll, when rows or columns are hidden or trimmed, and at the end of updateSettings(). Anything that changes the grid through the Handsontable API is covered.
When you call render() yourself
Call render() when you change something that Handsontable cannot detect. The common case is setCellMeta(), which writes to the cell’s metadata but does not repaint the grid: