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

  • 相关阅读:
    “无法更新EntitySet“*****”,因为它有一个DefiningQuery,而元素中没有支持当前操作的元素”问题的解决方法
    Web.Config全攻略
    C#常用的正则
    Asp.Net MVC2 Json
    webservice+Jquery返回Json格式【原创】
    JAVA线程池介绍以及简单实例
    从程序员到项目经理(17):你不是一个人在战斗思维一换天地宽
    SELECT INTO 和 INSERT INTO SELECT 两种表复制语句
    多表对应更新(跨服务器).sql
    sql导出excel.sql
  • 原文地址:https://www.cnblogs.com/Answer1215/p/12411783.html
Copyright © 2020-2023  润新知