共计 2826 个字符,预计需要花费 8 分钟才能阅读完成。
你好,我是九思,来自腾讯前端技术部,善于前端监控、工程化相干技术。此篇文章将围绕前端性能优化中 监控 问题展开讨论。
首先咱们要晓得,页面关上快不快,不是在电脑或手机上的关上速度说了算,也不是测试同学测试的后果说了算,而是实在用户应用的时候说了算。
那么如何去监控用户实在应用时的页面性能呢?本文将做粗疏介绍(倡议珍藏)
前端监控须要留神什么?
首屏
页面上线后,咱们最关怀用户关上页面的速度,通常就是首屏。
动态资源
页面加载离不开动态资源的加载,包含 js、css、img、video、font 等,在现在流行 SPA 的场景尤为重要,比方流动页面会有很多图片,咱们通常会开发一些模板,由产品 / 经营同学来配置,而图片多大适合是比拟难确定的,网速越来越快,大家对清晰度要求也越来越高,此时就能够通过监测这些图片的加载速度来酌情优化。
API 申请
数据是页面中相当重要的元素,能够说没有数据,你的页面简直没有应用价值(纯动态除外)。当然这里咱们只能粗犷的监控整个申请的总工夫,纯前端无奈监控各个阶段工夫,但这对于线上利用也很重要。
其余测速
实际上线后,不同的利用可能会有不同的测速诉求,比方:视频从加载到播放的工夫,此时能够自定义一些测速点,利用之前讲述的打点形式来上报。
如何监控动态资源?
这块其实还是比较简单的,只须要利用 PerformanceResourceTiming 即可,并且它的兼容性极高,能够笼罩到简直所有场景。
理论监控时,能够分两种场景,如果反对 performanceObserver 能够实时监听,否则应用定时器形式,此外须要将此代码放到页面最顶层,否则无奈监控到这段代码之前的资源加载。
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 的执行耗时
除了以上这几点,前端监控的实操中咱们还应该思考到 上报、限流 以及如何 解决 这些性能数据。
上报
发送申请
发送申请咱们很容易想到实用 fetch / XHR,当然也能够应用主动发动申请的 HTML 标签,比方 script、link、img。上报数据尽管能够拿来剖析页面的实在运行数据,但有一点要留神的是:不能影响以后页面的运行或最小水平的影响。
是否能够间接用 fetch/XHR 呢?答案是否定的,因为上报的域名和页面的域名根本是不同的,所以这里须要能够前端跨域的形式。
说到跨域,浏览器的 src 属性标签根本都能够,到底用哪个呢?原则上要实用对页面影响最小的那个,诸如 Script、link 这些标签之前有讲述,他们都会对页面的运行造成影响。
而 img 变成了较为适合的形式,结构图片打点不仅不必插入DOM,只有在 JS 中 new 出 Image 对象就能发动申请,而且还没有阻塞问题,在没有 js 的浏览器环境中也能通过 img 标签失常打点,这是其余类型的资源申请所做不到的。
在所有图片中 1px x 1px 大小,gif 体积最小,相较 BMP/PNG,能够节约41%/35% 的网络资源,所以实用 gif 绝对是最佳抉择。
限流
页面的性能数据,每次拜访都会有,如果你的我的项目 pv 有一定量级,那么解决起来就会相当消耗资源,而且这些数据咱们最终是求平均值或者分位值,所以没必要全量上报。那么咱们能够在上报前做一些限流解决。
更多内容
除了以上这几点,前端监控的实操中咱们还应该思考到如何解决这些性能数据,次要有取 中位数、平均值、分位数 等做法,因为篇幅无限此处不做具体介绍。
最初,如果这篇文章给你带来些许有价值的了解,欢送点赞、分享、在看,更多内容可翻阅我的付费专栏《前端性能优化 12 问》。
作者:九思