避免不必要的绘画:GIF 动画版
避免绘画对于实现丝般流畅的帧率至关重要,尤其是在移动设备上。 然而,有时,油漆会出现在最不寻常的地方。 本文探讨了为什么动画 GIF 会导致出现不必要的绘制,以及您可以应用的非常简单的修复方法。
上次我们研究了 在滚动过程中避免悬停效果 的方法。 如果您还没有看到,请立即查看!
层层可爱
您可能知道,现代浏览器可能会将 DOM 元素组绘制成单独的“图像”,称为图层。 有时整个页面只有一层,有时有数百层,或者在极少数情况下有数千层!
当 DOM 元素组合到一个图层中并且其中一个元素在视觉上发生变化时,我们最终不仅要绘制更改的元素,还要绘制 图层中与更改的元素重叠的所有其他元素 。 将一个东西画在另一个东西上面会导致被覆盖的像素永远“丢失”; 如果您想要恢复原始像素,则需要重新绘制它们。
因此,有时我们希望将一个元素与其他元素隔离开来,这样当它被绘制时,我们就不需要重新绘制其他 没有 改变的元素。 例如,当您将固定页眉与可滚动内容结合使用时,每次内容滚动时都必须重新绘制页眉,以及新出现的内容。 通过将标题放在单独的层中,浏览器可以优化滚动。 当你滚动时,浏览器可以四处移动图层——可能在 GPU 的帮助下——并避免重新绘制任何一个图层。
每个额外的层都会增加内存消耗并增加性能开销,因此目标是将页面分组为尽可能少的层,同时保持良好的性能。
如果您想更详细地了解图层的创建和使用方式,请务必查看 Tom Wiltzius 的主题介绍 。
这一切与动画 GIF 有什么关系?
好吧,让我们看看这张照片:
图 1:分解为四层的 Web 应用程序。
这是一个简单应用程序的潜在层设置。 这里有四层:其中三层(第 2 层到第 4 层)是界面元素; 底层是一个加载器,它恰好是一个动画 GIF。 在正常流程中,您会在应用程序加载时显示加载器(第 1 层),然后在一切完成后显示其他层。 但这里是关键: 您需要隐藏动画 GIF。
但为什么我需要隐藏它?!
好问题。 在理想情况下,浏览器会简单地为您检查 GIF 的可见性并避免自动绘制。 不幸的是,检查动画 GIF 在屏幕上是否被遮挡或可见通常 比简单地绘制它更 昂贵,所以它被绘制了。
在最好的情况下,GIF 在其自己的层中,浏览器只需绘制并将其上传到 GPU。 但在最坏的情况下,您的所有元素都可能被组合到一个层中,浏览器必须重新绘制 每个元素 。 而且,完成后,它仍然需要将所有内容上传到 GPU。 所有这些都是针对每个 GIF 帧发生的,尽管用户甚至看不到 GIF!
在台式机上,您可能可以摆脱这种绘画行为,因为 CPU 和 GPU 更强大,并且有足够的带宽用于在两者之间传输数据。 然而,在手机上,绘画非常昂贵,所以你必须非常小心。
这会影响哪些浏览器?
通常情况下,浏览器之间的行为不同。 今天,Chrome、Safari 和 Opera 都重新绘制,即使 GIF 被遮盖了。 另一方面,Firefox 发现 GIF 被遮盖了,不需要重新绘制。 Internet Explorer 仍然是一个黑盒子,即使在 IE11 中——因为 F12 工具仍在开发中——也没有迹象表明是否正在进行任何重绘。
我怎么知道我是否有这个问题?
最简单的方法是使用 Chrome DevTools 中的“Show paint rectangles”。 加载 DevTools 并按下右下角的齿轮 ( 选择 显示绘制矩形。 下 ) 并在渲染 部分
图 2:在 Chrome DevTools 中启用 Show paint rectangles。
现在您需要做的就是寻找像这样的红色矩形:
图 3:DevTools 的 Show Paint Rectangles 使用红色矩形提示动画 GIF 问题。
屏幕上的小红框表示 Chrome 正在重绘某些东西。 你知道在其他元素后面隐藏了一个加载器 GIF,所以当你看到像这样的红色框时,你需要隐藏可见元素并检查你是否让动画 GIF 旋转了。 如果你有那么你需要弹出一些 CSS 或 JavaScript 来应用 display: none
或者 visibility: hidden
它或它的父元素。 当然,如果它只是一张背景图片,那么您应该确保将其删除。
如果您想在实时站点中查看此行为的示例,请查看 Allegro ,其中每个产品的图像都有一个加载器 GIF,该 GIF 是模糊的而不是明确隐藏的。
结论
达到 60fps 意味着 仅 执行呈现页面所需的操作,而不会做更多。 去除多余的油漆是实现这一目标的关键步骤。 保持运行的动画 GIF 可能会触发不必要的绘制,您可以使用 DevTools 的 Show paint rectangles 工具轻松找到和调试这些东西。
现在,您不会让动画小猫加载器 GIF 永远运行,对吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论