[HTML5] Layout Reflow & thrashing

Layout reflow

Layout reflow can be a performance bottleneck. Let's see how to identify it in the browser and what causes the reflow.

In normal process, "Style & Layout" happens after "Javascript".

Here we can consider "Javascript" part is doing "DOM Mutataion" and

"Style & Layout" is doing "DOM Measurement".

 

"Layout reflow": "Style & Layout" happens during "Javascirpt". Or we can also say "measurement happens after Mutation".

You can identitfy the "Layout reflow":

 

In this code, it looks like:

function addItem() {
  const newEl = document.createElement("div")
  // Mutate
  wrapper.appendChild(newEl)
  // Measurement
  height = wrapper.getBoundingClientRect().height
}

 

Solve layout reflow

One possible way is move "Measurement" before "Mutate":

function addItem() {
  const newEl = document.createElement("div")
  // Measurement
  height = wrapper.getBoundingClientRect().height
  // Mutate
  wrapper.appendChild(newEl)
  
}

 

Second way: if it is not possible to reverse the order of code, we can do: "setTimeout":

复制代码
function addItem() {
  const newEl = document.createElement("div");
  // Mutate
  wrapper.appendChild(newEl);
  setTimeout(() => {
    // Measurement
    height = wrapper.getBoundingClientRect().height;
  }, 0);
}
复制代码

 

Or better, using 'requestAnimationFrame'

复制代码
function addItem() {
  const newEl = document.createElement("div");
  // Mutate
  wrapper.appendChild(newEl);
  requestAnimationFrame(() => {
    // Measurement
    height = wrapper.getBoundingClientRect().height;
  });
}
复制代码

 

Solving layout thrashing by caching measured value

Layout thrashing is when we force the browser to measure the DOM multiple times during a synchronous process. This can have major performance consequences. In this lesson we will see the case in which measuring a static value from the DOM can cause layout thrashing - and it can be solved by caching the value.

In short, do multi layout reflow during one single process

All the red block is showing that there is a big performance issue.

 

From the code:

复制代码
    function compareWidths() {
      // repeat "measure" - "mutate" - "measure" -...
      for (let i = 0; i < wrapper.childElementCount; i++) {
        // measure
        const wrapperWidth = wrapper.offsetWidth;
        // mutate
        wrapper.children[i].style.width = wrapperWidth;
      }
    }
复制代码

 

We can solve the problem by moving following code out of for loop, because it always getting the same value

const wrapperWidth = wrapper.offsetWidth;
    function compareWidths() {
       // measure
      const wrapperWidth = wrapper.offsetWidth;
      for (let i = 0; i < wrapper.childElementCount; i++) {
        // mutate
        wrapper.children[i].style.width = wrapperWidth;
      }
    }

 

Another way to solve the problem is using decounce:

const debouncedSubmitNewHeightEvent = _.debounce(submitNewHeightEvent, 50);

So that multi calculation will group into only one calculation.

posted @   Zhentiw  阅读(332)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2019-03-04 [Transducer] Make Transducer works for Iteratable collection and Object
2019-03-04 [Algorithm -- Dynamic programming] 91. Decode Ways <How Many Ways to Decode This Message?>
2016-03-04 [CSS] CSS Transitions: Delays and Multiple Properties
2016-03-04 [ReactJS] DOM Event Listeners in a React Component
2015-03-04 [Javascript + lodash] sortBy and sortedIndex
2015-03-04 [Javascript] Webpack Loaders, Source Maps, and ES6
点击右上角即可分享
微信分享提示