Web 性能
构建一个网站需要 HTML、CSS 和 JavaScript。为了构建人们需要的、能吸引和留住用户的网站和应用,你需要创建一个良好的用户体验。良好用户体验的一部分是确保内容能够快速加载并响应用户交互
。这就是所谓的 web 性能。
为什么关心性能
Web 性能及其相关的最佳实践对于网站访问者拥有良好的体验至关重要。从某种意义上说,web 性能可以被认为是 web 无障碍的一个子集
。在性能和无障碍方面,你需要考虑网站访问者使用的设备以及设备的连接速度。
提高转化率
减少网站的下载和渲染时间可以提高转化率和用户留存。
转化率是指网站访问者执行某种测量或期望操作的比率。
性能影响转化;提高 web 性能就能提高转化。网站访问者期望一个网站在两秒内或更短的时间内加载;有时在移动设备上甚至更短(通常需要更长时间)。从 3 秒开始,这些网站访问者就会开始放弃缓慢的网站。
什么是 web 性能
Web 性能是对网站或应用程序的客观度量和用户的体验。这包括以下主要方面:
减少总体负载时间
需要多长时间才能将渲染网站所需的文件下载到用户的计算机上?这往往受到延迟
、文件大小
、文件数量
以及其他因素的影响。一般策略是使文件尽可能小
,尽可能减少 HTTP 请求
的次数,并采用巧妙的加载技术(例如 preload
)使文件更快可用。
尽快使网站可用
简单来说就是以合理的顺序加载
你的网站资源,以便用户能够更快地开始使用。在用户继续执行主要任务的同时,任何其他资源都可以在后台继续加载。有时我们也会在实际需要时才加载资源(这被称为懒加载
)。网站从开始加载,到达到可用状态为止所需的时间被称为交互等待时间
。
流畅性和交互性
应用程序是否可靠,使用起来是否愉快?滚动是否流畅?按钮是否可点击?弹出窗口是否能够快速打开,并且在打开时动画是否流畅?在制作流畅的应用程序时,有很多优秀实践可以参考。例如使用 CSS 动画而不是 JavaScript 来制作动画,并尽量减少由于 DOM 变化而引起重绘
UI 的次数。
感知性能
用户所体验到的,是网站看起来有多快,而不是网站实际有多快。用户感受到的性能与任何客观统计数据一样重要,甚至可能更重要。但这种主观的感受不容易测量。感知性能是用户的感受,而不是度量标准。即使操作将花费很长时间(因为延迟或其他原因),也可以通过显示“加载中”的旋转指示器或一系列有用的提示和技巧(或笑话,以及其他你认为合适的内容)来保持用户在等待期间的参与度。
性能测量
Web 性能包括测量应用程序的实际速度和感知速度,在可能的情况下进行优化,然后监视性能,以确保已经优化过的内容保持优化状态
。这涉及到许多度量标准(可以指示成功或失败的可度量指标)和测量这些度量标准的工具.
总而言之,许多特性都会影响性能。包括延迟、应用程序大小、DOM 节点数量、资源请求数量、JavaScript 性能、CPU 负载等等。重要的是尽量缩短加载和响应时间,并通过增加额外的功能来隐藏延迟:先使网站变得可以交互,同时在后台加载用户体验中的次要部分。
内容如何渲染
为了有效地理解 web 性能、背后的问题以及我们上面提到的主要部分,你需要先了解一些关于浏览器如何工作的细节。这包括:
浏览器的工作原理
当你请求一个 URL 并敲击 Enter 或 Return 按键时,浏览器会找出保存该网站文件的服务器的位置,与之建立连接,并请求文件。请参阅渲染页面:浏览器的工作原理。
// todo 浏览器的工作原理
源顺序
HTML 索引文件的源顺序会显著影响性能。从索引文件链接到的附加资源的下载通常基于引用的顺序
。这是可以调整的,需要进行优化。
请注意
一些资源在被解析和执行完成之前,会阻塞其他的下载
关键路径
这是从服务器下载文件后,浏览器用来构建 web 文档的过程。浏览器按照明确定义的步骤进行操作,优化关键渲染路径以优先显示与当前用户操作相关的内容,将显著改善内容呈现时间。有关更多信息,请参见关键渲染路径。
// todo 关键渲染路径
文档对象模型
文档对象模型(DOM)是一种树状结构,它将 HTML 的内容和元素表示为节点树。这包括所有的 HTML 属性和节点之间的关系。加载页面后的大量 DOM 操作(例如添加、删除或移动节点)可能会影响性能。因此有必要了解 DOM 的工作原理,以及如何减轻此类问题。有关更多信息,请参见文档对象模型。
// todo 文档对象模型
延迟
简单来说,延迟是你的网站信息从服务器传输到用户计算机所需的时间。建立 TCP 和 HTTP 连接需要消耗系统资源,并且在网络上来回传输请求和响应字节时不可避免地存在延迟
。但是有一些方法可以减少延迟(例如,通过下载更少的文件来减少 HTTP 请求的数量,使用 CDN 使你的站点在全球范围内具有更普遍的性能,并使用 HTTP/2 协议提高传输的效率)
// todo 了解延迟
感知性能
网站的加载和渲染速度给人的感觉比网站实际加载和渲染的速度对用户体验的影响更大。即使操作需要很长时间(由于主线程的延迟或不可用),也可以通过显示加载旋转器或一系列有用的提示和技巧来让用户在等待时保持参与(或笑话,或任何您认为合适的其他内容)。
虽然没有一种理想的指标可以准确衡量用户的感受,但指标在衡量改进(和退化)方面是有用的。相关的测量指标包括首次有意义绘制(FMP)、最大内容绘制(LCP)、互动时间(TTI)、渲染开始、DOM 交互和速度指数。
首次绘制 First paint
由浏览器报告,并提供页面开始变化的时间(以毫秒为单位);但这种变化可能是简单的背景颜色更新,或者更不那么显眼的内容。它并不表示加载完成,并且有可能会在没有可见内容被绘制的时候报告时间。
首次有意义绘制 (FCP) First Contentful Paint
报告了浏览器首次绘制任何值得注意的内容的时间,无论是文本、前景或背景图像,或者画布或 SVG;捕捉加载体验的最初阶段。但是,仅仅因为有内容,并不意味着它是有用的内容,或者用户有内容可供消费。
首次有意义绘制(FMP)First Meaningful Paint
首次有意义绘制(FMP)是指内容出现在屏幕上的时间,该内容实际上具有意义;这是用户感知加载体验的更好度量标准,但仍然不是理想的。
最大内容绘制(LCP)Largest Contentful Paint
在 Largest Contentful Paint API 中定义,报告了在视口中可见的最大内容元素的渲染时间。
速度指数 Speed index
也用于近似感知性能:它测量了可见屏幕上像素被绘制的平均时间。它不考虑抖动,也不权衡用户更看重的内容,因此并不是一个完美的指标。
这些指标与初始加载和渲染有关。同样重要的是确保用户开始与网站进行交互时,网站能够快速响应。对于这一点,
可交互时间 time to interactive
可交互时间 是一个很好的指标;它表示加载过程中最后一个长任务完成并且 UI 可用以便用户进行有延迟的交互。
UI 的缺乏响应性和卡顿均会影响到感知性能。即使一个任务可能需要很长时间,但仍然有方法可以让它看起来更快。有一些改善感知性能的技巧。
提升感知性能
对网络、浏览器工作原理、用户对时间的感知等方面的了解,可以更好地帮助您理解如何改善用户交互。然而,并不需要深入了解所有事情的内部机理,包括人类思维的工作方式,也可以改善速度感知。
某件事情的感觉花费时间快慢很大程度上取决于用户是主动还是被动地等待它发生。等待可以有主动和被动阶段。当用户是主动的时候 - 移动鼠标、思考、被娱乐时,他们处于主动阶段。被动阶段是指用户被 passively waiting 等待,比如盯着单色屏幕。如果主动等待和被动等待的时间在客观上是相等的,用户会认为被动等待期更长。如果加载、渲染或响应时间不能再客观地最小化,将等待转变为主动等待而不是被动等待可以让它感觉更快。
尽快显示内容或至少页面的某些部分,并指示内容正在加载对于改善感知性能至关重要。例如,由于页面渲染被加载和解析 CSS 和 JavaScript 阻塞,最小化初始加载所需的 CSS 和 JS 的数量将对改善感知性能产生重大影响。即使字节可能相同,但不阻塞页面渲染会让加载感觉更快。
防止内容跳转和其他重排
图片或其他资源导致内容被向下推或跳转到不同位置,比如加载第三方广告,会让页面感觉仍在加载中,并且对感知性能有害。当用户未进行交互时,内容重排对用户体验尤为不利。如果某些资源的加载速度比其他资源慢,而某些元素在页面的其他部分已被绘制到屏幕上,则可以事先规划并在布局中留出空间
,以便内容不会跳动或调整大小,尤其是在网站已经变得具有交互性之后。
避免字体文件延迟
使用字体既可以提高用户体验,又可能损害用户体验。选择合适的字体是一门艺术,并且可以极大地改善用户体验。字体也可能对用户体验造成损害,特别是如果使用的字体需要导入,并且导入方式不够理想,或者要是使用了。未经样式化的文本出现闪烁和缺失文本都会影响性能。确保备用字体与正式字体具有相同的大小和粗细,这样在字体加载时页面变化就不会那么明显。
使任务启动器显得更具交互性
在按下按键而不是等待按键弹起时发出请求,可以使感知的内容加载减少 200 毫秒。在 KEYUP 后添加一个有趣但不显眼的 200 毫秒动画,甚至可以再降低 200 毫秒的加载感知。你并没有节省 400 毫秒的时间,但是用户直到真正等待内容时,才感觉到他们在等待内容。
测试性能
总结
通过将尽可能多的下载、渲染和等待时间转化为主动阶段
,并减少任何被动等待时间
,即使客观测量结果保持不变,用户也会感觉内容下载、渲染和响应更加迅速。既然我们已经知道应该加快速度的内容,让我们来看一些指标,并学习如何衡量这些事件。
参考资料
ps 记得可以给 MDN 这几篇未翻译的文章提交 issue。源于 MDN,反哺 MDN。