• [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.

  • 相关阅读:
    htmlunit 基础01
    @Transactional 事务失效问题
    SQL优化总结
    单点登录实现过程
    常见的mybatis对应关系
    命名规范(Oracle数据库)
    12-5 作为可叠加修改的特质
    12-4 Ordered特质
    10 绘制螺旋示例
    10-6 参数化字段
  • 原文地址:https://www.cnblogs.com/Answer1215/p/12411783.html
Copyright © 2020-2023  润新知