[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.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 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