前端性能优化(二)渲染优化

一.浏览器渲染流程

初次渲染—浏览器渲染流程
二次渲染主要是这五个步骤:
前端性能优化(二)渲染优化
JavaScript:指的是用js可以实现页面上的视觉变化,比如动画等;除此之外我们还可以用css做动画过渡等,这里只是统一代表,改变页面视觉变化的一系列操作

Style:浏览器对样式就行重新的计算,选择器重新的匹配,计算那些css收到了影响,新的规则是什么样的。这样每个元素是什么样子就清楚了

Layout:布局,把元素按照说的样式绘制到页面上,我们需要知道大小和位置

Paint:绘制,把元素绘制到页面上,画文字图片阴影等

Composite:复合,按照图层绘制,最后把各个图层绘制的合成在一起,类似于ps那种感觉

二.布局和绘制的优化

布局,绘制很耗资源,我们可以尽量避免这两个阶段进行优化

1.影响回流的操作

第一次叫做布局,当修改一些内容再布局,我们称为回流,其实和布局本质是一样的

①添加/删除元素
②display:none
③移动元素位置
④操作style
⑤读取offsetLeft,scrollTop,clientWidth
⑥修改浏览器大小、字体大小

2.什么是布局抖动、以及如何避免

①.什么是布局抖动:
我们举个例子
前端性能优化(二)渲染优化
在上述代码中,问题出现在for循环里,给我们宽度赋值的时候,先获取了offsetTop,我们浏览器其实是为了我们提高布局的性能,会尽力将修改布局相关的操作推迟,当我们获取布局相关属性时,浏览器就无法推迟,比如获取offsetTop,当我们要获取这个值的时候,浏览器不得不进行计算,获得offsetTop最新的结果,以至于我们在布局前强制进行了一次计算,所以我们会先去读取offsetTop,再去写width,由于for循环,我们会进行连续读写,而且每次读操作都会强制布局重新的计算,这样就会导致有连续不断的强制回流发送,连续不断的强制回流就会导致我们的布局抖动。

②如何避免呢?
(一)避免回流:
知道哪些操作会导致回流,我们尽量就不要做那些操作,比如说我们要改变某元素的位置,我们尽量不要用top left等操作,而使用transform translate做位移,不会触发回流和重绘,只会触发复合的过程

(二)把读和写分离

(三)利用插件:fastdom
fastdom
前端性能优化(二)渲染优化
从上面例子可以看出 如果不用fastdom的话,输出顺序是measure mutate measure measure 但是用了fastdom之后,就把measure(读)放在一起输出,mutate(写)放在一起输出。即把读和写分开

前端性能优化(二)渲染优化
这有个例子,能让我们更直观的感受fastdom的厉害之处

用fastdom修改上面的例子
前端性能优化(二)渲染优化
具体怎么批量处理我们不用关心,我们只需要按照逻辑书写代码即可。

3.复合线程(compositor thread)与图层(layers)

(一)什么是复合线程,与图层的关系:
复合是浏览器渲染的最后一步,但其实与绘制阶段是有密切关联的,为了提高绘制的效率,浏览器才有复合这个阶段,复合主要把页面拆解成不同的图层,当页面发生视觉变化的时候,有时候这个变化只影响某个图层的变化,而其他的图层不受影响,这样绘制效率就会变快

复合线程就是把页面分成多个图层进行绘制

如果某些元素对其他元素的影响非常的多,浏览器会将其提取成一个单独的图层。

(二)如何查看图层:
performance–Frames–Layers 查看图层,例子有两个图层
如何设置图层下面会讲
前端性能优化(二)渲染优化
(三)只进行复合而不触发回流和重绘的操作
①transform:translate(npx npx)
②transform:scale(n)
③transform:rotate(ndeg)
④opacity:0–1

三.requestanimationframe 这个API

requestAnimationFrame(callback) 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行

requestAnimationFrame(callback):优势:由系统决定回调函数的执行时机。60Hz的刷新频率,那么每次刷新的间隔中会执行一次回调函数,不会引起丢帧,不会卡顿