1. 性能工程几个定律
帕累托法则
常说的"二八法则",很多时候,大约20%的因素操控80%的局面。
应用场景 | 内容 | 意义 |
---|---|---|
应用程序的使用 | 80%的用户使用集中在大约20%的功能 | 对常用的模块进行充分优化 |
程序代码开发时间的分配 | 80%的开发时间花费在最精髓的20%的代码 | 合理规划好开发时间 |
程序代码的维护 | 80%的代码演进和改动发生在20%的代码上 | 对最常改动的少部分代码尽量熟悉 |
程序代码的修正和纠错 | 80%的错误发生在20%的代码上 | 代码修复要重点修复最容易产生bug的代码 |
客户流量的时间分布 | 80%的流量将在总时间段的特定20%内发生 | 设计和部署,充分考虑访问峰值和空闲时段 |
程序代码的优化 | 80%的时间是运行大约20%的代码 | 发现少数重点代码并做优化 |
理解80%和20%是相对的概念,实际比例不一定跟这个吻合。
阿姆达尔定律
处理器并行运算之后效率提升的能力,加速比用并行前的速度和并行后的速度之比来表示,表示效率提升情况。优先加速占用时间最多的模块,因为这样可以最大限度地提升加速比。
利特尔法则
在一个稳定的系统中,长期的平均客户人数(N)等于客户抵达速度(X)乘以客户在这个系统中平均处理时间(W),也就是说 N=XW。
- 设计性能测试的环境:用户请求流量速度和每个请求的延时都要考虑。
- 验证测试结果的正确性:在高低并发不同情况下响应速度可能不同。
2. 优化前需要了解的几件事
了解你的用户
通过埋点上报,数据收集,得到关于用户特征的统计信息
操作系统分布
可根据用户操作系统的分布。 举个例子:80%的用户使用windows访问系统,15%的用户使用MacOS,剩余为其他操作系统。
地区分布
国家地区分布,了解国内外用户的访问比例。可以是否做国际化、CDN部署海外站点等的决策依据。 举个例子:90%的用户都来自中国,10%的用户来自海外,其中海外的用户主要集中在欧洲。
浏览器分布和版本分布
开发时兼容浏览器版本和测试业务系统提供参考依据。举个例子:80%的用户都是使用Chrome浏览器,15%的用户使用Safari,需要重点针对Chrome和Safari浏览器。
基于以上所有信息,我们可以建立用户画像 :
90%的用户都是在中国,海外主要的用户是在美国,主要是在Mac或者Windows的操作系统进行工作。使用的浏览器主要是Chrome、其次是Safari。
了解你的整体架构
前后端整体架构
前端页面架构
机房部署
前后端服务尽可能部署在同一机房,提升响应的速度。
3.明确性能优化目的,建立北极星指标
为什么要做性能优化,收益如何度量
性能要比竞争对手领先20%,才有可能被用户感知。
对于C端而言,可以从以下方面进行衡量:
- 用户体验:提高网站或应用程序的加载速度和响应性,减少等待时间,提升用户体验和满意度。
- 用户留存率:更好的用户体验通常会导致用户更倾向于留在网站或应用程序,减少用户的跳出率。
- 转化率:快速加载的网页可以提高转化率,例如更多的订阅、购买或注册行为。
- SEO优化:搜索引擎对快速加载的网页进行青睐,可能提升网站在搜索结果中的排名,吸引更多流量。
- 节约成本:性能优化减少了服务器资源的使用,可能降低了运维成本和服务器费用。
对于B端,性能优化对于复购率的贡献率比较难以衡量,很少会因为性能而做出购买的决策,功能才是用户决策购买的最重要的因素。那有什么办法,可以相对量化对于用户产生的价值?个人的看法可以从两个方面进行分析(欢迎大家多多讨论):
- 降本。CDN成本 = 节省带宽(包体积减少大小)* 9000元/Gbps(CDN收费)
- 提效。节约成本 = 提升用户的时间效率 * PV * 人力平均成本
同时也为后面实现复杂功能,压榨性能空间,当性能特别好的时候,也可以作为产品的一个特性进行宣传。
以什么性能指标为北极星指标
分类 | 性能指标 | 含义解释 |
---|---|---|
页面加载速度 | FCP (First Contentful Paint) | 首次内容渲染,表示浏览器首次渲染页面的时间点。 |
LCP (Largest Contentful Paint) | 最大内容绘制,表示页面上最大的可见内容绘制完成的时间点。 | |
TTI (Time To Interactive) | 可交互时间,表示页面变得完全可交互的时间点。 | |
用户交互 | FID (First Input Delay) | 首次输入延迟,用户首次与页面交互到浏览器实际响应交互的时间。 |
CLS (Cumulative Layout Shift) | 累计布局位移,衡量页面内容在加载过程中的稳定性。 | |
LongTask | 长任务 | |
FPS (Frames Per Second) | 帧率,表示浏览器每秒渲染的帧数,用于衡量页面渲染的流畅程度。 |
结合你的业务实际去进行判断。
要优化哪些页面
如果有很多页面,需要确定优化的优先级,可以参考以下标准,结合自己的业务实际进行调整(如果有用户反馈某个页面很慢,影响到日常使用,那也是需要重点关注的页面)。
PV | 使用频次 | |
---|---|---|
L1 级页面 | PV 总量前 5% 的页面 | 使用频次前 5% 的页面 |
L2 级页面 | PV 总量前 5%~70% 的页面 | 使用频次前 5%~70% 的页面 |
L3 级页面 | PV 总量前 70%~100% 的页面 | 使用频次前 70%~100% 的页面 |
根据PV排名和使用频次进行优先级排行,根据资源投入决定优化先后顺序。除此之外,对于一些慢得比较离谱的页面(例如10s以上)也是一个优化重点,这种情况大概率是比较容易优化取得很大的优化效果。
系统性分析页面性能
准备工作
-
确定设备型号和网络环境
- 设备型号MacBook Pro(2018版,CPU: 2.2 GHz Intel Core i7, 内存: 16G)/'
-
确定使用的测试环境:不同环境的接口返回速度和响应性能具有很大的差异
-
测试冷启动情况下性能,需要勾选disable cache,防止缓存的干扰,有无缓存的情况下性能分析会有很大的不同。
-
最好在无痕窗口进行试验,排除扩展插件对于页面的干扰,有些扩展插件对于页面性能有比较大的影响。
使用 Performance 分析页面加载全流程
- 点击录制
一般分析页面,点击reload按钮(图中1),直接等待分析结果出来就可以了。
但有些情况,例如
- 刷新页面之后,需要手动触发才会出现我们想要分析的页面
- 点击reload按钮后,在还没出现页面主体内容的时候,直接录制结束,导致performance没有分析整个过程
这时候我们需要需要点击record按钮(图中2),进行录制。
以某个网页为例,点击record进行记录。然后再调整起始时间轴来进行分析。
起点和终点的判断。
- 一般起点为请求HTML模板的起点
- 终点为主体内容展示:可以通过screenshot进行辅助判断。
2. 划分阶段
划分阶段有助于我们对整个页面加载的各个阶段有个整体的了解,对于后续优化。按照示例,大致可分为两个阶段
-
主应用加载
- 模板下载
- 资源下载
- JS解析和执行
-
子应用加载和执行
- 模板下载
- 初始静态资源下载和执行
- 全局公共接口请求
- 页面渲染
关于图中的那些颜色块的含义:
- 左侧线条代表从事件组"Connection Start"(包含在内)之前的所有事件,是在"Request Sent"之前的所有事件,但不包括"Request Sent"。
- 条形图的浅色部分代表"Request Sent"和"Waiting (TTFB)"。
- 条形图的深色部分代表"Content Download"。
- 右侧线条表示主线程等待的时间。
network上先后顺序只是表现,要结合实际的业务代码去判断哪些请求是主路径上的。
可能出现的情况是,图中可能在某个时间段内只有个请求,但实际上这个请求并不会阻塞页面加载和渲染,很容易就被误导是这个原因导致。结合代码和main下面的执行任务综合起来看,才能够区分出这种情况。
注意看看是否有长任务,长任务执行的时候,会阻塞主进程的调用。也可以通过Call Tree等方式确定代码调用的位置来辅助定位。
包大小分析
有个原则:捡西瓜丢芝麻 ,重点优化体积比较大的包。可以使用www.npmjs.com/package/web... 来进行辅助分析
提供一些思路:
- 移除旧的历史依赖
- 查看初始化加载的问题
- external基础库
- 使用轻量的包进行替换
包体积的优化也能够减少js的执行时长
请求分析
接口可能存在不合理调用或者时序问题,分析业务接口的调用的先后顺序。
-
接口时序
- 串行改并行
- 只调用初始渲染必须的接口
- 历史遗留的多余接口可去除
-
接口数量优化
- 可合并,接口聚合
- 老旧接口可下掉
- 接口预请求
-
接口耗时
- 服务端进行优化
-
接口并发请求:可并发的请求尽量并发
一些小技巧
- performance导出Profile,可以多次回放
- 注意线上和线下的接口耗时数据区别,可能会有坑。
- 数据波动的解释:PV、UV的相关性指标辅助进行判断数据波动的原因