I am currently working on a 2 column layout, where the right-hand column contains a scrollable list displaying a maximum of 200 items (implemented using a ul with overflow-y: scroll;
).
However, I have noticed that scrolling through the right-hand column is causing some lag, particularly on lower-end hardware.
While analyzing the Chrome timeline, I observed significant delays in the "Update Layer tree" process whenever I scrolled through the column. Is there a way to determine why this update is taking so long and which CSS properties are impacting performance the most? Clicking on it only provides information about its duration without any additional details.
The individual li elements contain CSS styles like filters, transforms, and box-shadows that seem to be affecting the scrolling performance negatively. Removing each SASS file one by one improves the performance gradually (eliminating the lag after removing all CSS), but identifying the specific problematic CSS properties through this method is challenging.
I wonder if there are any features in the Chrome timeline that could assist in addressing this issue?
Although I attempted to use the will-change
CSS property to enhance scrolling by promoting it to a separate layer for hardware acceleration, it did not yield significant improvements.
No JavaScript events are triggered during scrolling.
Maintaining fewer than 200 items in the list is not a feasible solution.
To demonstrate the issue, I have created an example with a longer list of items: https://github.com/jooj123/jank/blob/master/scroll.html
An intriguing observation is that removing the overflow-y: scroll;
property from .map-search__results in the example significantly enhances scrolling smoothness and eliminates the lag. What could be causing such a dramatic impact?
Here is the Chrome timeline data, showing prolonged "Update Layer tree" sections: https://i.sstatic.net/UYGy8.png
Solution:
Paul's recommendation regarding will-change: transform
is highly effective, especially this insight:
"Add will-change: transform;. Once added, the "repaints on scroll" rect is gone."
It is important to note that this approach may not always work depending on your codebase. Verify that the "repaints on scroll" indicator is disabled by checking the scroll performance issues. In my case, I also had to disable a -webkit-clip-path
property (present in my actual codebase, not in the provided demo) that was set in one of the child divs. See: