本文概述
你的网页的渲染性能是否符合当今的标准?渲染是将服务器的响应转换为用户访问网站时浏览器”绘制”的图片的过程。较差的渲染性能可能会转化为相对较高的跳出率。
有不同的服务器响应来确定是否呈现页面。在本文中, 我们将重点介绍网页的初始呈现, 首先是解析HTML(前提是浏览器已成功接收HTML作为服务器的响应)。我们将探讨可能导致较长渲染时间的问题, 以及如何解决这些问题。
关键渲染路径
关键渲染路径(CRP)是浏览器将代码转换为屏幕上可显示像素的过程。它具有多个阶段, 其中一些阶段可以并行执行以节省时间, 但是某些部分必须相应地完成。这里是可视化的:
首先, 一旦浏览器获得响应, 它就会开始解析它。当遇到依赖项时, 它将尝试下载它。
如果是样式表文件, 则浏览器将不得不在呈现页面之前对其进行完全解析, 这就是CSS被称为呈现阻止的原因。
如果是脚本, 则浏览器必须:停止解析, 下载脚本并运行。只有在那之后它才能继续解析, 因为JavaScript程序可以更改网页的内容(尤其是HTML)。这就是为什么JS被称为解析器阻止。
完成所有解析后, 浏览器将构建文档对象模型(DOM)和级联样式表对象模型(CSSOM)。将它们组合在一起即可得到渲染树。页面的未显示部分不会进入”渲染树”, 因为它仅包含绘制页面所需的数据。
倒数第二步是将”渲染树”转换为”布局”。此阶段也称为回流。在此计算每个”渲染树”节点的每个位置及其大小。
最后, 最后一步是Paint。它涉及根据浏览器在先前阶段中计算出的数据从字面上为像素着色。
与优化有关的结论
如你所料, 网站性能优化过程涉及对网站的更改, 这些更改减少了:
- 必须传输的数据量
- 浏览器必须下载的资源数量(尤其是阻塞资源)
- CRP长度
此外, 我们将详细介绍其操作方法, 但首先, 有一个重要规则需要遵守。
如何衡量绩效
优化的重要规则是:首先进行测量, 然后根据需要进行优化。大多数浏览器的开发人员工具都有一个名为”性能”的标签, 这就是进行评估的地方。优化最快的初始(第一个)渲染时, 最重要的事情是发生以下事件的时间:
- 第一次油漆
- 首次满意涂料
- 第一有意义的油漆
在这里, “绘制”是指成功渲染页面, 这是关键渲染路径中的最后一个阶段。一些渲染可能会接连发生, 因为浏览器试图尽快显示某些内容并稍后进行更新。
除了渲染时间外, 还需要考虑其他因素-最重要的是, 使用了多少阻塞资源以及下载它们需要多长时间。进行测量后, 可以在”性能”选项卡中找到此信息。
绩效优化策略
鉴于以上所述, 网站性能优化有以下三种主要策略:
- 最大限度地减少通过有线传输的数据量,
- 减少要通过网络传输的资源总数, 以及
- 缩短关键渲染路径
1.最小化要传输的数据量
首先, 删除所有未使用的部分, 例如JavaScript中无法访问的功能, 带有从未与任何元素匹配的选择器的样式以及永远被CSS隐藏的HTML标记。其次, 删除所有重复项。
然后, 我建议设置一个自动缩小过程。例如, 它应该从后端服务中删除所有注释(但不删除源代码), 并且不包含任何其他信息的每个字符(例如JS中的空白字符)都应删除。
完成之后, 剩下的就是文本了。这意味着我们可以安全地应用诸如GZIP之类的压缩算法(大多数浏览器都可以理解)。
最后, 有缓存。浏览器第一次呈现页面时不会有任何帮助, 但在以后的访问中会节省很多。不过, 记住两点至关重要:
- 如果使用CDN, 请确保支持并在此正确设置了缓存。
- 你可能不希望等待资源的到期日期到来, 而是希望有一种方法可以较早地从一侧进行更新。将文件的”指纹”嵌入其URL中, 以使本地缓存无效。
当然, 应该为每个资源定义缓存策略。有些可能很少更改或根本不会更改。其他人的变化速度更快。有些包含敏感信息, 有些则被视为公开信息。使用”私有”指令可以防止CDN缓存私有数据。
尽管图像请求不会阻止解析或渲染, 但也可以优化网络图像。
2.减少关键资源的总数
“关键”仅指网页正确呈现所需的资源。因此, 我们可以直接跳过该过程中不涉及的所有样式。还有所有脚本。
样式表
为了告诉浏览器不需要特定的CSS文件, 我们应该将媒体属性设置为所有引用样式表的链接。使用这种方法, 浏览器将仅在必要时处理与当前媒体相匹配的资源(设备类型, 屏幕尺寸), 同时降低所有其他样式表的优先级(无论如何将对其进行处理, 但不作为关键呈现的一部分)路径)。例如, 如果你将media =” print”属性添加到引用要打印出页面的样式的样式标签中, 则在不打印介质时(即, 在显示媒体时), 这些样式不会干扰你的关键渲染路径。浏览器中的页面)。
为了进一步改善过程, 你还可以使某些样式内联。这为我们节省了至少一个往返服务器的往返时间, 否则该往返时间将需要获取样式表。
剧本
如上所述, 脚本是解析器阻止程序, 因为它们可以更改DOM和CSSOM。因此, 不更改脚本的脚本不应进行块解析, 从而节省了时间。
为了实现这一点, 所有脚本标签都必须标记有属性-异步或延迟。
标有异步的脚本不会阻止DOM的构建或CSSOM, 因为可以在构建CSSOM之前执行它们。但是请记住, 除非你将内联脚本置于CSS之上, 否则它们仍然会阻止CSSOM。
相比之下, 标记为defer的脚本将在页面加载结束时进行评估。因此, 它们不应影响文档(否则, 它将触发重新渲染)。
换句话说, 使用defer, 直到页面加载事件触发后脚本才执行, 而async则使脚本在解析文档时在后台运行。
3.缩短关键渲染路径的长度
最后, 应将CRP长度缩短到可能的最小值。上述方法将部分地做到这一点。
媒体查询作为样式标签的属性将减少必须下载的资源总数。脚本标记属性defer和async将阻止相应的脚本阻止解析。
使用GZIP的压缩, 压缩和归档资源将减少传输数据的大小(从而也减少了数据传输时间)。
内联某些样式和脚本可以减少浏览器和服务器之间的往返次数。
我们还没有讨论的是在文件之间重新排列代码的选项。根据最佳性能的最新想法, 网站应该做的最快的事情就是显示ATF内容。 ATF代表首折。这是立即可见的区域, 无需滚动。因此, 最好以先加载所需样式和脚本的方式重新排列与呈现有关的所有内容, 同时停止所有其他操作-既不解析也不呈现。并且始终记得在进行更改之前和之后进行测量。
结论:优化涵盖了整个堆栈
总而言之, 网站性能优化结合了网站响应的所有方面, 例如缓存, 设置CDN, 重构, 资源优化等, 但是所有这些可以逐步完成。作为网络开发人员, 你应该将本文用作参考, 并且始终记住要在实验前后评估性能。
浏览器开发人员会尽最大努力为你访问的每个页面优化网站性能, 这就是为什么浏览器通常会实现所谓的”预加载器”。程序的这一部分先扫描你在HTML中请求的资源, 以便一次发出多个请求并使其并行运行。这就是为什么最好使HTML中的样式标签(逐行)以及脚本标签彼此靠近。
此外, 请尝试将更新批处理为HTML, 以避免发生多个布局事件, 这些事件不仅是由于DOM或CSSOM的更改, 而且还因为设备方向的更改和窗口大小的调整而触发。
有用的资源和进一步的阅读:
- PageSpeed见解
- 缓存清单
- 测试你的网站是否启用GZIP的方法
- 高性能浏览器网络:Ilya Grigorik所著