Web性能优化-I
关于
关键渲染路径(CRP)及其优化、PRPL模式和性能预算。
介绍
Web 性能的关键在于让网站运行速度更快,包括让缓慢的进程看起来更快。网站性能的好坏与用户体验以及大多数网站的整体效率息息相关。无论用户处于何种环境,网站和应用程序都需要为所有用户提供快速高效的体验。为了实现这一点,我们使用性能优化。MDN Web 文档将性能优化分为四个主要方面。
-
减少总体加载时间
- 压缩并缩小所有文件。
- 减少服务器和用户代理之间来回发送的文件和其他 HTTP 请求的数量。
- 采用先进的加载和缓存技术,并在用户真正需要时有条件地为其提供所需的内容。
-
尽快使网站可用
- 实现方式是:首先加载关键组件,为用户提供初始内容和功能;然后,使用延迟加载,将不太重要的功能推迟到稍后加载,仅在用户访问或与其交互时才请求和显示内容。通过预加载功能,用户更有可能与下一个功能进行交互。
-
流畅度和互动性
- 通过骨架界面、可视化加载器以及明确指示某事正在发生并且即将开始工作来提高网站的感知性能。
-
性能测量
- 用于监控性能并验证站点工作的工具和指标。需要注意的是,并非所有性能优化都适合您的解决方案和需求。
- 浏览器性能测量工具包括 Lighthouse(Chrome)、网络监视器、性能监视器。此外,还有一些第三方托管工具,例如 PageSpeed Insights(Google)、WebPage Test、GTMetrics(实际上是 Lighthouse)可以帮助测量性能。
- 这些工具用来描述性能的关键指标是:
- 首次绘制 - 用户在浏览器中看到变化所需的时间。最大内容绘制 (LCP) - 用户在浏览器中看到内容(例如文本、图像或其他内容)所需的时间。
- 首次有效绘制 (FMP) - 用户看到真正有意义的内容所需的时间。因此,当全部内容和 Web 字体加载完毕后,用户才能从所见内容中获取意义。
- 交互时间——内容加载完成并与 UI 进行交互所需的时间,以便用户可以实际点击按钮、填写表格或执行网站上将要发生的任何其他操作。
网站达到上述每个点所需的时间越长,用户感到厌烦或彻底放弃用户体验的可能性就越大。因此,良好的性能不仅对访问者更有利,对您也更有利,因为您无需支付太多托管费用,还能提高您的 Google 排名,最终,对环境也更有利。
关键渲染路径 (CRP)
要了解性能优化,首先需要深入了解在浏览器的地址栏中输入内容如何导致页面在视口中呈现。
一切都始于浏览器向其互联网服务提供商发送某个 site.com 的请求。
然后,ISP 会立即将请求发送到 DNS 域名服务(网络电话簿),将您正在寻找的网站映射到该网站的地址。
此 DNS 查找针对每个唯一的主机名进行。因此,如果您请求的网站使用了外部托管的字体、JavaScript 库、图片、视频或其他服务,则此 DNS 查找会针对每个不同的服务进行。每当有新的域名加入时,都必须进行新的 DNS 查找。这是第一个主要的性能瓶颈。
为了消除部分性能开销,域名与 IP 地址的关联可能会在多个不同步骤中进行缓存,您的 ISP 会将其作为信息缓存,它也可能缓存在您的路由器和计算机上。这样,当您向之前请求的同一域名发送请求时,我们只需从更靠近计算机的位置获取缓存,而不必再次进行整个 DNS 查找。但这也意味着,如果 DNS 在此期间发生变化,您将获得错误的地址指向,并且无法按预期工作。
一旦确定了 IP 地址,浏览器和服务器就会执行所谓的 TCP 握手,在此过程中,它们交换身份密钥和其他信息,以建立临时连接和工作关系。同时,也会确定连接的类型:是常规 HTTP 连接还是加密的 HTTPS 连接?如果是后者,则会交换加密密钥。如果浏览器和服务器都支持 HTTPS,则事务将从 HTTP 1.1 更新到 HTTP 2,从而显著提升性能。
现在我们已经建立了连接,一切准备就绪。此时,浏览器会发送一个 HTTP GET 请求,请求它要查找的资源。这个初始 GET 请求将指向服务器位置上的默认文件,通常是 index.html、index.php、index.js 或类似的文件。
浏览器最终接收到它所查找的实际页面的第一个字节所需的时间,以到达第一个字节的时间或 TTFB 来衡量。浏览器接收到的第一个数据(称为数据包)始终为 14 KB,之后每次传输数据包大小都会翻倍。这意味着,如果您希望某件事立即发生,就需要将其塞进最初的 14 KB 中。
浏览器现在获取一个 HTML 文档文件,并开始从上到下读取它,然后解析其中的数据。这意味着 HTML 被转换成 DOM 树,CSS 被转换成 CSSOM 树和页面 CSS 的对象模型,这使得浏览器能够渲染 CSS 以供 JavaScript 与其交互。在解析文档的过程中,浏览器还会加载遇到的任何外部资源。这意味着每当它遇到新的 CSS 文件或对其他任何内容的引用时,它都会发送新的请求,服务器会响应并返回请求,然后请求会被放入系统,浏览器也会开始渲染它。
然而,对于 JavaScript,浏览器会停止所有其他操作,等待文件完全下载。为什么?因为 JavaScript 很可能会修改 DOM 或 CSSOM,或者两者兼而有之。这就是所谓的渲染阻塞,无论正在进行什么渲染,浏览器都会停止,并在等待 JavaScript 完全加载并完全执行的整个过程中一直处于阻塞状态。一旦所有这些解析完成,渲染就可以正式开始,此时浏览器会将 DOM 和 CSSOM 结合起来,在视口中对文档进行样式设置、布局、绘制和合成。
首次内容绘制的度量时间指的是所有这些操作完成所需的时间。对于我们而言,重要的是记住实际发生的情况,这样我们才能识别瓶颈并添加性能增强功能,以尽快克服它们。
优化CRP
如今,当您在网络上与内容交互时,您正在使用两种不同版本的 HTTP 协议之一:旧的 HTTP/1.1 或更现代的 HTTP/2。使用哪个协议版本对网站的性能有显著的影响。在 HTTP/1.1 中,浏览器请求的所有文件都是同步加载的,一个接一个。因此,一个典型的包含两个样式表、几张图片和一些 JavaScript 的 HTML 页面需要浏览器依次加载 HTML 文档、CSS 文件、JavaScript 文件,最后加载图片文件。这种加载方式速度慢、效率低,并且会导致性能低下。
为了解决这个显而易见的问题,浏览器会通过最多打开六个并行连接到服务器来下载数据。然而,这会造成所谓的“队头阻塞”,即第一个文件(HTML 文件)会阻止其余文件的下载。这也会给互联网连接和基础设施(包括浏览器和服务器)带来巨大的压力,因为你现在使用的是六个连接,而不是一个连接。
在 HTTP/2 中,我们实现了所谓的多路复用。浏览器可以通过一个连接同时下载多个单独的文件,并且每个下载过程彼此独立。这意味着,使用 HTTP/2,浏览器可以在遇到新资源时立即开始下载,整个过程速度显著加快。
现在,要使 HTTP 正常工作,需要满足几个关键条件。第一,服务器必须支持 HTTP/2。第二,浏览器也必须支持 HTTP/2。第三,连接必须通过 HTTPS 加密。如果任何一个条件不满足,连接将自动回退到 HTTP/1.1。因此,为了以最少的工作量获得即时性能提升,请为您的域名获取 SSL 证书,并确保您的服务器支持 HTTP/2。
确定哪些瓶颈会导致性能问题是性能优化的关键。服务器本身可能会导致性能不佳。
下一个瓶颈是浏览器与托管渲染页面所需文件的服务器之间的连接。对于每个连接,都需要进行整个 DNS 和 TCP 握手循环,这会减慢整个过程的速度。
缓存(或存储资源)也是性能优化的方法之一。这可以在服务器、CDN 或浏览器中完成。
- 服务器上的缓存
如果您运行的网站依赖于服务器端渲染,这意味着每个页面或视图都是由服务器在请求时动态生成的,那么缓存可能会带来巨大的性能提升。启用缓存后,服务器不再需要在每次请求页面时都渲染页面。
相反,在渲染页面时,会创建该页面的快照并将其存储在服务器缓存中。下次访问者访问该网站时,将访问此存储的缓存快照,而不是新渲染的页面。这就是静态网站生成器如此流行的原因:它们生成预渲染的可缓存静态页面,从而绕过整个 CMS 服务端渲染问题。这种缓存的挑战在于其动态功能。例如,每次添加新评论时,都需要清除缓存,然后重新生成页面。即便如此,所有依赖于服务器端渲染的网站都应该启用缓存,因为性能优势非常显著。
- CDN 上的缓存
CDN 实际上是网站的外部缓存服务。CDN 还可以进行边缘计算。CDN 会在请求时渲染页面,然后自行缓存。这种边缘方法与 Gatsby 等现代静态网站生成器以及所有基于 JavaScript 的网站生成器和框架兼容,因为它们默认提供静态资源,并且专为在现代 Web 架构中运行而构建。
- 浏览器中的缓存
这里我们主要可以做两件事。一是存储现有资源。这样,当访问者再次访问网站时,所有信息都已缓存在浏览器中。二是提前将文件推送到浏览器,这样当浏览器请求文件时,已经缓存的文件就被加载了。所有浏览器都会自动进行一定程度的缓存,我们也可以指示浏览器如何精确地处理资源的缓存。对于不太可能发生变化的资源,例如主样式表、JavaScript 和其他图像,长缓存是合理的。对于可能随时间变化的资源,短缓存时间或根本不进行缓存可能更合理。
为了确保新的和更新的资源始终能够到达访问者,我们可以使用缓存清除策略,例如在文件名后附加自动哈希值,或者依靠服务器本身记录每个文件的文件名和文件日期,然后自动进行缓存。您还可以将 CSS 和 JavaScript 文件拆分成更小的模块,这样,当您更新 CSS 或 JavaScript 中的某些内容时,无需为整个网站重新缓存整个样式表,只需重新缓存包含该更新的模块即可。
PRPL 和绩效预算
为了使您的网站或应用程序获得最佳性能,请始终牢记PRPL模式。PRPL
是以下缩写的缩写:将重要资源
推送或预加载到浏览器:初始加载时使用服务器推送,并在下一轮加载时使用 Service Worker,应用程序将运行得更快。通过向浏览器提供关键 CSS 和 JavaScript,尽快
渲染初始路由,应用程序的感知性能将得到提升。
预缓存剩余资源,以便在浏览器需要时可用。
延迟加载所有非关键资源,使它们仅在实际需要时加载,这样可以缩短初始加载时间,避免访问者将带宽浪费在他们永远不会使用的资源上。
决定网站或应用性能的首要指标是其权重。
性能预算为您提供了衡量每个新功能的指标,以及在需要做出艰难决策时使用的工具。性能预算可能包括对页面总权重、图片总权重、HTTP 请求数量、字体、图片或外部资源的最大数量等的限制。
我们现在拥有可以集成到构建流程中的工具,例如 Webpack 的性能选项(可直接在 Webpack 和 Lighthouse 轻钱包中获取),它使您能够随时根据性能预算测试构建,并在图片过大、JavaScript 过大、CSS 过大或其他任何问题时发出警告。
绩效预算的一些最佳实践指标包括:
- 确保您的网站满足三秒以下的速度指数。
- 交互时间不到五秒。
- 最大的内容绘制时间不到一秒
- 最大潜在首次输入延迟低于 130 微秒。
- Gzipped JavaScript 包的最大大小在 170kb 以下。
- 总捆绑包大小不到 250kb,并且所有这些都发生在 3G 的低功耗功能手机上。
现在这些性能预算指标非常严格,很难达到。它们也是 Lighthouse 等工具用来测试性能的指标。
那么问题来了,如何制定切合实际的绩效预算?
- 在慢速网络上建立单独的性能预算,在快速网络上建立笔记本电脑/台式机设备的性能预算。
- 做绩效审计。
- 根据审计制定合理目标。
- 根据性能预算测试生产版本。
- 进行竞争对手绩效审计:使您的绩效目标优于竞争对手。
- 尽管每个项目的绩效预算都是独一无二的,并且会随着时间的推移而改变,但要根据绩效预算测试所有工作。