1. 性能优化概述
(1)性能优化的影响
为何会出现性能优化呢?实际上产品的性能优化是市场中类似产品的激烈竞争所导致的,这种竞争是不可避免的。归根结底比的就是“人无我有,人有我优,人有我廉,人廉我专”。最终竞品之间的比较都会趋向于性能的竞争,产品的性能可以直接影响其转化率、用户留存率等指标。
网站性能会对以下指标产生影响:
- 用户的留存:产品的留存情况一般是自用户登录注册之日起,经过一段时间后,仍然在使用该产品的用户数。用户留存数在用户注册数中的比例就是用户留存率。页面加载时间越长,应用就会被多数用户所抛弃。一般情况下,加载越快,用户的留存率越高。
- 网站的转化率: 网站转化率指的是用户进行某项目标行为的访问次数与总访问次数的比率,比如在电商网站上浏览某个商品的用户中有多少用户最终购买了这件商品,其所占的比例就是访客到消费者的转化率。页面的加载越快,提升了用户体验,用户的转化率也会随之提高。
- 体验与传播: 性能问题导致的用户体验差,造成的不仅使用户放弃该应用,还会导致用户拒绝想自己周边网络推荐该应用,更坏的情况就是用户会对应用的低性能进行差评。产品的口碑对于其发展的重要性是不言而喻的。
(2)性能的评估模型
对于软件产品的性能优化,根据RAIL性能模型(该模型以用户为原则),可以分为四部分:
- 响应(Response)
- 动画(Animation)
- 加载(Load)
- 空闲(Idle)
这四部分代表了应用生命周期的四个方面,它们会以不同的方式影响应用的性能。
1)响应
网站对于响应发面的要求是:在用户感知延迟之前接收到操作的反馈。 比如,用户进行页面的操作,必须在100ms之内收到反馈,如果超过100ms,用户就会感知到延迟,具体的用户感知的时间窗口如下表所示:
延迟时间 | 用户响应 |
0~100ms | 在该时间窗口内响应的用户操作,才会是流畅的体验 |
100~300ms | 用户能感知到轻微的延迟 |
300~1000ms | 所感知的延迟会被用户当做网站页面加载或更改视图过程的一部分 |
>1s | 用户的注意力将离开之前正在执行的任务 |
>10s | 用户感到失望,可能会放弃任务 |
其实,用户的操作背后可能存在着复杂的业务逻辑处理及网络请求与数据计算。所以,尽量将较大开销的工作放在后台异步执行,而即便后台的处理要数百毫秒才能完成,也应当给用户通过及时的阶段性反馈,比如在用户下载内容时,在页面提供下载进度。
2)动画
前端所涉及到的动画不仅有炫酷的特效,还包括滚动和触摸拖动等交互效果(说到这里,不得不提一句,Apple官网的动画做的是真的🐂🍺)。对于动画,其性能要求就是流畅。
研究表明,对于动画来说,无论动画帧率多高,人眼仅能分辨其中的30帧,但是高帧率会带来更好的流畅体验,因此动画尽力要达到60fps的帧率。根据60fps的帧率计算,一帧图像的生成预算为10ms(1000ms / 60 ≈ 16.66ms),出去浏览器绘制新帧的时间,留给执行代码的时间仅10ms左右,所以尽量要控制每帧动画的执行时间在10ms以内。
3)空闲
以用户的角度来看待性能问题时,可以利用空闲时间来处理可延迟的任务,只要让用户感知不到延迟即可,这样可以减少预加载的数据大小,以保证网站或应用快速完成加载。
4)加载
用户感知要求我们尽量在1s内完成页面的加载,如果没有完成,用户的注意力就会转移到其他事情上,并对当前处理的任务产生断感。当然,这里所指的加载并渲染出页面并非是要完成所有页面资源的加载,从用户感知体验的角度来说,只要关键渲染路径完成,用户就会认为全部加载已完成。对于非关键资源的加载,延迟到浏览器的空闲时间再进行,是比较常见的渐进式优化策略。
(3)性能优化的指标
对于性能的优化,我们首先要明确衡量性能的指标。常见的性能衡量指标有两种,分别是感官指标和Performance API。
1)感官指标
一般来说,业界认可的常用感官上的指标有:
- 首次绘制(FP)时间:对于应用页面,用户在视觉上首次出现不同于跳转之前的内容时间点,或者说是页面发生第一次绘制的时间点。
- 首次有内容绘制(FCP)时间:指浏览器完成渲染 DOM 中第一个内容的时间点,可能是文本、图像或者其他任何元素,此时用户应该在视觉上有直观的感受。
- 首次有意义绘制(FMP)时间:指页面关键元素渲染时间。这个概念并没有标准化定义,因为关键元素可以由开发者自行定义——究竟什么是“有意义”的内容,只有开发者或者产品经理自己了解。
- 首屏时间:对于所有网页应用,这是一个非常重要的指标。用大白话来说,就是进入页面之后,应用渲染完整个手机屏幕(未滚动之前)内容的时间。需要注意的是,业界对于这个指标其实同样并没有确切的定论,比如这个时间是否包含手机屏幕内图片的渲染完成时间。
- 用户可交互时间:顾名思义,也就是用户可以与应用进行交互的时间。一般来讲,我们认为是 domready 的时间,因为通常会在这时候绑定事件操作。如果页面中涉及交互的脚本没有下载完成,那么当然没有到达所谓的用户可交互时间。
2)Performance API
提到性能优化指标就不得不说 Performance API,这个 API 是 HTML5 新增的特性。过去要统计脚本的运行时间,可能会使用 Date.getTime() 去获取对应的时间;如果要获取白屏时间是在 head 末尾插入一段获取时间戳的代码,然后用这个时间戳减去开始接收数据的那个时间戳,得出的结果为白屏时间。这样的方法无疑是笨重的,而且获取的时间无法更精确(只能到ms级别),而且一些后台比较关注的时间根本无法获取。W3C 为了解决这个问题,在 HTML5 推出的时候,新增了这个 API 。
MDN 上对 Performance API 的解释:
Performance 接口可以获取到当前页面中与性能相关的信息。它是 High Resolution Time API 的一部分,同时也融合了 Performance Timeline API、Navigation Timing API、 User Timing API 和 Resource Timing API。该类型的对象可以通过调用只读属性 Window.performance 来获得。
可以在控制台的console面板中通过window.performance来获取网站的各项指标信息,结果如下图所示:
如图所以,performance包括了五个属性,其中timing是需要重点关注的,timing是一个map数据结构,其中key值是性能优化指标,value值是对应的时间戳。其中这些时间戳与页面整个加载过程中的关键节点是有着一一对应的关系,这里通过谷歌开发者网站的一张图来说明:
从图中可以看到很多指标都是成对出现,直接作差就可以求出对应页面加载过程中关键节点的时间,这里介绍几个比较常用的,比如:
const timingInfo = window.performance.timing; // TCP连接耗时 timingInfo.connectEnd - timingInfo.connectStart // DNS查询耗时 timingInfo.domainLookupEnd - timingInfo.domainLookupStart; // 获得首字节耗费时间,也叫TTFB timingInfo.responseStart - timingInfo.navigationStart // domReady时间(与前面提到的DomContentLoad事件对应) timingInfo.domContentLoadedEventStart - timingInfo.navigationStart // DOM资源下载 timingInfo.responseEnd - timingInfo.responseStart 复制代码
上述就是比较常用的指标,这些指标也可以在Chrome浏览器的network面板中的Timing下获取:
(4)性能优化的步骤
RAIL性能模型指出了用户对不同延迟时间的感知度,以用户为中心的原则,就是要让用户满意应用的性能体验。
对于不同类型的操作,需要的规定的时间窗口内完成,所进行的性能优化的步骤如下:
- 量化的评估出网站的性能表现;
- 立足于网站页面响应的生命周期,分析出造成较差性能表现的原因;
- 进行技术改造,可行性分析等具体的优化实施。
对于页面的生命周期以及页面性能测量会分别在第2和3部分进行详细介绍。
对于性能优化,具体的思路如下:
- 传输资源的优化:比如图像资源,不同的格式类型会有不同的使用场景,在使用过程中判断是否恰当;
- 加载过程的优化:比如加载延迟,是否有不需要在首屏展示的非关键信息,占用了页面的加载时间;
- JavaScript的优化:JavaScript代码是否进行了压缩,书写是否规范,有无考虑内存泄漏等;
- 关键渲染路径优化:比如是否存在不必要的回流与重绘等;
- 本地存储和浏览器缓存。
2. 前端页面的性能检测
(1)常见的性能检测工具
常见的性能检测工具有很多,比如Chrome开发者工具中有与性能检测相关的工具面板,页面加载性能分析工具PageSpeed Insights,专业的性能检测工具WEBPAGETEST等。
1)Chrome 任务管理器
在Chrome浏览器中,可以使用任务管理器查看当前所有进程关于GPU、网络、和内存的使用情况,这些进程包括当前打开的标签页、安装的各种插件以及GPU、网络、渲染等浏览器的默认进程。通过监控这些数据,可以在有异于其他进程的大幅度开销出现时,去定位存在内存泄漏或者网络资源加载异常的问题进程。Chrome任务管理器如图所示:
2)Network 面板
Network面板是Chrome浏览器开发者工具中经常用到的面板,通过它可以查看网站资源的请求情况,包括加载时间、尺寸大小、优先级设置、HTTP缓存触发情况等信息,从而发现网站资源请求中存在的问题。Network面板如图所示:
3)Coverage 面板
Coverage面板可以用来监控并统计出网站应用运行过程中代码执行的覆盖率情况。该面板统计的对象时JavaScript脚本文件与CSS样式表文件。统计结果主要包括:每个文件的字节大小、执行过程中已覆盖的代码字节数,以及可视化的覆盖率条形图。代码覆盖率低就意味着该代码文件存在着较多没有用到的代码,开发者可以根据这个结果对代码进行拆分,在需要的时候在进行加载。Coverage面板如图所示:
4)Memory 面板
Memory面板可以快速生成当前文件的堆内存快照,或者查看内存随时间的变化情况,据此可以查看并发现可能出现的内存泄漏等情况。Memory面板如图所示:
5)PageSpeed Insights
这是Google官方推出的用于性能检测网页加载性能的自动化工具,在该工具中,可以直接输入页面的URL来分析页面的性能,需要注意的是该结果是根据Lighthouse分析的实验数据得出的。官网链接:PageSpeed Insights。以语雀的文章为例进行测试:
6)WEBPAGETEST
WEBPAGETEST是一个专业的Web页面性能分析工具,它可以对检测分析的环境配置进行自定义化,内容包括测试节点的物理位置、设备型号、浏览器版本、网络条件和检测次数等。除此之外,它还提供了网站应用与竞品之间的性能比较,以及查看网络路由情况等多种情况下的测试工具。官网链接:WEBPAGETEST。 以语雀主页为例进行测试:
(2)Performance
Performance面板主要是对网站应用的运行时性能表现进行检测与分析,其可以检测的内容包括:页面的每秒帧数(FPS)、CPU的使用情况、各种请求的时间花费、网络任务的执行情况。
Performance面板可以在Chrome开发中工具中打开,建议在无痕模式下使用该工具,因为该模式下网页不会受到缓存或其他插件程序等因素的影响:
可以看到,上图Performance面板中间提示了如何开始使用这个面板,点击左上角最左侧的黑色圆就可以开始一个新的监测记录,点击刷新按钮可以记录整个刷新过程中的监测记录,还可以点击右侧按钮来删除检测记录。
点击刷新按钮,网站首页的性能结果如下,其包含的信息可以分为四大类:控制面板、概览面板、线程面板、统计面板: