大家好,这里是全网优质技术社区:前端修罗场。我们知道,渲染一个页面就是将服务器的响应内容翻译成图片的过程。但是如果你的页面渲染性能不好,可能会带来比较高的跳出率。在本文中,我将重点介绍网页的初始呈现,从解析HTML开始。我将探讨可能导致渲染时间过长的问题,以及如何解决这些问题。关键呈现路径(CRP)关键呈现路径(CRP)是浏览器将代码转换为屏幕上可显示像素的过程。它有几个阶段,其中一些可以并行执行以节省时间,但有些部分必须顺序完成。如下图所示:首先,浏览器得到响应后,开始解析。当它遇到依赖项时,它会尝试下载它。如果它是样式表文件,浏览器必须在呈现页面之前完全解析它,这就是CSS阻止呈现的原因。对于脚本,浏览器必须:停止解析,下载脚本,然后运行它。只有这样它才能继续解析,因为JavaScript程序可以改变网页(尤其是HTML)的内容。这就是JS阻止解析的原因。完成所有解析后,浏览器构建文档对象模型(DOM)和层叠样式表对象模型(CSSOM)。将它们组合在一起会产生渲染树。页面的非显示部分不会进入渲染树,因为它只包含绘制页面所需的数据。倒数第二步是布局渲染树。这个阶段也叫回流:就是计算每个渲染树节点的每个位置和大小的地方。最后一步是绘制。它根据浏览器在前一阶段计算的数据为像素着色。优化相关的结论因此,基于这个过程,我们在优化性能方面得出了一些结论。如果要提高页面初始渲染的性能,需要:减少传输的数据量减少浏览器必须下载的资源数量(尤其是被阻塞的资源)减少CRP的长度同时,我们会根据以下3个指标衡量优化效率:FP(FirstPaint)FCP(FirstContentfulPaint)FMP(FirstMeaningfulPaint)除了渲染时间,还有其他一些因素需要考虑。例如,您的页面使用了多少阻塞资源以及下载它们需要多长时间。性能优化策略鉴于我们上面得出的结论,我们总结出网站性能优化的三个主要策略:最小化通过网络传输的数据量;减少通过网络传输的资源总数;缩短关键渲染路径;1.首先,移除所有未使用的部分,例如JavaScript中无法访问的函数,带有选择器的样式永远不会匹配任何元素,以及被CSS永久隐藏的HTML标签。其次,删除所有重复项。然后,我建议设置一个自动压缩过程。例如,它应该从您的后端服务中删除所有注释(但不包括源代码)和每个不包含附加信息的字符(例如JS中的空格)。完成后,剩下的可能是文本字符串。这意味着我们可以安全地应用压缩算法,例如GZIP(大多数浏览器都能理解)。最后,还有缓存。它不会在浏览器第一次呈现页面时提供帮助,但会在后续访问时节省很多。但是,记住两件事很重要:如果您使用CDN,请确保支持缓存并正确设置。不是等待资源过期,而是将文件的“指纹”嵌入其URL中以使本地缓存失效。当然,应该为每个资源定义一个缓存策略。有些可能很少更改或根本不更改,有些更改很快,有些文件包含敏感信息(您可以使用“私有”来防止CDN缓存私有数据)。2.减少关键资源总数“关键”仅指网页正确呈现所需的资源。因此,我们可以直接跳过所有不参与流程的样式和脚本文件。样式为了告诉浏览器不需要特定的CSS文件,我们应该为所有引用样式表的链接设置media属性。使用这种方法,浏览器将只根据需要处理与当前媒体(设备类型、屏幕尺寸)匹配的资源,同时降低所有其他样式表的优先级。例如,如果您将media="print"属性添加到引用打印页面样式的样式标签,那么当媒体未被打印时,这些样式将不会干扰您的关键渲染路径。为了进一步改进流程,您还可以内联一些样式,这至少为我们节省了一次往返服务器的时间。脚本如上所述,脚本会阻止解析,因为它们可以改变DOM和CSSOM。为避免这种情况,所有脚本标签都必须标有属性--async或defer。标记为async的脚本不会阻塞DOM构造或CSSOM,因为它们可以在CSSOM构造之前执行。但是请记住,内联脚本无论如何都会阻止CSSOM,除非你将它们放在CSS之上。相反,标记为defer的脚本将在页面加载结束时执行。换句话说,使用defer脚本直到页面加载事件被触发才执行,而使用async脚本在文档被解析时在后台运行。3.缩短关键渲染路径长度最后,CRP长度应尽可能减少。媒体查询作为样式标签的属性将减少必须下载的资源总数。script标签属性defer和async会阻止对应的脚本阻塞解析。使用GZIP压缩、压缩和归档资源将减少传输数据的大小(从而减少数据传输时间)。内联一些样式和脚本还可以减少浏览器和服务器之间的往返次数。根据最新的最佳性能实践理念,网站应该做的最快的第一件事就是显示ATF内容。ATF代表首屏。这是无需滚动即可立即看到的区域。因此,最好重新安排与渲染相关的所有内容,以便首先加载所需的样式和脚本,同时停止其他所有内容(既不解析也不渲染)。综上所述,网站性能优化包括网站响应的方方面面,如缓存、设置CDN、重构、资源优化等,但这些都是可以循序渐进的。作为Web开发人员,您可以将本文作为参考,并始终记住在实验前后测量性能。浏览器开发人员尽最大努力为您访问的每个页面优化网站性能,这就是为什么浏览器通常会实现所谓的“预加载器”。该程序的这一部分会先于您在HTML中请求的资源进行扫描,以便一次发出多个请求并让它们并行运行。这就是为什么您在HTML中(逐行)以及脚本标签保持样式标签彼此靠近的原因。此外,尝试批量更新HTML以避免多个布局事件,这些事件不仅由DOM或CSSOM的更改触发,而且在设备方向更改和窗口大小调整时触发。
