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.

  • 相关阅读:
    jsonp跨域请求
    jQuery之异步Ajax请求使用
    table表格cellspacing与cellpadding属性
    常用正则匹配
    插入数据显示 Duplicate entry '4913' for key 'user_id'
    事件驱动模型 IO多路复用 阻塞IO与非阻塞IO select epool
    python 协程
    python 进程 线程
    python 并发socketserver模块
    python 网络 socket
  • 原文地址:https://www.cnblogs.com/Answer1215/p/12411783.html
Copyright © 2011-2022 走看看