scroll性能..........
从性能的角度来看,滚动看起来并不像你想的那样。毕竟,你的内容是风格化的,所有的资源都被加载或加载,所以为什么突然间我们会关心你在滚动时会发生什么呢?简单的原因是,每当你滚动浏览器需要画你的网站或应用程序的屏幕。这意味着我们有机会最大限度地减少浏览器的工作量,从而最大限度地提高页面性能。
实际上,使用应用程序时,平滑滚动实际上是用户体验中经常被忽视的一个关键部分。当您获得滚动性能的权利时,您的应用程序将会感觉如丝般顺滑和令人愉快的使用,而不是一个笨重和不自然的经验。
滚动的细节让我们来看看当你滚动时会发生什么样的事情。为了理解我们必须对浏览器如何在屏幕上绘制东西做一个简要的介绍。一切都从DOM树开始,DOM树实质上是页面内的所有元素。浏览器看看你的风格的DOM,它发现它认为看起来一样,当你滚动的东西。然后将这些元素分组在一起并拍摄它们的图片,这就是所谓的图层。每个图层都需要被绘制和光栅化为纹理,然后合成到屏幕上的图像。
如果您对Chrome浏览器的更多详细信息感兴趣,请查看本摘要文章。
无论何时滚动页面,浏览器可能都需要绘制这些图层中的一些像素(有时称为合成器图层)。通过将事物分组成图层,当特定图层内的内容发生变化时,我们只需要更新特定图层的纹理,而我们只需要绘制和栅格化渲染图层中被损坏的部分而不是整个东西。很明显,如果你在滚动的时候像在视差网站那样移动的东西,那么你可能会损坏大面积,可能跨越多层,这可能导致大量昂贵的油漆工作。
总之,less painting is better。
诊断你的Paints这么多理论,让我们来看看这是如何在实践中解决的。这是一个演示页面,您可以在Chrome的DevTools中查看。如果打开“时间轴”面板,将其设置为帧模式,点击录制按钮,然后开始滚动,您应该看到一堆条形的绿色条。我录制了一个视频,展示你要做什么,以及你应该看到什么:
在时间线下方的列表中,您将看到一大堆油漆记录。这是Chrome绘画和栅格化页面的合成器图层的纹理。(所有绘画完成后,您还可以看到一些复合图层记录,这些记录可能是所有这些更新图层都合成为可以在屏幕上显示的。
在每个油漆记录旁边,您将看到所绘油墨区域的尺寸,如果您翻转,Chrome会突出显示页面中必须重新绘制的区域。另一种查看重绘区域的方法是在Chrome的DevTools设置中启用“显示绘制矩形”,该设置可通过右下角的小齿轮图标访问。这是您滚动时关于页面执行情况的第一个指标。提醒一下:你应该寻找尽可能小的油漆区域。
在侧面菜单可见的情况下,你会看到油漆区域基本上是整个屏幕,性能真的受到影响。这是因为Chrome做了一个受损区域的联合。在这种情况下,沿着底部的薄的100%宽的条带用于刚才看到的内容和100%高的侧面菜单,它必须绘制到相同的合成层中,所有这些都合并到100%宽的区域, 100%高。如果您使用顶部的复选框禁用侧边菜单并再次滚动,您将注意到唯一需要执行的重新绘制工作是沿着底部的细条,并且发生得非常快。
如果你想看到一个真实世界的例子,请尝试加载Google+,然后将侧面导航position: fixed改为position: absolute。当然,这会改变网站的行为,但重点在于您可以通过切换样式来获得真正的性能提升。你对这一切的反应可能是决定position:fixed永远不要使用,但实际上所有这些都取决于上下文和要求。大部分事情都有时间和地点,重要的是能够衡量和理解你的决定的影响。
图像大小调整除了基本的油漆记录之外,我们实际上还可以获得更多关于图像的信息。如果您在录制过程中不断调整页面大小,则会看到一些绘画记录可让您轻松查看更多详细信息。如果你这样做,你应该看到一些图像调整大小记录。这正是它所说的:浏览器不得不调整图像大小作为其绘画工作的一部分。
如果您将大图像发送到设备,然后使用CSS或图像尺寸属性缩放它们,则更有可能看到发生这种情况。当然,浏览器必须重新调整图像的数量,以及频率如何影响页面在主浏览器线程上的性能,从而阻止其他工作的发生。
因此,发送不需要调整大小的图像的情况非常强烈。作为一个有趣的侧面说明,在某些情况下,缩放操作是不可避免的,特别是在移动的情况下,当捏合到缩放时用户可以轻松地从1改变缩放。在这种情况下,你可以做的事情很少,但知道它可以(也可能会)发生是很好的。从好的方面来说,浏览器中的东西总是在不断改进,特别是渲染是一个热门话题,所以你可以期待在未来的几个月里事情会变得更好。
所有这一切说,还有其他的事情可能会影响你的滚动性能:
- Expensive Styles
- Reflows and repaints
- Failing to debouncing your scroll events
让我们来更详细地讨论其中的每一个。
所以首先要说的是并不是所有的样式都是相同的,从渲染的角度来看,像box-shadow这样的效果经常被引用为特别昂贵,这只是因为它们相关的绘制代码需要很长时间运行相比其他风格。这意味着,如果你有昂贵的款式需要经常重新粉刷,你可能会受到打击。第二点要说的是,没有什么东西可以保持不变,所以今天的一个缓慢的风格明天可以优化和快速,而且不同于浏览器。这里的关键是利用像我们上面所做的开发工具来确定瓶颈来自哪里,然后看看如何减少浏览器的工作量。
在Google I / O 2012上, Nat Duca和Tom Wiltzius做了一个很棒的演讲,讨论如何在Chrome中渲染你的渲染效果,还有一堆金色的提示,包括昂贵的风格以及如何衡量它们的影响。
Reflows and repaints每当你offsetTop在JavaScript中请求一个元素的属性,你就立即给浏览器一个很大的工作,因为它现在必须关闭并且布置页面,这样才能给你正确的答案。这个过程被称为回流。如果我们根据offsetTop值来更改元素的另一个属性(因此它的合成器层)将需要重新绘制,这可能是昂贵的。它也具有连锁效应,我们offsetTop通过重绘使计算失效,因为就浏览器而言,事情发生了变化。
当你扩大到一组元素时,真正的问题就出现了。如果我们立即计算每个元素的位置,然后重新绘制它,我们迫使浏览器进入一个昂贵的和不必要的回流重绘周期。在这些情况下,我们需要做的就是通过两次通过做事情来避免这个循环:在第一次通过时,我们只是收集offsetTop值,第二次是做视觉更新。通过这样做,我们避免了重复计算页面中元素位置的需要,假设我们使用requestAnimationFrame,我们将在浏览器的最佳时间安排视觉更新。
另外值得一提的是,除了offsetTop之外,还有其他一些操作会导致回流操作发生,所以值得检查一下,所以你要小心。
Failing to debouncing your scroll events假设您正在构建一个大视差滚动网站。当你得到滚动事件时,你的自然倾向可能是做视觉更新。这里的主要问题是滚动事件没有定时到浏览器的可视化更新(即在requestAnimationFrame回调中),因此您有可能在单个渲染框架内执行多个更新。如果你的更新是昂贵的,如果你正在建造一个视差网站(大量的损坏区域,大量的绘画和合成),那么他们更可能是那么多,那么做这些不必要的时间是一个坏主意。要解决这个问题,你需要去掉你的滚动事件。您只需在收到滚动事件时将最后一次滚动值存储在变量中,然后在a中执行视觉更新即可完成此操作requestAnimationFrame,利用最后一个已知的值。这意味着浏览器可以在正确的时间安排视觉更新,而且我们没有在每个框架内完成更多的工作。
我们在前面的文章中介绍了回流/重绘周期,所以如果您想了解更多信息,请查看。
结论现在,您已经知道如何解释Chrome的DevTools时间表,以便在滚动期间评估应用程序的性能。值得重申的是,性能特征总是在变化,所以虽然有些事情比现在的其他事情更快,但是随着时间的推移,它们会发生变化和变化,这是了解如何解读所看到的读数的关键,以便您能够适应做法相应。
您应该始终检查您的开发人员工具中的实际性能数据。用眼睛来比较变化是很有吸引力的,但是结果可能并不明显。所以不要猜测,测试它。
共同学习,写下你的评论
评论加载中...
作者其他优质文章