(三)渲染优化 (与浏览器为友,共进退)

浏览器渲染原理和关键渲染路径

浏览器是怎么把页面渲染出来的,渲染过程分很多环节,就是关键渲染路径,只有理解了渲染经历了什么步骤,才知道针对性的进行优化
网络资源被加载过来后,脚本、css都要进行解析,解析完之后浏览器要进行理解,如何把内容画到页面上,这就是渲染的过程
在这里插入图片描述
主线程有Recalculate style(计算样式)、Layout(布局)、Paint(绘制),这几个就是渲染过程中几个非常重要的阶段

浏览器的渲染流程

Javascript(触发视觉变化) 》Style(浏览器对样式重新进行计算) 》Layout(布局) 》Paint(绘制)》Composite(合成),这就是关键渲染路径,一共5步,无论是首次加载还是后面页面发生了样式上的变化,都要经历这几个步骤,最终把页面呈现给用户,理论上这5个步骤都是会被经历的,但是有些样式不会影响布局,也不会影响绘制,所以浏览器就进行了优化,如果是这样的样式,实际上可以不经历布局和绘制的过程,这样渲染就可以大大的被加速
Javascript,是可以通过Javascript实现一些页面视觉上的变化,例如添加dom元素,实现动画,还可以用css做动画,web animation api实现动画,这些都会触发视觉上变化
Style,浏览器对样式重新进行计算,这个过程会根据选择器进行重新匹配,计算哪些元素css受到影响,新的规则是什么样的,应该绘制成什么样子,每个元素绘制成什么样我们就清楚了
Layout,布局把你的元素按照你说的样式绘制到页面上,要把它绘制到页面上,这实际上是几何问题,需要知道元素的大小、位置
Paint,绘制,真正把内容画到页面上,画文字、图片、颜色、阴影等
Composite,合成,绘制会和这个合成联系在一起,浏览器为了提高效率,并不是把所有的东西都花在同一个层里,类似ps里,会建多个图层,最后再把它们组合起来,形成我们最后的一张图,浏览器为了提高效率也会把不同的东西画在不同的层上,最终再把它们合成在一起显示出来
当用户在地址栏输入一个地址,然后回车后,到页面显示出来之前,都经历了哪些过程
当浏览器拿到服务端返回的资源后,做了什么事?
无论js、css、html,都是代码,是文本,计算机理解不了文本,所以第一步它要通过一些解释器,把这些文本翻译成它能理解的数据结构
html是如何被转换的?
首先浏览器下载完html文档,就要把代码读进去,读进去的是文本,它先把这些文本转换成单个的字符;第二步,html里面有很多标签,标签是通过一对箭括号标记出来的,这个箭括号就可以用作识别,就可以把一些字符串理解成有含义的标记,这些标记最终被换成节点对象,放在链形数据结构里,链形数据结构就类似下图中的树,这就可以把html描述的嵌套关系很好的表达出来,通过这样一棵树,就可以把html的内容、属性、节点之间所有的关系都给表达清楚,这就叫DOM(文档对象模型),描述了html的结构
在这里插入图片描述
css部分如何被转换?
一样的道理,当解释器遇到你可能引用了web的css样式表,先把资源下载过来,下载完成后对这个资源进行文本处理,把里面的标记全部识别出来,看样式描述的是哪个节点的样式,然后也用树形结构把这个关系存储起来,如下图:除了描述节点之间的联系之外,还把每个节点所关联的样式给挂载起来
在这里插入图片描述

1.浏览器构建对象模型(两棵树)

构建DOM对象:HTML>DOM
构建CSSOM对象:CSS>CSSOM

2.浏览器构建渲染树

DOM(描述的是内容)和CSSOM(描述的是样式)合并成Render Tree,把内容和样式合在一起,让浏览器理解最终我们要把什么画在页面上,合并的结果如下图,把真正需要显示的东西留下,不需要显示的东西去掉,比如span节点的样式是diaplay:none,不需要显示在页面上,构造成渲染树后,span节点就会被去掉,最终只会留下需要显示到页面上的,有了这颗渲染树后,浏览器利用这棵树,知道每个节点什么尺寸,画在什么位置,
在这里插入图片描述

回流与重绘, 如何避免布局抖动

Layout(布局)与Paint(绘制)

是关键渲染路径中最重要的两个步骤,也是开销最高的两个步骤,如何减少或避免布局和绘制的发生?

  • 渲染树只包含网页需要的节点
  • 布局根据渲染树布局,计算每个节点精准的位置和大小-“盒模型”,关心位置和大小
  • 绘制是像素化每个节点的过程,把节点画在屏幕上
    在我们页面中,这个关键路径至少会被走完一次,也就是最开始整个页面的加载
    布局关心的是位置和大小,元素的几何信息,所以你的样式例如修改背景颜色不会修改位置和大小,是不会触发布局,关键渲染路径中Layout就可以跳过,直接到重绘
    有没有即不会发生布局也不会发生重绘,是有的,有些动画是可以利用gpu加速,这种动画可以直接走复合的过程,不需要进行布局和重绘

影响回流的操作

布局也叫做回流,通常页面第一次加载完之后,把东西放在页面上我们叫做布局,如果是由于你之后页面上发生了视觉上的变化又导致再次布局,通常叫做回流

  • 添加/删除元素
  • display:none
  • 移动元素的位置
  • 操作styles
  • offsetLeft,scrollTop,clientWidth
  • 修改浏览器大小,字体大小

写个load事件,更改卡片的宽度,然后在performance里Timings那一栏load事件之后主线程有发生layout
在这里插入图片描述
如果一个回流操作不只影响本身,还会导致其他元素,甚至整个页面所有元素的位置都发生变化,这个消耗是非常高的,甚至页面会出现卡顿的状况

避免布局抖动(layout thrashing)

  • 避免回流
    比如想改变元素位置,千万不要修改top、left这样的值,可以使用transform或者translate,通过translate做位移,这个3d动画既不会发生回流也不会发生重绘,只会触发复合的过程;
    减少回流:react的v-dom减少回流,把一些你要会导致回流发生的操作,进行批量处理,积攒一些之后进行统一的计算,最后应用我们真正的dom上
  • 读写分离
    批量的读操作完再进行批量写的操作
    在这里插入图片描述

页面上所有的图片都开始进行动画的变化,发现动画并不流畅
在这里插入图片描述
性能分析里右上角红色三角形是表示发生了长任务
提示了强制回流,我们应该引起重视,这种是一个问题,问题出现在for循环里,给我们width进行赋值时,先取了offsetTop,浏览器为了提高布局的性能,会尽量把修改布局相关属性的操作推迟,但是什么情况是无法推迟呢?当你获得布局相关属性比如offsetTop时是无法推迟,不得不立即进行最新的计算,以保证你能取得最新的结果,所以在布局前它就被强制进行了一次计算,所以会先读这个值再对width写的操作,这是个循环,有连续的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值