参考
把前端性能监控做到极致 PPT
大前端时代前端监控的最佳实践 (gmtc视频) PPT文章
如何计算首屏加载时间?

GMTC2018 《大前端时代前端监控的最佳实践》 彭伟春myslide.cn.pdf

1 发展阶段

1.1 手动打点

image.png
image.png
比如以前一个项目就是手动打点,时间截取根据项目特性定,比如页面展示依赖接口,则一般在js把数据插入页面才算页面结束时间,但是这可能就不是首屏时间,这个首屏时间其实没有统一的规定。

  1. // 页头
  2. <head>
  3. <meta charset="UTF-8">
  4. <script type="text/javascript">
  5. sessionStorage.setItem('startHtmlTime',new Date().getTime());
  6. </script>
  7. <title>xxxxxx</title>
  8. <link rel="stylesheet" href="css/swiper.min.css">
  9. .......
  10. </head>
  11. // 页尾
  12. <script src="js/lib/swiper.min.js"></script>
  13. <script type="text/javascript" src="js/lib/sea.js"></script>
  14. <script>
  15. seajs.config({
  16. base: "./js/",
  17. alias: {
  18. "zepto": "lib/zepto.js"
  19. }
  20. });
  21. seajs.use("index.js");
  22. sessionStorage.setItem('endHtmlTime',new Date().getTime());
  23. </script>
  24. </body>
  25. </html>
  26. // 页面加载完成后数据上报
  27. exports.getSessionTime = function(async){
  28. var userGid =sessionStorage.getItem(config.USERGID_KEY);
  29. var pageEle=document.querySelector("[id^=xxx_acv]");
  30. var pageId=(pageEle&&pageEle.id)||"";
  31. var zuid=getStoreUuid();
  32. var timeParams = {
  33. "mid":"ACQ04",
  34. "appid":appflag,
  35. "ugid": userGid || "",
  36. "ctime": new Date().getTime(),
  37. "zuid": zuid,
  38. "eleId":pageId,
  39. "pageId":pageId,
  40. "path":window.location.pathname,
  41. "startHtmlTime" : sessionStorage.getItem("startHtmlTime"),
  42. "endHtmlTime" : sessionStorage.getItem("endHtmlTime"),
  43. "jsRealyTime" : sessionStorage.getItem("jsRealyTime"),
  44. "loadingHideTime" : sessionStorage.getItem("loadingHideTime"),
  45. "htmlDuaration":sessionStorage.getItem("endHtmlTime")-sessionStorage.getItem("startHtmlTime"),//html加载时间
  46. "applyDuaration":sessionStorage.getItem("jsRealyTime")-sessionStorage.getItem("endHtmlTime"),//js加载时间
  47. "jsDuaration":sessionStorage.getItem("loadingHideTime")-sessionStorage.getItem("jsRealyTime")//接口加载时间
  48. };
  49. $.ajax({
  50. url:config.ACQUISIURL+"zuid="+encodeURI(zuid)+"&appid="+appflag,
  51. type:'post',
  52. data:JSON.stringify(timeParams),
  53. async:async,
  54. dataType:'json',
  55. contentType:'application/json;charset=UTF-8;',
  56. success:function(data){
  57. }
  58. })
  59. };

1.2 标准API

