@Sakura-W
2019-01-25T08:08:00.000000Z
字数 1920
阅读 1002
前端性能
页面不仅要快速加载,而且要顺畅地运行;滚动应与手指的滑动一样快,并且动画和交互应如丝绸般顺滑。
60fps 与设备刷新率
目前大多数设备的屏幕刷新率为 60 次/秒。
像素管道
1. 对于动画效果的实现,避免使用 setTimeout 或 setInterval,请使用 requestAnimationFrame。
2. 将长时间运行的 JavaScript 工作从主线程移到 Web Worker。
3. 使用微任务来执行对多个帧的 DOM 更改。
如果必须在主线程上执行大型任务,可以将大型任务分割为微任务,每个微任务所占时间不超过几毫秒。
用于计算某元素计算样式的时间中大约有 50% 用来匹配选择器,而另一半时间用于从匹配的规则中构建 RenderStyle(计算样式的表示)。
1. 降低选择器的复杂性,使用以类为中心的方法,如BEM
// 渲染性能比较好的方式
.final-box-title {
/* styles */
}
// 渲染性能比较差的方式
.box:nth-last-child(-n+1) .title p {
/* styles */
}
*
2. 减少要计算样式的元素数量
在现代浏览器中,这往往不再是个问题,因为浏览器并不一定需要检查一项更改可能影响的所有元素。
但较早的浏览器不一定针对此类任务进行了优化,应当尽可能减少声明为无效的元素的数量。
布局是浏览器计算各元素几何信息的过程,包括元素的大小和在页面中的位置。
布局的开销:
1)需要布局的元素数量
2)布局的复杂性
1. 尽可能避免布局操作
几何属性(高度、宽度、位置等)的更改都会引发布局计算,而布局几乎总是作用到整个文档,所以会耗费大量的性能。
2. 使用 flexbox 而不是较早的布局模型
flexbox 布局性能更好!
3. 避免强制同步布局
box.classList.add('super-big');
// Gets the height of the box in pixels
// and logs it out.
console.log(box.offsetHeight);
由于需要获取盒子的高度,则浏览器会强制重新渲染盒子,因为新增了super-big
类。
4. 避免布局抖动
function resizeAllParagraphsToMatchBlockWidth() {
// Puts the browser into a read-write-read-write cycle.
for (var i = 0; i < paragraphs.length; i++) {
paragraphs[i].style.width = box.offsetWidth + 'px';
}
}
绘制是填充像素的过程,像素最终合成到用户的屏幕上。
绘制通常是像素管道中开销最大的部分;应尽可能避免绘制。
1. 将元素提升为合成层
.moving-element {
will-change: transform; translate3D(120, 0, 0)
}
// 不支持 will-change 的浏览器
.moving-element {
transform: translateZ(0);
}
提升为合成层的元素,transform 和 opacity 的改变不会引发绘制,只会引发合成。
但也要注意不要创建太多层,因为每层都需要内存和管理开销。
2. 减少绘制的区域
减少绘制区域往往是编排您的动画和变换,使其不过多重叠,或设法避免对页面的某些部分设置动画。
3. 降低绘制的复杂性
在谈到绘制时,一些绘制比其他绘制的开销更大。
合成是将页面的已绘制部分放在一起以在屏幕上显示的过程。
影响页面的性能因素:
1)需要管理的合成器层数量
2)动画属性
1. 坚持使用 transform 和 opacity 属性更改来实现动画
使用 transform 和 opacity 时要注意的是,这些属性所在的元素应处于其自身的合成器层(will-change 提升)。
2. 管理层并避免层数激增
如无必要,请勿提升元素
1. 输入处理程序防抖