CSS 绘制时间和页面渲染权重
如果您是那种关注 浏览器工作 方式的人,那么您已经知道最近有一些精彩的文章详细介绍了 Chrome 的 GPU 加速渲染器/复合操作。 首先是 Accelerated Rendering in Chrome: The Layer Model 很好地介绍了 Chrome 如何使用图层的概念来绘制页面; 为了更深入地了解, Chrome 中的 GPU 加速合成 讨论了 Chrome 如何使用这些层以及 GPU 来呈现您的页面。
这些文章的快速版本是 Chrome 中的硬件加速路径将 绘制 通过将页面视觉效果栅格化为图块来 您的页面。 然后将这些图块传递给 GPU,硬件将在 GPU 中将图块最终绘制到屏幕上,这一过程称为 合成 。 Chrome 将根据平台之间可能发生变化的需求和性能启发式将磁贴移入和移出内存。
哲学问题
在花费大量时间编写 用于 3D 目的的软件光栅器 后,我逐渐意识到, 某些CSS 属性 在绘制页面时, 应该具有不同的性能。 例如,将小图像光栅化到屏幕是一种完全不同的算法操作,它与在任意形状上绘制阴影完全不同。 所以问题变成了: 不同的 CSS 属性如何影响页面的渲染权重?
我的目标是根据绘制时间对大量 CSS 属性/值进行分类,这样我们就可以了解哪些类型的 CSS 属性比其他类型的属性性能更高。 为此,我使用胶带和泡泡糖编写了一些自动化程序,以尝试为 CSS 绘制时间添加数字可见性,其工作方式如下:
- 生成一套独立的 HTML 页面; 每一个都有一个 DOM 元素和附加到它的 CSS 属性的一些排列。
- 运行一些自动化脚本,对于每个页面,该脚本将:
- 启动 Chrome
- 加载页面
- 制作 Skia 图片 为页面
- 运行通过 Skia Benchmark 拍摄的每张 Skia 图片以获得计时
- 抛开所有的时间安排,惊叹于这些数字。 (这部分很重要..)
Chrome 的软件光栅化程序包称为 SKIA ,它不仅可以处理网页的光栅化,还可以处理所有 HTML5 Canvas API 所需的(方框、线条、位图填充、阴影、模糊,Chrome 需要将 DOM 转换为像素)。 为了帮助调试页面的呈现,SKIA 允许您保存 Skia Picture (*.SKP) 文件,其中记录了用于绘制页面的所有命令。
通过这种设置,我们生成了一套 HTML 页面,其中每个页面都包含 CSS 属性和值的唯一排列; 例如,这里有两个 html 文件:
<style> #example1 { background: url(foo.png) top left / 50% 60%; padding: 20px; margin-top: 10px; margin-right: 20px; text-align: center; } </style> <div>WOAH</div>
还有一个更复杂
<style> #example1 { background-color:#eee; box-shadow: 1px 2px 3px 4px black; border-radius: 50%; background: radial-gradient(circle closest-corner, white, black); padding: 20px; margin-top: 10px; margin-right: 20px; text-align: center; } </style> <div>WOAH</div>
下面,作为上一个示例的变体,我们只更改径向渐变值:
<style> #example1 { background-color:#eee; box-shadow: 1px 2px 3px 4px black; border-radius: 50%; background: radial-gradient(farthest-side, white, black); padding: 20px; margin-top: 10px; margin-right: 20px; text-align: center; } </style> <div>WOAH</div>
然后将每个页面加载到一个 新的 Chrome 实例中(以确保计时不会因页面重新加载中的任何陈旧状态而产生偏差),并 使用Skia 图片 (*.SKP) 来评估用于绘制的 Skia 命令这一页。 构建)推送 *.SKP 文件,该应用程序会转储呈现 一旦为每个 HTML 文件生成了 SKP 文件,我们将运行另一批次以通过 Skia Benchmark 应用程序(从Skia 源代码 该页面所花费的平均时间。
评估数据
由此,我们现在有一些粗略的能力来绘制一组 CSS 属性需要多少。 或者更确切地说,我们可以通过绘制性能对 CSS 属性进行堆栈排名。 这是一张用 Chrome 27 beta 拍摄的大图,展示了该过程的所有完整计时数据集。 请注意,随着 Chrome 随着时间的推移变得越来越快,所有数据都可能发生变化。
每个垂直条表示具有单个 CSS 属性组合的页面的绘制时间(放大 100 倍;此图的真实比例值为 [0,1.56ms])。 很多漂亮的线条,但在这种形式下它有点没用; 我们需要进行一些数据挖掘以找到有用的趋势。
首先,我们发现 一些 CSS 属性的渲染成本明显高于其他属性 。 例如,在 DOM 元素上绘制阴影涉及使用样条曲线和其他类型的多通道操作,而不是应该更容易呈现的不透明度。
其次,更有趣的是, CSS 属性的组合比它们各部分的总和有更长的绘制时间 。 从观察者的角度来看,这有点奇怪,我们期望 A+B = C,而不是 2.2C。 例如添加 box-shadow
和 border-radius-stroke
:
真正有趣的是,这不仅仅是 box-shadow
属性本身,而是 特定的值排列 。 例如,下面显示了一组 box-shadow : 50%
和 border-radius
随着价值的变化。
查看数据,这会持续一段时间。 有很多奇怪的组合,我的测试套件几乎没有接触到所有的组合; 仍然有大量的测试和组合可以产生有趣的结果
查找页面渲染权重
有了跟踪页面上每个元素的渲染时间的能力,开发人员就可以开始评估他们的页面渲染权重,以及它如何影响您网站的响应能力; 这里有一些入门技巧
- 在 Chrome 开发者工具中使用 Chrome 的 连续绘制模式,了解哪些 CSS 属性正在消耗您的资源。
- 将 CSS 审查合并到您现有的代码审查过程中以发现性能问题在您的 CSS 中寻找您使用已知更昂贵的东西的地方,例如渐变和阴影。 问问自己,我真的需要这些吗?
- 当有疑问时,总是宁愿选择更好的性能。 您的用户可能不记得您的列的填充宽度是多少,但他们会记得访问您的网站的感觉。
不幸的是,如果没有像构建的那样的自定义计时设置,目前很难自动化查找页面渲染权重的过程,这使得跨平台页面构建的持续集成变得困难。
最后的想法
不断变化 这个实验最有趣的事情之一是时间将随着每个版本的 Chrome (希望变得更快)浏览器软件是一个不断变化的表面区域。 今天慢的东西,明天可能会很快。 你可以从这篇文章中拿走以避免把 box-shadow: 1px 2px 3px 4px
一个已经有的元素 border-radius:5
. 然而,更有价值的收获应该是 CSS 属性直接影响您的页面绘制时间。
与任何软件一样,在做出设计决策之前,请务必针对您的性能目标和平台测试所有设计选择,以确定您自己的应用程序的有效性。
参考链接
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 避免 Web 中不必要的渲染
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论