zoukankan      html  css  js  c++  java
  • [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.

  • 相关阅读:
    014 停止进程
    014 创建进程的函数使用
    014 进程 获取当前目录 获取当前文件搜在目录 获取环境变量
    013 Windows进程及线程
    012 CopyFile
    011 异步I/O处理 003
    010 异步I/O处理 002
    MVVM
    ORM
    MVC
  • 原文地址:https://www.cnblogs.com/Answer1215/p/12411783.html
Copyright © 2011-2022 走看看