zoukankan      html  css  js  c++  java
  • 重排与重绘

    当DOM的变化引起了元素的几何属性发生变化,浏览器不得不重新计算元素的几何属性,并重新构建渲染树,这个过程称为重排。注意这里至少会有一次重排-初始化页面布局。

    由于节点的几何属性发生改变或者由于样式发生改变,例如改变元素背景色时,屏幕上的部分内容需要更新。这样的更新被称为重绘

    由于浏览器渲染界面是基于流式布局模型的,也就是某一个DOM节点信息更改了,就需要对DOM结构重新进行计算,重新布局界面在,再次引发重排。

    引起重排的操作有:

    (1)页面首次渲染

    (2)浏览器窗口大小发生变化(resize事件发生时)

    (3)元素尺寸(大小,外边距,边框)或位置发生改变,或使用动画

    (4)元素内容变化

    (5)元素字体大小变化

    (6)添加或删除可见的DOM元素

    (7)设置style属性

    (8)读取某些元素属性(offsetLeft/Top/Height/Width)

    重排一定会引起重绘,但是重绘不一定会引起重排。

      当DOM结构发生变化时,例如节点的增减、移动等,也会触发重排。浏览器引擎布局的过程,类似于树的先序遍历,是一个从上到下从左到右的过程。通常在这个过程中,当前元素不会再影响其前面已经遍历过的元素,所以,如果在body最前面插入一个元素,会导致整个文档的重新渲染;而在其后插入一个元素,则不会影响到前面的元素。

    如何减少重排次数?

    (1)避免设置大量的style属性,因为通过设置style属性改变节点样式的话,每一次设置都会触发一次reflow,所以最好是使用class属性

    (2)将需要多次重排的元素,position属性设置为absolute或fixed,这样元素就会脱离文档流,它的变化不会影响到其他元素。例如有动画效果的元素最好设置为绝对定位。

    (3)由于display属性为none的元素不在渲染树中,对隐藏的元素操作不会引发其他元素的重排。如果对一个元素进行复杂的操作时,可以先隐藏他,操作完成之后再显示。这样只在隐藏和显示时触发两次重排,但是这可能导致浏览器的闪烁。

             这个会在显示与隐藏节点的时候,产生两次重绘。

    function appendDataToElement(appendToElement,data){
        let li;
        for(let i=0;i<data.length;i++){
            li=document.createElement('li');
            li.textContent='text';
            appendToElement.appendChild(li);
        }
    }
    const ul=document.getElementById('list');
    ul.style.display='none';
    appendDataToElement(ul,data);
    ul.style.display='block';

    (4)不要把DOM节点的属性值放在循环里当成循环里的变量,例如改变DOM的内容,先定义一个变量,最后再添加到DOM上。

    var position=document.getElementById('position');
    var jobHTML='';
    for(var i=0;i<jobArr.length;i++){
        jobHTML+='<option value='+i+'>'+jobArr[i]+'</option>';               
    }
    position.innerHTML+=jobHTML;

    (5)使用文档片段在当前DOM之外构建一颗子树,再把它拷贝回文档

    const ul = document.getElementById('list');
    const fragment = document.createDocumentFragment();
    appendDataToElement(fragment, data);
    ul.appendChild(fragment);
  • 相关阅读:
    vscode sftp 本地目录设置问题
    Zend where or怎么传
    docker如何查看最近创建的容器
    基于apline构建php7+nginx
    修改layui tree组件支持上移下移
    mysql千万级数据表如何删除
    filezilla 链接ftp不显示本地目录 “您没有权限列出该目录内容”
    php使用socket通过tcp通信及php16进制求和校验位计算
    Session must be started before any output has been sent to the browser;问题解决
    mysql数据库中的union和union的区别(示例演示)
  • 原文地址:https://www.cnblogs.com/xiaoan0705/p/8652131.html
Copyright © 2011-2022 走看看