Performance API
image.png
比如:(注意:performance.timing api将要被废弃)

  1. if (!!window.performance) {
  2. var _PerforMance = window.performance;
  3. var _Timing = _PerforMance.timing;
  4. if (_Timing) {
  5. var loadAcData = {
  6. mid: _this.store.storeTiming,
  7. startTime: _this.util.getTimeStr(),
  8. path: _this.util.getCookie(_this.store.storePage),
  9. connectEnd : _Timing.connectEnd, //返回浏览器与服务器之间的连接建立时的Unix毫秒时间戳
  10. connectStart : _Timing.connectStart, //返回HTTP请求开始向服务器发送时的Unix毫秒时间戳
  11. domComplete:_Timing.domComplete,//返回当前文档解析完成时的Unix毫秒时间戳。
  12. domContentLoadedEventEnd : _Timing.domContentLoadedEventEnd,//返回当所有需要立即执行的脚本已经被执行(不论执行顺序)时的Unix毫秒时间戳。
  13. domContentLoadedEventStart : _Timing.domContentLoadedEventStart,//返回当解析器发送DOMContentLoaded 事件,即所有需要被执行的脚本已经被解析时的Unix毫秒时间戳。
  14. domInteractive : _Timing.domInteractive,//返回当前网页DOM结构结束解析、开始加载内嵌资源时的Unix毫秒时间戳。
  15. domLoading : _Timing.domLoading,//返回当前网页DOM结构开始解析的Unix毫秒时间戳。
  16. domainLookupEnd: _Timing.domainLookupEnd, //表征了域名查询结束的UNIX时间戳。
  17. domainLookupStart: _Timing.domainLookupStart, //表征了域名查询开始的UNIX时间戳。
  18. fetchStart: _Timing.fetchStart, //表征了浏览器准备好使用HTTP请求来获取(fetch)文档的UNIX时间戳。这个时间点会在检查任何应用缓存之前。
  19. loadEventEnd: _Timing.loadEventEnd,//返回当load事件结束,即加载事件完成时的Unix毫秒时间戳。
  20. loadEventStart: _Timing.loadEventStart,//load事件被发送时的Unix毫秒时间戳。
  21. navigationStart: _Timing.navigationStart,//准备加载新页面的起始时间
  22. redirectEnd: _Timing.redirectEnd, //表征了最后一个HTTP重定向完成时(也就是说是HTTP响应的最后一个比特直接被收到的时间)的UNIX时间戳
  23. redirectStart: _Timing.redirectStart, //表征了第一个HTTP重定向开始时的UNIX时间戳
  24. requestStart: _Timing.requestStart,//返回浏览器向服务器发出HTTP请求时(或开始读取本地缓存时)的Unix毫秒时间戳。
  25. responseEnd: _Timing.responseEnd,//返回浏览器从服务器收到(或从本地缓存读取,或从本地资源读取)最后一个字节时的Unix毫秒时间戳。
  26. responseStart: _Timing.responseStart,//返回浏览器从服务器收到(或从本地缓存读取)第一个字节时的Unix毫秒时间戳
  27. secureConnectionStart: _Timing.secureConnectionStart, //浏览器与服务器开始安全链接的握手时的Unix毫秒时间戳
  28. unloadEventEnd: _Timing.unloadEventEnd, //表征了unload事件处理完成时的UNIX时间戳
  29. unloadEventStart: _Timing.unloadEventStart //表征了unload事件抛出时的UNIX时间戳
  30. };
  31. loadAcData.DNS = _Timing.domainLookupEnd - _Timing.domainLookupStart; //DNS查询时间
  32. loadAcData.TCP = _Timing.connectEnd - _Timing.connectStart; //TCP连接耗时
  33. loadAcData.WT = _Timing.responseStart - _Timing.navigationStart; //白屏时间
  34. loadAcData.PRDOM = _Timing.domComplete - _Timing.responseEnd; //dom解析耗时
  35. loadAcData.ONL = _Timing.loadEventEnd - _Timing.loadEventStart; //执行onload事件耗时
  36. loadAcData.DR = _Timing.domContentLoadedEventEnd - _Timing.navigationStart; //dom ready时间,脚本加载完成时间
  37. loadAcData.ALLRT = _Timing.responseEnd - _Timing.requestStart; //所有请求耗时
  38. loadAcData.FXHR = _Timing.fetchStart - _Timing.navigationStart; //第一个请求发起时间
  39. this.util.setCookie(this.store.storeTiming, JSON.stringify(ACPdata));
  40. }

image.png
对于查看首屏渲染时间,可以使用devtool查看这个时间,现代浏览器也有DOMContentLoaded事件,这个在ssr渲染模式下参考价值才大。
image.png

1.3 SPA阶段-标准无意义

image.png
SPA页面一般只存在几个简单的元素,然后由js调用ajax拿到数据再向页面插入内容,这种模式下,w3c的标准就不在准确
image.png

1.4 FMP

没有标准API支持,通过算法计算
image.png

image.png
可以在lighthouse报告中看到,First Meaningful Paint
image.png
更多的需要去监听计算来确认FMP的时间,比如视频中的FMP量化方式
另外一个分享
影子-如何量化页面FMP .pdf

2 监控模式

2.1 合成监控—-lighthouse / webpagetest

image.png

2.2 实时(真实)监控——埋点/性能/行为/错误/设备等数据上报

image.png

3 选择合适指标image.png

4 埋点

埋点(无埋点/坑位)

image.png

数据内容

image.png

页面卸载数据上报

Navigator.sendBeacon() / img (兼容)