Layout Reflow

Estimated Reading Time: 4 minutes

The browser is a wondrous thing. We give it JS, HTML and CSS – and they are translated into visual wonders. It does it by running the same rendering cycle again and again. Sometimes, something in the cycle can go wrong. Layout reflow is one of those things.

I wrote about the Critical Rendering Path (CRP) in a former article. Here’s an egghead video that shows it in the browser. In a nutshell, the regular flow of the code in the browser is this:

Figure 1: The healthy CRP diagram

Reflow is a disturbance in the force… sorry… in the flow. That means that we force a later stage (layout) into our javascript.

A reflow looks more like this:

Figure 2: The CRP diagram for a reflow

Figure 2 illustrates a reflow. The Javascript code caused the browser to initiate style and layout calculations during its run.

The calculations were done, and the Javascript continued until it finished. The rest of the flow runs then.

Besides the fact we might run costly style and layout calculations twice – our javascript now takes much longer to run.

How does it happen and how can you avoid it?

When you query the DOM for size or position, the result is usually taken from former calculations.  The browser knows how the DOM looks like, and if it knows it didn’t change, it just gets the correct value from the layout cache (created in the former calculation).

Querying the DOM is called: Measure.

Now, let’s assume you are changing the DOM. Appending elements, changing height/width or position of elements etc.

Changing the DOM is called: Mutate.

After you are changing the DOM, the browser flags its layout cache as invalid and schedules a recalculation.  If you measure the size or position of an element at this stage, the browser needs to recalculate the whole DOM in order to give you the real answer.

The reflow happens when during Javascript we mutate the DOM then measure it.

element.style('height', 500);
console.log(element.style('height'));

For instance, in the code above, we change the height of an element and then query its height.

Understanding by Touching

In this exercise you will see an example for reflow and how it looks in the DOM.

  1. Clone the following repository: https://github.com/YonatanKra/performanceWorkshop
    git clone https://github.com/YonatanKra/performanceWorkshop
  2. Type: checkout layout-reflow-1
  3. Run yarn or npm i
  4. Run yarn demo or npm run demo
  5. Open the app in the browser: http://localhost:3000
  6. Query the server (just use the input field at the top)
  7. Start monitoring
  8. Click the sorting buttons
  9. Stop the recording

A short TL;DC (too long, didn’t clone) – the app queries a list of users from a server. It then allows you to sort the users by their ID or name.

Here’s the result of the sorting scenario described above:

Figure 3: Layout reflow monitoring result. Purple part under the yellow javascript part is the reflow.

You can see that the style and layout parts (the purple part) are now inside the javascript part – causing it to run longer. That’s the reflow!

Let’s compare it to the CRP recording of a reflow-free code:

Figure 4: A “healthy” CRP recording as shown in a former article

You can see that the style and layout parts start after the javascript finished running.

The reflow in Figure 3 happens because a simple line that was added to the code. In the data-table.component.js file:

Code snippet 1: The method refreshData measures the DOM in line 41 (scrollHeight) which initiates layout calculation (reflow).

Line 40 in the code snippet #1 emits an event when we finish loading the data. Inside, it measures the DOM and sends the updated scrollHeight (line 41). Innocent product demand, right?

The problem arises from the fact that line 31 starts the process of adding elements to the DOM (mutating the DOM) and hence requires the recalculations during javascript run in the measurement of the DOM in line 41.

Summary

Layout reflow happens when we measure the DOM after we mutate it. It has severe performance implications and should be avoided as much as possible.

If watching short videos fits you, I’ve created several Egghead videos about the subject including solutions for layout reflow usecases. Each video is around 1-2 minutes, so you can definitely just check 🙂

Thanks a lot for Hod Bauer for his thorough review of this article!

Leave a Reply

Your email address will not be published. Required fields are marked *