为什么要有前端监控
- 用户体验直接决定用户留存,然而众多体验问题单靠用户反馈并不现实
- 移动互联网时代,用户要求越来越高,耐心越来越差,对页面响应慢,页面不可用的容忍度低
- 使用场景复杂,H5、APP、Web、浏览器版本、手机机型、用户网速等,都可能给业务带来影响
前端监控能带来什么
-
提升稳定性、更快的发现异常、定位异常、解决异常
- JS错误
- 接口异常
- 资源异常
- 白屏
-
提升用户体验、建立性能规范、长期关注优化
- 页面性能
- 接口性能
- 资源加载性能
- 卡顿监控
-
了解业务数据、指导产品升级
- PV&&UV
- 业务数据
- 行为数据
前端监控的流程
-
数据收集
- PV监控:页面切换后新的url、页面切换原因
- JS错误:错误对应类型、描述、行列号、堆栈,错误发生前的用户交互、错误的上下文等
- 性能监控:首屏加载各阶段耗时、各性能指标、SPA切换耗时、longtask等
- 请求监控:请求的路径、状态码、请求头和响应头、请求各阶段耗时等
- 白屏监控:白屏发生的页面、关联的异常、相关的上下文等
- 静态资源监控&&用户行为监控&&自定义监控
-
组装上报
-
清洗存储
- User-Agent解析:浏览器版本、系统版本、机型、设备品牌等
- IP解析:地区、省份、城市、运营商、地理位置等
- 分类型落表落库
- 处理JS错误:堆栈归一化、堆栈反解析
- Clickhouse存储
-
数据消费
- 总览分析
- 各功能模块消费视角&&多维分析
- 单点查询,针对用户全生命周期上报数据的重建展示
- 数据订阅&&实时报警
- issue管理&&归因分析
前端监控的关注点重要指标
-
可交互性
- 卡顿监控:通常由业务逻辑引起,关联用户行为可定位问题
- 请求性能:长期关注,异动分析,以此为基准衡量服务端性能
-
服务稳定性
- 请求成功率:主要关注页面级别和接口级别两个维度,需要具备衡量基准
-
加载速度
- 首屏性能:智能归因,根据timing各阶段耗时,明确得出可优化的阶段,指导优化
-
可用性
- 渲染错误/白屏:关联异常类数据,包括JS错误、静态资源错误、请求错误等
- 请求错误:长期关注错误率的变更,衡量产品质量;短期关注波动,关联线上问题
- JS错误:sourcemap反解&&issue管理
- 静态资源错误:拔测归因,着重展示能定位出问题的静态资源,降低噪因
-
业务数据
- PV/UV:用户分析、留存、转化
- 自定义事件/打点
总结
前端监控主要解决什么问题?
- 提升稳定性,更快的发现异常、定位异常、解决异常
- 提升用户体验,建立性能规范,长期关注优化
- 了解业务数据,指导产品升级
前端监控接入后应该关心哪些重要指标
- 可交互性、服务稳定性、加载速度、可用性、业务数据
传统的性能指标
传统的性能指标主要依赖Navigation Timing
以及Navigation Timing 2
,通过记录一个文档从发起请求到加载完毕的各阶段的性能耗时,以加载速度为衡量性能
Navigation Timing各阶段说明
初始化阶段
- navigationStart:用户完成卸载前一个文档的时间点
- redirectStart:页面重定向的开始时间,或者是0
- redirectEnd:页面重定向的结束时间,或者是0
请求阶段
- fetchStart:浏览器发起资源请求时,有缓存时,则返回读取缓存的开始时间
- domainLookupStart:查询DNS的开始时间
- domainLookupEnd:查询DNS的结束时间
- connectStart:浏览器开始与服务器连接时的时间
- secureConnectionStart:如果页面使用HTTPS,它的值是安全连接握手之前的时刻
- connectEnd:当浏览器端完成与服务器端建立连接的时刻
- responseStart:指客户端收到从服务器端(或缓存、本地资源)响应回的第一个字节的数据的时刻
- responseEnd:指客户端收到从服务器端(或缓存、本地资源)响应回的最后一个字节的数据的时刻
解析渲染阶段
- domLoading:浏览器即将开始解析第一批收到的HTML文档字节,Document.readyState变为loading
- domInteractive:当前网页DOM结构结束解析、开始加载内嵌资源的时间点,Document.readyState变为interactive
- domContentLoadedEventStart:当解析器发送DomContentLoaded事件,所有需要被执行的脚本已经被解析
- domComplete:当前文档解析完成,Document.readyState变为complete
- loadEventStart:作为每个网页加载的最后一步,浏览器会触发load事件,以便触发额外的应用逻辑,如果这个事件还未被发送,它的值将会是0
- loadEventEnd:load事件执行完成,如果这个事件还未被发送,或者尚未完成,它的值将会是0
各阶段耗时
实际运用中的常见耗时
如何采集
- Navigation Timing:
window.performance.timing
- Navigation Timing 2:
window.performance.getEntriesByType('navigation')
以用户为中心的性能指标
传统的性能指标专注于容易衡量的技术细节,但是它们很难反映出用户所真正关心的是什么
,如果你仅仅是把加载速度优化的更快,你很快会发现网站的用户体验依然很差,这就是创建以用户为中心的性能指标的原因,它们专注于用户视角下的浏览体验
指标描述
- FP:首次渲染的时间点,白屏
- FCP:首次有内容渲染的时间点
- FMP:首次绘制有意义内容的时间点:整体页面渲染完成
- SI:衡量页面可视区域加载速度,帮助检测页面的加载体验差异,实验环境
- TTI:内容是否可用,越小越好,代表用户可以更早操作页面
- FID:测量从用户第一次与页面交互,直到浏览器对交互做出响应
- LCP:最大的内容在可视区域内变得可见的时间点,例如一张图片可见,用来替代FMP,因为时间相近,同时计算FMP的性能消耗较大会因为一些细小的变化导致巨大波动,所以LCP替代FMP
- TBT:页面无法响应用户输入的时间有多久,一个页面的TBT,是从FCP到TTI之间所有长任务的阻塞时间的总和
- CLS:量化在页面加载时,内容的偏移度,越低越好
如何根据性能指标衡量站点满意度呢
推荐选择样本量的75个百分位来设置阈值
字节内部性能评分标准
如何优化传统性能指标
优化思路
- 网络优化:全局生效、一劳永逸的,ROI较高
- 缓存优化:除了常见的HTTP缓存,还有Memory缓存、Cache API缓存、Push缓存等
- 资源加载优化:从请求时机、文件体积、加载方式等方向优化
网络优化
- 开启HTTP2:关注兼容性问题,同时做好域名收敛
- 开启brotli压缩:相比gzip,它具有更高的压缩比和更快的压缩性能
- 善用HTTPS:通过有效的优化手段,如Session Resume、OCSP Stapling等,提升HTTPS性能
- 使用CDN部署静态资源:有效降低访问延迟,提高可用性
- DNS预解析:常用于CDN域名场景,减少DNS耗时
<link rel='dns-prefetch' href='//cdn.demo.com'>
- 提前建立网络连接:常用语Server API等域名,兼容性更好,
<link ref='preconnect' href='//demo.com'>
缓存优化
从上到下,进行
资源加载优化
一般从请求时机、文件体积、加载方式等方向入手
优化HTML文件
- 控制体积在30kb以内
- 优化DOM节点
- 压缩
- 谨慎使用内联
优化JS文件
- 请求时机:defer/async/动态加载
- 文件体积:常规的压缩/Tree Shaking/按需加载/精准控制polyfill
- 加载方式:减少网络请求/充分利用缓存
优化CSS文件、字体文件、图片文件
- 请求时机:关键的先请求,次要的后请求
- 文件体积:如何才能让资源的体积更小?
- 加载方式:减少请求数/善用缓存
如何优化以用户为中心的关键指标
优化FP&&FCP
进快渲染,加载快、解析快、渲染快,最终的值才会越优秀
- 消除阻塞渲染的资源
- 缩小CSS&&移除未使用的CSS
- 预连接到所需的来源
- 减少服务器响应时间
- 避免多个页面重定向
- 预加载关键请求
- 避免巨大的网络负载
- 使用高效的缓存策略服务静态资产
- 避免DOM过大
- 最小化关键请求深度
- 确保文本在页面字体加载期间保持可见
- 保持较低的请求数和较小的传输大小
优化FMP&&LCP
缩短页面关键路径的渲染时间
主要受四个因素的影响
- 缓慢的服务器响应速度:策略:网络优化
- JS和CSS渲染阻塞:策略:削减CSS、延迟加载非关键CSS、内联关键CSS、削减压缩JS文件、延迟加载未使用的JS文件、最大限度减少未使用的polyfill
- 资源加载时间:策略:优化和压缩图片、预加载重要资源、压缩文本文件、自适应服务(不同设备显示不同图片)
- 客户端渲染:最小化关键JS、使用服务端渲染、预渲染
优化FID
如何快速地响应用户交互
-
分割长任务:拆分成尽可能小的异步任务
-
优化页面,尽快做出交互准备
-
使用Web Worker
-
减少JS执行时间
优化CLS
尽量减少布局偏移
CLS较差的常见原因
- 无尺寸的图像:设置宽高、或者通过CSS宽比容器预留所需的空间
- 无尺寸的广告、嵌入和iframe:预留空间、避免在可视区域顶部放置广告、使用占位符或预先计算足够的空间
- 动态注入的内容:预留空间,比如使用占位符或骨架屏等
- 导致不可见文本闪烁/无样式文本闪烁的网络字体:预加载字体
- 在更新DOM之前等待网络响应的操作:倾向于使用transform动画,而不是触发偏移
优化TTI
尽快的渲染、尽早的请求、请求尽快结束、尽量避免长任务
- 参考如何优化FCP
- 预加载关键请求
- 最小化关键请求深度
- 减少JS执行时间
- 最小化主线程工作
- 保持较低的请求数和传输大小
JS错误监控
监听全局的error和unhandledrejection
Script error
出于安全原因,浏览器有意隐藏来自不同来源的脚本文件的错误,非同源的错误通过监听只能获取到一个script error的信息, 解决步骤:
- 为script添加crossorigin='anonymous'
- 添加跨域头:
access-control-allow-origin:*
部署思路
- 构建过程中将生成的sourcemap直接上传到监控平台
- 通过git blame找到出错行的作者,发送email自动分配
异常报警
针对JS错误监控,阈值类的报警意义不大,重点关注波动报警和新增报警
新增报警:根据release
请求监控
如何定义请求成功率
请求成功率=请求成功数/(请求成功数+请求失败数)。 不包含状态码为0的情况
请求成功率如何配置报警
- 设置较短的任务执行间隔:5-10min
- 关注波动,这往往意味着线上故障
- 推荐选择请求路径作为归因维度
请求耗时如何配置报警
- 推荐设置天级别的任务执行间隔
- 推荐选择请求耗时/75分位值作为度量指标
- 可以选择设置波动大小,也可以选择设置阈值大小
白屏
- 打分任务:分数小于设置阈值可能白屏
- 回测任务:检测是否有用户行为,如果一段时间都没有用户行为,进行下一步
- 截屏任务:截屏下来清晰度很低,但是可以看到是否真的白屏
- 白屏上报
本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。 在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!内容来源:火山引擎开发者服务