绘制是填充像素的过程,像素最终合成到用户的屏幕上。它通常是流水线中运行时间最长的任务,应尽可能避免此任务。
绘制是填充像素的过程,像素最终合成到用户的屏幕上。它通常是流水线中运行时间最长的任务,应尽可能避免此任务。
摘要
- 更改除 transform 或 opacity 属性之外的任何属性始终都会触发绘制。
- 绘制通常是像素管道中开销最大的部分;应尽可能避免绘制。
- 通过层的提升和动画的编排来减少绘制区域。
- 使用 Chrome DevTools 绘制分析器来评估绘制的复杂性和开销;应尽可能降低复杂性并减少开销。
触发布局和绘制
如果您触发布局,就会始终触发绘制,因为更改任何元素的几何图形意味着其像素需要修正!
![完整的像素管道。](https://web.developers.google.cn/static/articles/simplify-paint-complexity-and-reduce-paint-areas/image/the-full-pixel-pipeline-2db0601111cfe.jpg?authuser=5&hl=ro)
如果更改非几何属性(例如背景、文本颜色或阴影),您也可以触发绘制。在此类情况下,不需要布局,且流水线将如下所示:
![无布局的像素管道。](https://web.developers.google.cn/static/articles/simplify-paint-complexity-and-reduce-paint-areas/image/the-pixel-pipeline-withou-b4844130ec9db.jpg?authuser=5&hl=ro)
使用 Chrome 开发者工具快速识别绘制瓶颈
您可以使用 Chrome 开发者工具快速识别正在绘制的区域。打开“渲染”标签页,然后启用 Paint Flashing。
打开此选项后,每次发生绘制时,Chrome 都会让屏幕闪烁绿色。如果您看到整个屏幕闪烁绿色,或者看到您认为不应绘制的屏幕区域,那么应该再深入一点。
![每当进行绘制时,网页都会闪烁绿色。](https://web.developers.google.cn/static/articles/simplify-paint-complexity-and-reduce-paint-areas/image/the-page-flashing-green-w-f830587a03866.png?authuser=5&hl=ro)
提升移动或淡出的元素
绘制并非总是绘制到内存中的单个图像。事实上,如有必要,浏览器可以绘制到多个图像或合成层。
![合成器层的表示。](https://web.developers.google.cn/static/articles/simplify-paint-complexity-and-reduce-paint-areas/image/a-representation-composi-c93c6e6c3367e.jpg?authuser=5&hl=ro)
这种方法的优势在于,定期重绘或通过变形在屏幕上移动的元素,可以在不影响其他元素的情况下进行处理。这与 Sketch、GIMP 或 Photoshop 等艺术包一样,其中各个图层可以相互处理和合成,以创建最终图像。
创建新图层的最佳方法是使用 will-change
CSS 属性。此方法适用于 Chrome、Opera 和 Firefox,并且值为 transform
时,会创建一个新的合成器层:
.moving-element {
will-change: transform;
}
对于不支持 will-change
但受益于图层创建的浏览器(例如 Safari 和 Mobile Safari),您需要(滥用)使用 3D 转换来强制创建新图层:
.moving-element {
transform: translateZ(0);
}
但必须注意不要创建太多层,因为每层都需要内存和管理开销。如需了解详情,请参阅坚持仅使用合成器的属性和管理层数部分。
如果您已将元素提升到新层,请使用开发者工具来确认这样做是否提高了性能。请勿在不分析的情况下提升元素。
减少绘制区域
不过,有时,尽管提升元素,仍有必要进行绘制。绘制问题的一大挑战是,浏览器将两个需要绘制的区域结合在一起,这可能导致整个屏幕重绘。例如,如果您在页面顶部有一个固定的标题,而在屏幕底部绘制某些元素,那么整个屏幕最终都可能会被重新着色。
减少绘制区域通常包括:编排您的动画和转场,使之不重叠,或设法避免为页面的某些部分添加动画效果。
降低绘制的复杂性
![绘制部分屏幕所用的时间。](https://web.developers.google.cn/static/articles/simplify-paint-complexity-and-reduce-paint-areas/image/the-taken-paint-part-t-3dda443178b76.jpg?authuser=5&hl=ro)
在绘制方面,一些绘制比其他绘制的开销更大。例如,绘制任何涉及模糊处理的内容(例如阴影)所花费的时间要比绘制红色方框的时间长。然而,就 CSS 而言,这并不总是很明显:background: red;
和 box-shadow: 0, 4px, 4px, rgba(0,0,0,0.5);
看起来不一定具有截然不同的性能特征,但它们确实存在。
通过上面的绘制性能分析器,您可以确定是否需要了解其他方式来实现效果。问问自己,能否使用一组更便宜的样式或其他方式来实现最终效果。
您可以在此类情况下始终避免绘制,尤其是在动画播放期间,因为每帧的 10 毫秒通常不足以完成绘制工作,尤其是在移动设备上。