Figure 1. Data Grid with 1,000,000 rows
Fast Data Grid Features:
- Incredibly Fast
- Multithreaded
- Only 523 Lines of Code
- No Dependencies
- Vanilla JavaScript
Try scrolling and searching through 1,000,000 rows - Fast Data Grid.
In this article I will list the nuances of working with DOM. About multithreading in the next article.
The smaller the DOM, the better. Changing the contents of a DIV is faster than deleting a DIV and creating a new one.
The browser is slow in rendering a large DOM tree. The browser won't render 1,000,000 lines of 20 px height at all - the maximum height of a DIV in Chrome is 15,000,000 px. The fewer HTML elements, the better.
Fast Data Grid adds as many rows to the DOM as will fit on the screen.
const rowsCount = Math.ceil(viewPortHeight / rowHeight);
Listing 1. Counting how many lines fit on the screen
When new data needs to be output, the row DIVs are reused. New data is written to the same DIVs. Changing the contents of a DIV is faster than deleting a DIV and creating a new one.
When scrolling, the position of the DIV rows is calculated using JavaScript.
Maximum DIV height is 15,000,000 px
To make the scroll work, Fast Data Grid makes a big DIV. The scroll event is attached to this DIV. The scroll event handler calculates the position of the row DIVs.
Figure 2. Large DIV for scrolling
If the total height of the rows is more than 15,000,000 px, then the row DIVs should scroll faster than the big DIV. When the big DIV scrolls to the end -> the row DIVs should also scroll to the end.
When scrolling DIV rows, a coefficient must be applied.
const scrollYKoef =
// if {allRowsHeight} > 15 million -> we have to applay koef on scroll
// if {allRowsHeight} <= 15 million -> {scrollYKoef} = 1
(allRowsHeight - viewPortHeight) / (scrolHeight - viewPortHeight);
listen(scrollOverlayDiv, 'scroll', /** @param {Event & {target:HTMLDivElement}} evt */ evt => {
const scrollTop = evt.target.scrollTop * scrollYKoef;
rowsDiv.style.transform = `translateY(${scrollTop}px)`;
});
Listing 2. Using the coefficient when scrolling
CSS transform translate is faster than CSS top
When scrolling, the position is set via transform translate. CSS transform translate is faster than CSS top.
<!-- transform faster-->
<div style="transform: translateY(-16px);"></div>
<!-- than top -->
<div style="top: -16px;"></div>
Listing 3. CSS transform translate is faster than CSS top
Read DOM first, then modify DOM. It's bad to read DOM after modification
The browser displays frames on the monitor like this:
First, JavaScript is processed, then styles are calculated, then layout, then rendering.
Figure 3. Standard order of operations when outputting a frame to the monitor
If the standard order is not violated, the browser will render the frame as quickly as possible.
At the beginning of the cycle, the DOM parameters are already calculated and correspond to the parameters of the previous frame. For example, box.offsetHeight is already calculated at the beginning of the cycle. But if you change the DOM and then read the DOM -> the browser will have to break the standard order. It will be necessary to calculate the layout again.
box.classList.add('super-big');
// Gets the height of the box in pixels and logs it out:
console.log(box.offsetHeight);
Listing 4. Modifying DOM before reading DOM. Bad. Leads to layout thrashing.
Excessive recalculation of Layout is called “layout thrashing”.
A visual demonstration of how modifying the DOM before reading slows down the browser:
https://wilsonpage.github.io/fastdom/examples/animation.html
Great article on the topic:
Avoid large, complex layouts and layout thrashing | Articles | web.dev.
Self-promotion
I make the most convenient flowchart editor DGRM.net.
It is also the most convenient service for business: Excel + business process diagrams.
Give stars on GitHub.
Top comments (0)