重绘和回流

浏览器的渲染过程

首先我们简单的介绍一下浏览器的渲染过程:

  1. 浏览器会将 html代码解析成一个 Dom 树(Dom tree),html中的每个标签(tag)都是 Dom tree中的一个节点,根节点就是document对象, Dom tree 中包含了所有的html标签 其中有 display: none 隐藏元素和js动态添加的元素等

  2. 浏览器把所有样式(主要包括css和浏览器的样式设置)解析成样式结构体,在解析的过程中会去掉浏览器不能识别的样式,比如IE会去掉-moz开头的样式.

3.dom tree和样式结构体(cssom)结合后构建呈现树(render tree ),render tree有点类似于Dom tree,但其实区别有很大,render tree能识别样式,render tree中每个node都有自己的style,而且render tree不包含隐藏的节点(比如display:none的节点,还有head节点),因为这些节点不会用于呈现,而且不会影响呈现的,所以就不会包含到 render tree中。

注意: visibility:hidden隐藏的元素还是会包含到render tree中的,因visibility:hidden 会影响布局(layout),会占有空间。

回流

原理: 当render树的一部分或者全部因为大小边距或其他原因发生页面布局的改变,需要重新绘制页面的时候叫做回流

重绘

原理:当元素一部分属性发生变化,如背景图片改变文字颜色改变等,不导致页面布局发生改变而需要重新渲染的过程叫做重绘

哪些情况下会发生重绘和回流?

1.页面初始渲染

2.改变字体,改变元素尺寸(宽、高、内外边距、边框,改变元素位置等
各种情况:
设置 style 属性的值
激活 CSS 伪类,比如 :hover
操作 class 属性
css3的某些属性(https://csstriggers.com/ 结合此链接查看哪些属性会触发重排、哪些属性会触发重绘以及哪些属性会触发合成;)

(注意:如果修改属性不影响布局则不会发生重排)
3…改变元素内容(文本或图片等或比如用户在input框中输入文字)
4.添加/删除可见DOM元素(注意:如果是删除本身就display:none的元素不会发生重排;visibility:hidden的元素显示或隐藏不影响重排)
5.fixed定位的元素,在拖动滚动条的时候会一直回流
6. 调整窗口大小(Resizing the window)

何减少回流,重绘?

1、修改html元素中对应的class名,利用class替换样式
2、csstext(利用cssText属性合并所有改变,然后一次性写入)

// 不好的写法
var left = 1;
var top = 1;
el.style.left = left + "px";
el.style.top = top + "px";

// 比较好的写法 
el.className += " className1";
// 比较好的写法 
el.style.cssText += "; left: " + left + "px; top: " + top + "px;";

3、display:none(隐藏元素,应用修改,重新显示)
先将元素隐藏,此时元素不在 render tree上,修改其样式不会发生 重绘和回流,修改完毕再将元素显示出来这样只触发两次回流和两次重绘

4、cloneNode(将原始元素拷贝到一个脱离文档的节点中,修改副本,完成后再替换回去)
将原始元素 拷贝到一个新创建的元素 此时新创建的元素还没加载到dom tree上,修改新创建的元素成我们需要展示的样式后再将原始元素用新创建的元素替换

5、document.createDocumentFragment();(使用文档片段(document fragment)在当前DOM之外构建一个子树,再插回去)就好比在html中创建一个虚拟的div然后将要加入div中的新元素创建并加入,再将这个div加载到dom tree中的某个节点下

var fragment = document.createDocumentFragment();
var list = document.getElementById("list");
for (var i = 0; i < 10; i++)
{
    var _li = document.createElement("li");
    _li.onmouseover = function ()
    {
        this.style.backgroundColor = "#22b909";
        this.style.width = "120px";
        this.style.height = "50px";
    }
    _li.onmouseout = function ()
    {
        this.style.backgroundColor = "";
        this.style.width = "100px";
        this.style.height = "40px";
    }
    fragment.appendChild(_li);
}
list.appendChild(fragment);

6、使用trsansform
CSS的最终表现分为以下四步:Recalculate Style(重新计算样式) -> Layout(重新布局) -> Paint Setup and Paint -> Composite Layers
按照中文的意思大致是 查找并计算样式 -> 排布 -> 绘制 -> 组合层。
由于transform是位于Composite Layers层,而width、left、margin等则是位于Layout层,在Layout层发生的改变必定导致Paint Setup and Paint -> Composite Layers,
所以相对而言使用transform实现的动画效果肯定比使用改变位置(margin-left等)这些更加流畅。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值