解剖课-回流与重绘篇

浏览器的渲染过程

 

一. 首先我们要知道什么是HTML?

HTML:是文本也是一个字符串,它很多的根标签比如:html,head,body,都是手写的字符串些字符串最后都会转换为DOM树

 二.DOM树如何形成?

1:首先我们拿HTML会交给Parser解析器,解析完成就是DOM树,也就是说字符串转换为对象,

在这个过程中将HTMl标签转换为对象,但HTML过于生硬,需要解析CSS

const htmlObj = { label:'html',vhildren:[ {label:'head'},{label:'body'} ],

2拿到CSS样式,交给Parser(帕瑟)解析器,解析成一个个的规则对象,如:

.box { 
    color : white
 } 

三.DOM内部怎么转换的?

1.被解析好的 DOM树和CSS的规则对象,通过:Attachment, DOM树和CSS规则合体,合成了RenderTree渲染树,

2浏览器拿到RenderTree渲染树,调出渲染引擎,渲染整个网页,在这个之前是没有办法对网页进行渲染的,浏览器刚开始拿到的就是一对字符串和css

3 渲染引擎会做两件事

3.1布局layout,  会根据字符节点一层一层渲染到网业中但是没有任何额颜色信息,只有位置信息,如div元素的位置,把所有的结构节点全部绘制之后才去绘制着色

3.2 绘制/着色Painting, 把拼好的结构和网页上色,最后在显示Display

假设

如果我们让JS改变标题颜色,这时候重绘就会被触发,结构没有发生变化,回流就不会触发,会在执行一遍,会先改样式规则StyleRules更新了会后DOM树重新合体做一个新的RenderTree渲染树出来,这时候浏览器会看改动的信息是几何属性,还是颜色属性的信息

几何属性:宽高,位置,大小, 改变这些会影响页面布局,就必须要回流

颜色属性: 颜色信息,改动一点颜色信息只会触发重绘

比如:现在要改动logo的标题的大小,那么我们会先经过回流改变logo的位置大小,然后重绘会修改变动地区的颜色

-----------------------------------------------------------------------------------------------------------------------------

何时发生回流重绘

我们前面知道了,回流这一阶段主要是计算节点的位置和几何信息,那么当页面布局和几何信息发生变化的时候,就需要回流。比如以下情况:

  • 添加或删除可见的DOM元素
  • 元素的位置发生变化
  • 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
  • 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。
  • 页面一开始渲染的时候(这肯定避免不了)
  • 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)


作者:腾讯IVWEB团队
链接:https://juejin.cn/post/6844903779700047885
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

---------------------------------------------------------------------------------------此处引用掘金:腾讯IVWEB团队

核心

重绘:(绘制/着色Painting), 重绘不一定会触发回流,

回流:(布局layout),  但回流一定会触发重绘, 回流会更消耗性能

平时开发时尽量减小DOM操作,就可以减少回流和重绘的触发的次数

写动画一定多用css3,c3动画性能比js高很多

优化方案

1. DocumentFragment - 文档片段

它时一个没有父对象的最小文档对象。它被作为一个轻量版的 Document 使用,就像标准的document一样,存储由节点(nodes)组成的文档结构。与document相比,最大的区别是DocumentFragment 不是真实 DOM 树的一部分,它的变化不会触发 DOM 树的重新渲染

HTML
<ul id="list"></ul>


JavaScript
const list = document.querySelector('#list');
const fruits = ['Apple', 'Orange', 'Banana', 'Melon'];

const fragment = document.createDocumentFragment();

fruits.forEach(fruit => {
  const li = document.createElement('li');
  li.innerHTML = fruit;
  fragment.appendChild(li);
});

list.appendChild(fragment);

优点: DocumentFragment文档片段:创建一段html出来,一次性添加到整个网页中,只触发一次回流和重绘,  这个方案一般的框架都会自带的,

缺点:ie9 一下的版本都不支持

2. 减少回流和重绘的次数

可以合并多次的DOM和样式的修改以及操作,然后在最后一次处理掉

const biu = document.getElementById('test');

biu .style.padding = '15px';

biu .style.borderLeft = '10px';

biu .style.borderRight = '20px';

,有三个样式属性被修改了,每一个都会影响元素的几何结构,引起回流 ,因此,我们可以合并所有的改变然后依次处理,比如我们可以采取以下的方式:

使用cssText

const biu = document.getElementById('test');
biu .style.cssText += 'border-left: 1px; border-right: 2px; padding: 5px;';



修改CSS的class
const biu = document.getElementById('test');
biu.className += ' active';

批量修改DOM

当我们需要对DOM对一系列修改的时候,可以通过以下步骤减少回流重绘次数:

  1. 使元素脱离文档流
  2. 对其进行多次修改
  3. 将元素带回到文档中。

该过程的第一步和第三步可能会引起回流,但是经过第一步之后,对DOM的所有修改都不会引起回流重绘,因为它已经不在渲染树了。

有三种方式可以让DOM脱离文档流:

  • 隐藏元素,应用修改,重新显示
  • 使用文档片段(document fragment)在当前DOM之外构建一个子树,再把它拷贝回文档。
  • 将原始元素拷贝到一个脱离文档的节点中,修改节点后,再替换原始的元素。

因为也是今天才学习了一下,看了一部分视频以及文章自我总结了一下,希望对大家有用

以上方法有部分借鉴引用掘金:腾讯IVWEB团队的文章,有想更加深入的了解可以进去链接查看你真的了解回流和重绘吗 - 掘金本文先从浏览器的渲染过程来从头到尾的讲解一下回流重绘,如果大家想直接看如何减少回流和重绘,优化性能,可以跳到后面。(这个渲染过程来自MDN) Display:将像素发送给GPU,展示在页面上。(这一步其实还有很多内容,比如会在GPU将多个合成层合并为同一个层,并展示在页面中。而…https://juejin.cn/post/6844903779700047885

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值