1. 概述
web性能说简单点就是网站打开速度快不快,页面中的动画够不够流畅,表单提交的速度是否够快,列表滚动页面切换是否卡顿。性能优化就是让网站变得快。
在MDN上对web性能的定义是网站或应用程序的客观度量和可感知的用户体验。比如减少页面加载事件(减少文件体积,减少HTTP请求,使用预加载),让网站尽快可用(懒加载或者分片加载),平滑的交互性(使用CSS替代JS动画,减少UI重绘),感知表现(加载动画,loading等给用户感觉快),性能测定(性能指标,性能测试,性能监控以便持续优化,毕竟性能优化是个持续的过程)。
页面性能关乎到用户的留存,网站的转换率,用户体验和网站的传播,甚至影响搜索排名遭到用户投诉,当然也会影响开发的效率。
为什么速度很重要
2. 性能指标
进行性能优化之前首先要知道要在哪些方面做性能优化。
首先需要了解性能指标,多快的速度才算快呢?可以使用专业的工具可量化的评估出网站或应用的性能表现。
立足于网站页面响应的生命周期,分析出造成较差性能表现的原因,最后进行技术改造,可行性分析等具体的优化措施,持续迭代优化就可以了。
事实上性能是相对的,他并不是绝对的概念。对于一个用户而言在不同的网络环境下访问页面的速度可能是不同的。即使相同的网站在懒加载的情况下也会显得快。
在讨论性能的时候精确地,可量化的指标是很重要的。但是仅仅因为一个度量标准是基于客观准备并且可以定量的度量的,并不一定意味这些度量是有用的。对于Web开发人员来说,如何恒量一个Web页面的性能一直都是一个难题。
最初,开发人员使用Time to To Byte。DomContentLoaded和Load这些恒量文档加载进度的指标,但他们不能直接反应用户视觉体验。
为了恒量用户视觉体验,Web标准中定义了一些性能指标。这些性能指标被各大浏览器标准化实现,例如First Paint和First Contentful Paint。
还有一些由Web孵化器社区组提出的性能指标,如Largest COntentful Paint, Time to Interactive, First Input Delay, First CPU Idle。
另外还有Google提出的First Meaningful Paint, Speed Index。
百度提出的First Screen Paint。
这些指标之间并不是毫无关联,而是在以用户为中心的目标中不断演进出来的,有的已经不再建议使用,有的被各种测试工具实现,有的则可以作为通用标准可用于生产环境测量的API。
3. RAIL性能模型
RAIL是Response,Animation,Idle和Load的首字母缩写,是一种由Google Chrome团队于2015年提出的性能模型,用于提升浏览器的用户体验和性能。
RAIL分别代表:
- Response:响应
- Animation:动画
- Idle:空闲
- Load:加载
RAIL模型的理念是以用户为中心,最终目标并不是让你的网站在任何特定设备上都能运行很快,而是使用户满意。
Response: 应该尽可能快速的响应用户的操作,应在在100ms以内响应用户输入。
Animation: 在展示动画的时候,每一帧应该以16ms进行渲染,这样可以保持动画效果的一致性,并且避免卡顿。
Idle: 当使用js主线程的时候,应该把任务划分到执行时间小于50ms的片段中去,这样可以释放线程以进行用户交互。50ms为单位是为了保证用户在发生操作的100ms内做出响应。
要使网站响应迅速,动画流畅,通常都需要较长的处理时间,但以用户为中心来看待性能问题,就会发现并非所有工作都需要在响应和加载阶段完成,完全可以利用浏览器的空闲时间处理可延迟的任务,只要让用户感受不到延迟即可。利用空闲时间处理延迟可减少预加载的数据大小,以保证网站或应用快速完成加载。
Load: 应该在小于1s的时间内加载完成你的网站,并可以进行用户交互。根据网络条件和硬件的不同,用户对性能延迟的理解也有所不同,在3G网络需要花费更多的时间,5s是一个更现实的目标。
基于用户体验的性能指标其中包括一下几个比较重要的性能指标。
1. FCP (First Contentful Paint)
首次内容绘制,浏览器首次绘制来自DOM的内容的时间,内容必须包括文本,图片,非白色的canvas或svg,也包括带有正在加载中的web字体文本。这是用户第一次看到的内容。
| FCP时间(秒) | 颜色编码 | FPC分数 |
|---|---|---|
| 0 - 2 | 绿色(快) | 75 - 100 |
| 2 - 4 | 橙色(中等) | 50 - 74 |
| 超过4 | 红色(慢) | 0 - 49 |
2. LCP (Largest Contentful Paint)
最大内容绘制,可视区域中最大的内容元素呈现到屏幕上的时间,用以估算页面的主要内容对用户的可见时间。img图片,video元素的封面,通过url加载到的北京,文本节点等,为了提供更好的用户体验,网站应该在2.5s以内或者更短的时间最大内容绘制。
| LCP时间(秒) | 颜色编码 |
|---|---|
| 0 - 2.5 | 绿色(快) |
| 2.5 - 4 | 橙色(中等) |
| 超过4 | 红色(慢) |
3. FID (First Input Delay)
首次输入延迟,从用户第一次与页面进行交互到浏览器实际能够响应该交互的时间,输入延迟是因为浏览器的主线程正忙于做其他事情,所以不能响应用户,发生这种情况的一个常见原因是浏览器正忙于解析和执行应用程序加载的大量计算的JavaScript。
| FID时间(毫秒) | 颜色编码 |
|---|---|
| 0 - 100 | 绿色(快) |
| 100 - 300 | 橙色(中等) |
| 超过300 | 红色(慢) |
4. TTI (Time to Interactive)
网页第一次完全达到可交互状态的时间点,浏览器已经可以持续的响应用户的输入,完全达到可交互的状态的时间是在最后一个长任务完成的时间,并且在随后的5s内网络和主线程是空闲的。从定义上来看,中文名称叫持续可交互时间或可流畅交互时间更合适。
| TTI时间(秒) | 颜色编码 |
|---|---|
| 0 - 3.8 | 绿色(快) |
| 3.9 - 7.3 | 橙色(中等) |
| 超过7.3 | 红色(慢) |
5. TBT (Total Block Time)
总阻塞时间,度量了FCP和TTI之间的总时间,在该时间范围内,主线程被阻塞足够长的时间以防止输入响应。只要存在长任务,该主线程就会被视为阻塞,该任务在主线程上运行超过50毫秒。
线程阻塞是因为浏览器无法中断正在进行的任务,因此如果用户确实在较长的任务中间与页面进行交互,则浏览器必须等待任务完成才能响应。
| TBT时间(毫秒) | 颜色编码 |
|---|---|
| 0 - 300 | 绿色(快) |
| 300 - 600 | 橙色(中等) |
| 超过600 | 红色(慢) |
6. CLS (Cumulative Layout Shift)
累计布局位移,CLS会测量在页面整个生命周期中发生的每个意外的布局移位的所有单独布局移位分数的总和,他是一种保证页面的视觉稳定性从而提升用户体验的指标方案。
用人话来说就是当点击页面中的某个元素的时候,突然布局变了,手指点到了其它位置。比如想点击页面的链接,突然出现了一个banner。这种情况可能是因为尺寸未知的图像或者视频。
| CLS时间(毫秒) | 颜色编码 |
|---|---|
| 0 - 0.1 | 绿色(快) |
| 0.1 - 0.25 | 橙色(中等) |
| 超过0.25 | 红色(慢) |
4.衡量前端性能指标
最常用的值
- navigationStart: 浏览器处理当前网页的启动时间
- fetchStart:浏览器发起HTTP读取文档的毫秒时间戳
- domainLookupStart: 域名查询开始的时间戳
- domainLookupEnd: 域名查询结束的时间戳
- connectStart: HTTP请求开始向服务器发送的时间戳
- connectEnd: 浏览器与服务器链接建立
- requestStart: 浏览器向服务器发出HTTP请求的时间戳
- responseStart: 浏览器从服务器收到第一个字节的时间戳
- responseEnd: 浏览器从服务器收到最后一个字节的时间戳
- domLoading: 浏览器开始解析网页DOM结构的时间
- domInteractive: 网页DOM树创建完成,开始加载内嵌资源时间
- domContentLoadEventStart: 网页domContentLoadd时间发生时的时间错
- domContentLoadedEventEnd: 网页所有需要执行的脚本执行完成的时间, domReady的时间
- loadEventStart: 当前网页load事件回调函数开始执行的时间戳
- loadEventEnd: 当前网页load事件回调函数执行结束的时间戳
| 性能数据名称 | 描述 | 计算方法 |
|---|---|---|
| DNS查询时间耗时 | DNS解析耗时 | domainLookupEnd - domainLookupStart |
| 请求响应耗时 | 网络请求耗时 | responseStart - requestStart |
| DOM解析耗时 | DOM解析耗时 | domInteractive - responseEnd |
| 资源加载耗时 | 资源加载耗时 | loadEventStart - domContentLoadedEventEend |
| DOM_READY耗时 | DOM阶段渲染耗时 | domContentLoadedEventEend - fetchStart |
| 首次渲染耗时 | 首次渲染时间/白屏时间 | responseEnd - fetchStart |
| 首次可交互耗时 | 首次可交互耗时 | domInteractive - fetchStart |
| 首包时间耗时 | 首包时间 | responseStart - domainLookupStart |
| 页面完全加载耗时 | 页面完全加载时间 | loadEventStart - fetchStart |
| TCP链接时间 | TCP链接耗时 | connectEnd - connectStart |
5. 性能测试
性能检测是作为性能优化过程中的一环,他的目的通常是给后续优化工作提供指导方向,参考基线以及千户对比的依据。性能检测并不是一次性执行结束后就完成的工作,他会在检测,记录和改进的迭代过程中不断重复。来协助网站的性能优化不断接近期望的效果。
1. Lighthouse(灯塔)
Lighthouse是谷歌开发并开源的web性能测试工具,用于改进网络应用的质量,可以将其作为一个Chrome扩展程序运行,或从命令行运行。只需要为其提供一个需要审查的地址,Lighthouse就会对页面进行一连串的测试,生成一个有关页面性能的报告。
在浏览器的调试工具中默认就存在lighthouse选项,只需要切换至lighthouse,在右侧的选项区选中需要的选项。点击生成报告。
可以看到淘宝的首屏时间是0.6s,可交互时间是1.5s,总阻塞时间是10ms。最大绘制时间是1s。通过这些指标就可以看到在哪方面存在性能瓶颈。
在下方会对渲染进行拍照截图,如果空白页面较多也能体现网站白屏时间过长。下面还会给一些优化建议。比如某些资源过大,加载时间过长等,当然这些建议不并一定都是对的,只是一些建议。
最后是测试环境信息,不能制作一种环境的测试,要多环境测试。
2. WebPageTest
在线web性能测试工具(https://www.webpagetest.org), 提供多地点测试。他只能测试已经发布了的网站。输入需要测试的网页地址,点击start test按钮就开始测试了,可以选择测试地理位置,测试的浏览器等。