Troubleshooting common performance issues

Users expect interactive and smooth pages. Each stage in the pixel pipeline represents an opportunity to introduce jank (interruptions of rendering). Learn about tools and strategies to identify and fix common problems that slow down runtime performance.

Summary

  • Don't write JavaScript that forces the browser to recalculate layout. Separate read and write functions, and perform reads first.

  • Don't over-complicate your CSS. Use less CSS and keep your CSS selectors simple.

  • Avoid layout as much as possible. Choose CSS that doesn't trigger layout at all.

  • Painting may take up more time than any other rendering activity. Watch out for paint bottlenecks.

JavaScript

JavaScript calculations, especially ones that trigger extensive visual changes, may stall application performance. Don't let badly timed or long-running JavaScript interfere with user interactions.

JavaScript: Tools

Take a recording in the Performance tool and look for suspiciously long Evaluate Script events.

If you notice quite a bit of jank (interruptions of rendering) in your JavaScript, you may need to take your analysis to the next level and collect a JavaScript CPU profile. CPU profiles show where runtime is spent within the functions of your page. Learn how to create CPU profiles in Speed up JavaScript runtime.

JavaScript: Problems

The following table describes some common JavaScript problems and potential solutions.

Problem Example Solution
Expensive input handlers affecting response or animation. Touch, parallax scrolling. Let the browser handle touch and scrolls, or bind the listener as late as possible. See Expensive Input Handlers in Paul Lewis' runtime performance checklist.
Badly timed JavaScript affecting response, animation, load. User scrolls right after page load, setTimeout / setInterval. Optimize JavaScript runtime: use requestAnimationFrame, spread DOM manipulation over frames, use Web Workers.
Long-running JavaScript affecting response. The DOMContentLoaded event stalls as it is swamped with JS work. Move pure computational work to Web Workers. If you need DOM access, use requestAnimationFrame.
Garbage-y scripts affecting response or animation. Garbage collection may happen anywhere. Write less garbage-y scripts. See Garbage Collection in Animation in Paul Lewis' runtime performance checklist.

Style

Style changes are costly, especially if those changes affect more than one element in the DOM. Any time you apply styles to an element, the browser figures out the impact on all related elements, recalculates the layout, and repaints.

Style: Tools

Take a recording in the Performance tool. Check the recording for large Recalculate Style events (displayed in purple).

Select a Recalculate Style event to view more information about it in the Details pane. If the style changes are taking a long time, that is a performance hit. If the style calculations are affecting a large number of elements, that is another area with room for improvement.

Long recalculate style

To reduce the impact of Recalculate Style events, minimize use of CSS properties that trigger layout, paint, and composite. These properties have the greatest impact on rendering performance. For more information, see Stick to Compositor-Only Properties and Manage Layer Count

Style: Problems

The following table describes some common style problems and potential solutions.

Problem Example Solution
Expensive style calculations affecting response or animation. Any CSS property that changes the geometry of an element, like the width, height, or position; the browser checks all other elements and recalculates the layout. Avoid CSS that triggers layouts
Complex selectors affecting response or animation. Nested selectors force the browser to know everything about all the other elements, including parents and children. Reference an element in your CSS with just a class.

Layout

Layout (or reflow in Firefox) is the process by which the browser calculates the positions and sizes of all the elements on a page. The layout model of the web means that one element may affect others; for example, the width of the <body> element typically affects the widths of any child elements, and so on, all the way up and down the tree. The process may be quite involved for the browser.

As a general rule of thumb, if you ask for a geometric value back from the DOM before a frame is complete, you are going to find yourself with "forced synchronous layouts", which may be a big performance bottleneck if repeated frequently or performed for a large DOM tree.

Layout: Tools

The Performance pane identifies when a page causes forced synchronous layouts. These Layout events are marked with red bars.

Forced synchronous layout

"Layout thrashing" is a repetition of forced synchronous layout conditions. This occurs when JavaScript writes and reads from the DOM repeatedly, which forces the browser to recalculate the layout over and over. To identify layout thrashing, look for a pattern of multiple forced synchronous layout warnings. See the previous figure.

Layout: Problems

The following table describes some common layout problems and potential solutions.

Problem Example Solution
Forced synchronous layout affecting response or animation. Forcing the browser to perform layout earlier in the pixel pipeline, resulting in repeating steps in the rendering process. Batch your style reads first, then do any writes.
Layout thrashing affecting response or animation. A loop that puts the browser into a read-write-read-write cycle, forcing the browser to recalculate layout over and over again. Automatically batch read-write operations using FastDom library.

Paint and composite

Paint is the process of filling in pixels. It is often the most costly part of the rendering process. If you noticed that your page isn't working as designed in any way, it is likely that you have paint problems.

Compositing is where the painted parts of the page are put together for displaying on screen. For the most part, if you stick to compositor-only properties and avoid paint altogether, you should notice a major improvement in performance, but you need to watch out for excessive layer counts.

Paint and composite: Tools

To find out how long painting takes, or how often painting occurs:

  1. In DevTools, in the Performance tool, click the Capture settings (The 'Capture settings' icon) button, and then select the Enable advanced rendering instrumentation checkbox.

  2. Take a recording.

If most of your rendering time is spent painting, you have paint problems. For more information, see Turn on advanced rendering instrumentation in Performance features reference.

Paint and composite: Problems

The following table describes some common paint and composite problems and potential solutions.

Problem Example Solution
Paint storms affecting response or animation. Big paint areas or expensive paints affecting response or animation. Avoid paint, promote elements that are moving to their own layer, use transforms and opacity.
Layer explosions affecting animations. Overpromotion of too many elements with translateZ(0) greatly affects animation performance. Promote to layers sparingly, and only when you know it offers tangible improvements.

Note

Portions of this page are modifications based on work created and shared by Google and used according to terms described in the Creative Commons Attribution 4.0 International License. The original page is found here and is authored by Kayce Basques (Technical Writer, Chrome DevTools & Lighthouse) and Meggin Kearney (Technical Writer).

Creative Commons License This work is licensed under a Creative Commons Attribution 4.0 International License.