性能优化,首先要带着目的,再去发现问题、解决问题;这个过程中,也需要一些指标作为参考,及监测这些指标的工具:
前端性能指标
- First Paint(FP) 第一次渲染,开始有变化了,可能没有内容(看不到,无感知)
- First Contentful Paint(FCP) 第一次有内容的渲染,有感知了
- First Meaningful Paint(FMP) -- 目前已弃用(没办法用技术定义有意义的内容),改用LCP; 第一次有意义的内容渲染,知道页面是什么东西了
- DomContentLoaded(DCL) 页面的DOM加载完成
- Largest Contentfull Paint(LCP) 页面最大/最多的内容渲染完成
- Load(L)
监测性能指标工具
- Chrome devTools
- Performance可查看上述性能指标,并有网页快照
- 先输入网址,点击监测开始,再打开网址,加载完后,点击监测结束
- Network 可以查看各个资源的加载时间
- Performance可查看上述性能指标,并有网页快照
- Lighthouse
- 可以输出测试报告和优化建议
- 先安装 npm i lighthouse -g
- 使用命令:lighthouse https://www.xxxx.com/ --view --preset=desktop(默认H5方式访问,加上这个参数以PC方式访问)
识别问题,找到问题(可使用二分法排除)
- 加载慢?
- 渲染慢?
- 优化服务端接口(如Ajax获取数据慢)
- 优化前端组件内部的逻辑
- 服务端渲染SSR
持续跟进
- 性能优化是一个循序渐进的过程,不像bug一次性解决
- 持续跟进统计结果,再逐步分析性能瓶颈,持续优化
- 可使用第三方统计服务,如阿里云ARMS、百度统计
性能优化的目的:
- 首屏时间
- 收集可交互时间(比如打开就立马就能输入)
- 收集有意义内容渲染时间
总结一些优化方式:
- 页面性能检测:https://developers.google.com/speed/pagespeed/insights/
-
只请求当前需要的资源
异步加载, 懒加载, polyfill的优化 https://polyfill.io/v3/url-builder/
-
缩减资源体积
打包压缩 webpack4
gzip
图⽚格式优化, 压缩, 根据屏幕分辨率展示不同分辨率的图⽚, webp
尽量控制cookie⼤⼩ request header, cookie
-
时序优化
js中promise.all
ssr seo
prefetch、prerender、preload
<link rel=“dns-prefetch” href=“xxxxxx” /> <link rel=“preconnect” href=“xxxxxxx” /> <link rel=“preload” as=“image” href=“xxxxxxxxx” />
-
合理利⽤缓存
cdn cdn预热 cdn刷新 douyin.com,cdn-douyin.com
http缓存, localStorage, sessionStorage
-
如果⼀段js执⾏时间⾮常⻓? 利用装饰器计算函数执⾏时间
export function measure(target: any, name: string, descriptor: any){ const oldValue = descriptor.value; descriptor.value = async function(){ console.time(name); const ret = await oldValue.apply(this, arguments); console.timeEnd(name); return ret; } return descriptor; }
-
阿⾥云oss⽀持通过链接后拼参数实现图⽚格式转换, 可尝试, 利用阿里云把任意图⽚转为webp格式? 及注意事项?, 判断浏览器是否⽀持webp & webp格式转换
// 检测是否支持webp格式图片 function checkWebp(){ try { return ( document.createElement('canvas') .toDataURL('image/webp') .indexOf('data:image/webp') === 0 ); } catch(e) { return false; } } const supportWebp = checkWebp(); export function getWebpImageUrl(url){ if(!url){ throw Error('url 不能为空'); } if(url.startsWidth('data:')){ return url; } if(!supportWebp){ return url; } return url + '?x-oss-processxxxxx'; }
-
如果有巨量的图⽚需要展示在⻚⾯, 除了懒加载这种⽅式, 还可以限制其同⼀时间加载的数量? 使⽤promise实现并发控制
promise.limit