user888734
user888734

Reputation: 3897

Can I do anything about "repaints on scroll" warning in Chrome for "overflow:scroll" div

In Chrome DevTools, under Rendering, there's an option to "Show potential scroll bottlenecks".

When I enabled this, some div elements I have on the screen with overflow:scroll show a flag at the top saying "repaints on scroll."

I can't find a lot of documentation on this feature, and I don't know whether it's something I can actually fix or improve upon, or just a statement of fact - the divs have content, and they do indeed scroll.

Upvotes: 57

Views: 18381

Answers (5)

Joseba
Joseba

Reputation: 1

I was experiencing the same "repaints on scroll" issue with an input of type text. By removing the input's "placeholder" attribute, the warning disappeared.

Upvotes: 0

ninjagecko
ninjagecko

Reputation: 91152

This amazingly took me multiple days to track down what was going on, and only because I saw the one side-comment at the end of a bug report at Chromium bugtracker Issue 514303. Here's what's going on and how to fix it:

There exists a concept called "LCD text", which I believe means subpixel antialiasing, i.e. "crisper sharper text". Unfortunately, this feature is mutually incompatible with compositor-accelerated scrolling.

LCD text is enabled by default (at least on Blink/Webkit?) on all platforms which are not high-DPI (most normal monitors; i.e. you can check console.log(devicePixelRatio)). On the other hand, LCD text is DISABLED by default on high-DPI devices (think Retina display, or most mobile devices and tablets) since you don't really need a "crisper sharper text" feature on high-DPI platforms.

Therefore the opposite is true for compositor-accelerated scrolling: it is only possible on high-DPI platform where LCD text is disabled.

However, you can force compositor-accelerated scrolling on most monitors by promoting the overflow:scroll element to its own layer, by either adding will-change:transform to that element, or any hackish equivalent which will force the overflow element to be the parent of its own layer (such as transform:translateZ(0)). (Do note that vendor prefixes are being removed.)

tl;dr: Chrome doesn't suppose both subpixel antialiasing AND gpu-assisted scrolling; pick one or the other. Subpixel antialiasing is the default pick on Chrome (except on cellphones and retina displays, because their text is so small you don't need the feature, so you won't notice this issue on those platforms). Override this by forcing the element into its own compositor Layer with will-change:transform (but note that maybe your text won't look crystal perfect).

Upvotes: 30

maheshsenni
maheshsenni

Reputation: 782

Although the accepted answer solves the problem, it is worth looking at the CSS will-change property. This is preferred over transform: translateZ(0); in recent times. Here is an that article explains the difference in detail - https://dev.opera.com/articles/css-will-change-property/

.scroll-container {
  will-change: transform;
}

Upvotes: 36

lepix
lepix

Reputation: 4990

You can apply this CSS on the div with overflow: scroll or overflow: auto that create scroll bottlenecks.

transform: translateZ(0);
-webkit-transform: translateZ(0);

That will force the browser to create a new layer to paint this element, and sometimes fix scroll bottlenecks (especially with Webkit).

Upvotes: 73

Jordan
Jordan

Reputation: 3996

Nope, you cant modify that, it is a Chrome function to allow you to know, what's painted each update in the window.

Updates can be a lot of different things (scroll, mousemove, interval, requestanimationframe,...).

But, now you know that, you can enhance your code.

If (I dont know), the browser alway re-paint a div if it is set to overflow scroll you maybe can do some JS to set to overflow hidden when out of screen...

This post talk about different Browser layout

Upvotes: -6

Related Questions