挑战月薪30K | 前端性能优化的12 条建议(干货收藏)

做者:九思

你好,我是九思,来自腾讯前端技术部,擅长前端监控、工程化相关技术。此篇文章将围绕前端性能优化中监控问题展开讨论。css

首先咱们要知道,页面打开快不快,不是在电脑或手机上的打开速度说了算,也不是测试同窗测试的结果说了算,而是真实用户使用的时候说了算。前端

那么如何去监控用户真实使用时的页面性能呢?本文将作细致介绍(建议收藏)bootstrap

前端监控须要注意什么?


首屏

页面上线后,咱们最关心用户打开页面的速度,一般就是首屏。跨域

静态资源

页面加载离不开静态资源的加载,包括 js、css、img、video、font 等,在现在盛行 SPA 的场景尤其重要,好比活动页面会有不少图片,咱们一般会开发一些模板,由产品/运营同窗来配置,而图片多大合适是比较难肯定的,网速愈来愈快,你们对清晰度要求也愈来愈高,此时就能够经过监测这些图片的加载速度来酌情优化。浏览器

API 请求

数据是页面中至关重要的元素,能够说没有数据,你的页面几乎没有使用价值(纯静态除外)。固然这里咱们只能粗暴的监控整个请求的总时间,纯前端没法监控各个阶段时间,但这对于线上应用也很重要。性能优化

其余测速

实际上线后,不一样的应用可能会有不一样的测速诉求,好比:视频从加载到播放的时间,此时能够自定义一些测速点,利用以前讲述的打点方式来上报。网络

如何监控静态资源?


这块其实仍是比较简单的,只须要利用 PerformanceResourceTiming 便可,而且它的兼容性极高,能够覆盖到几乎全部场景。框架

图片

实际监控时,能够分两种场景,若是支持 performanceObserver 能够实时监听,不然使用定时器方式,此外须要将此代码放到页面最顶层,不然没法监控到这段代码以前的资源加载。dom

const typeList = \['script', 'link', 'img'\]; //   
 const staticTime = {};  
 const dealTime = (entries) => {  
 for (let i = 0, l = entries.length; i < l; i++) {  
 const entry = entries\[i\];  
 if (typeList.indexOf(entry.initiatorType) !== -1) {  
 staticTime\[entry.name\] = entry.connectEnd - entry.connectStart;  
 }  
 }  
 }  
 if (typeof window.PerformanceObserver === 'function') {   
 const observer = new window.PerformanceObserver((list) => {  
 dealTime(list.getEntries());  
 });  
 observer.observe({ entryTypes: \['resource'\] });  
 } else {  
 setInterval(() => {  
 const allEntries = performance.getEntriesByType('resource');  
 const entries = allEntries.slice(allEntries.length);  
 dealTime(entries);  
 }, 5000);  
 }

entry 部分数值前端性能

connectEnd: 32.63499999593478

connectStart: 32.63499999593478

decodedBodySize: 160302

domainLookupEnd: 32.63499999593478

domainLookupStart: 32.63499999593478

duration: 37.54000000481028

encodedBodySize: 23876

entryType: "resource"

fetchStart: 32.63499999593478

initiatorType: "link"

name: "https://stackpath.bootstrapcdn.com

nextHopProtocol: "h2"

redirectEnd: 0

redirectStart: 0

requestStart: 44.60999999719206

responseEnd: 70.17500000074506

responseStart: 65.40999999560881

secu reConnectionStart: 32.63499999593478

serverTiming:[]

startTime: 32.63499999593478

transferSize: 23971

workerStart: 0

图片

API 监控


关于 API 的监控,能够采用重写 XHR 或者 fetch,这样能够适用任何的框架、请求库。时间计算则是经过打点的方式,若是只是固定项目监控,也能够直接采用打点的方式。若是采用重写的方式,不只能够监控请求的时长,还能够监控请求的成功失败率。

打点最简单的方式:

const startTime = Date.now();  
fn() // 假设这里是同步执行  
const timeCycle = Date.now() - startTime; // fn的执行耗时

除了以上这几点,前端监控的实操中咱们还应该考虑到上报、限流以及如何处理这些性能数据。

点击连接查看详情:https://ke.sifou.com/course/1...
图片

上报


发送请求

发送请求咱们很容易想到适用 fetch / XHR,固然也可使用自动发起请求的 HTML 标签,好比 script、link、img。上报数据虽然能够拿来分析页面的真实运行数据,但有一点要注意的是:不能影响当前页面的运行或最小程度的影响。

是否能够直接用 fetch/XHR 呢?答案是否认的,由于上报的域名和页面的域名基本是不一样的,因此这里须要能够前端跨域的方式。

说到跨域,浏览器的 src 属性标签基本均可以,到底用哪一个呢?原则上要适用对页面影响最小的那个,诸如 Script、link 这些标签以前有讲述,他们都会对页面的运行形成影响。

img 变成了较为合适的方式,构造图片打点不只不用插入DOM,只要在 JSnewImage 对象就能发起请求,并且尚未阻塞问题,在没有js的浏览器环境中也能经过 img 标签正常打点,这是其余类型的资源请求所作不到的。

在全部图片中1px x 1px 大小,gif 体积最小,相较 BMP/PNG,能够节约41%/35%的网络资源,因此适用 gif 相对是最佳选择。

限流

页面的性能数据,每次访问都会有,若是你的项目 pv 有必定量级,那么处理起来就会至关耗费资源,并且这些数据咱们最终是求平均值或者分位值,因此不必全量上报。那么咱们能够在上报前作一些限流处理。

更多内容


除了以上这几点,前端监控的实操中咱们还应该考虑到如何处理这些性能数据,主要有取中位数、平均值、分位数等作法,因为篇幅有限此处不作详细介绍。

最后,若是这篇文章给你带来些许有价值的理解,欢迎点赞、分享,更多内容可翻阅个人付费专栏《前端性能优化12问》。

点击连接查看详情:https://ke.sifou.com/course/1...
图片

相关文章
相关标签/搜索