项目代码
参考文章

监控目标

  1. 稳定性【stability】 | 错误名称 | 描述 | | —- | —- | | js报错 | js执行错误或promise异常 | | 资源resource报错 | script或者link资源加载异常 | | 接口报错 XMLHttpRequest | ajax或者fetch接口异常 | | 白屏 | 页面没有绘制出元素 |

  2. 用户体验【experience】 | 错误名称 | 备注 | | —- | —- | | 加载时间 | 各个阶段的加载时间 | | TTFB(time to first byte) | 首字节时间 | | FP(First Paint) | 首次绘制 | | FCP(First Content Paint) | 首次内容绘制 | | FMP(First Meaningful Paint) | 首次有意义绘制 | | L(load) | 加载时间 | | LCP(load Content Paint) | 内容加载完成 | | 卡顿 | 超过50ms的长任务 |

  3. 业务指标【business】 | 名称 | 备注 | | —- | —- | | PV | page view 页面浏览量或点击量 | | UV | 访问站点的不同IP地址的人数 | | 页面停留时间 | 用户在页面停留时间 |

监控流程

  1. 数据埋点
  2. 数据采集/上报
  3. 数据分析
  4. 可视化展示
  5. 监控报警

前端监控系统 - 图1

埋点方案

  1. 代码埋点
    1. 以嵌入代码的形式进行埋点。比如监控用户的点击事件,在用户点击时插入一段代码,保存这个监听行为的各种数据,并发送给服务器
    2. 优点:可以在任意时刻,精确的发送或保存所需要的数据信息
    3. 缺点是工作量大
  2. 可视化埋点
    1. 通过可视化交互的手段,代替代码埋点
    2. 将业务代码和埋点代码分离,提供一个可视化交互的页面,输入为业务代码。通过可视化系统可以在业务代码中自定义增加埋点事件。
    3. 可视化埋点是用系统代替手工插入埋点代码。
  3. 无痕埋点

    1. 前端的任意一个事件被绑定一个标识,所有事件都被记录下来
    2. 通过定期上传记录文件,配合文件解析,

      监控采集脚本

      阿里云日志服务,开通sls日志服务。日志服务(SLS)是云原生观测分析平台,为Log/Metric/Trace等数据提供大规模、低成本、实时平台化服务。一站式提供数据采集、加工、分析、告警可视化与投递功能,全面提升研发、运维、运营和安全等场景数字化能力。
      日志服务帮助文档
      web Tracking
      putWebTracking
      image.png

      监控错误

      错误分类

  4. js错误

  5. promise错误
  6. 资源错误

    数据结构设计

    jsError
    1. {
    2. "title": "前端监控系统",
    3. "url": "http://localhost:8000",
    4. "timestamp": "1523223",
    5. "useAgent": "Chrome",
    6. "kind": "stability",
    7. "type": "error",
    8. "errorType": "jsError",
    9. "message": "Uncaught TypeError: Cannot set properties of undefined (setting 'error')",
    10. "filename": "http://localhost:8000/",
    11. "position": "0:0",
    12. "stack": "errorClick (http://localhost:8000/:22:30)^HTMLInputElement.onclick (http://localhost:8000/:12:68)",
    13. "selector": "html body div#container div.content input"
    14. }
    promiseError
    1. {
    2. "title": "前端监控系统",
    3. "url": "http://localhost:8000",
    4. "timestamp": "1523223",
    5. "useAgent": "Chrome",
    6. "kind": "stability",
    7. "type": "error",
    8. "errorType": "promiseError",
    9. "message": "Cannot set properties of undefined (setting 'error')",
    10. "filename": "http://localhost:8000/",
    11. "position": "0:0",
    12. "stack": "http://localhost:8000/:26:34^new Promise (<anonymous>)^promiseErrorClick (http://localhost:8000/:25:9)^HTMLInputElement.onclick (http://localhost:8000/:17:11)",
    13. "selector": "html body div#container content input"
    14. }

    接口异常采集脚本

    数据设计

    1. {
    2. "title": "前端监控系统",
    3. "url": "http://localhost:8000",
    4. "timestamp": "1523223",
    5. "useAgent": "Chrome",
    6. "kind": "stability",
    7. "type": "xhr",
    8. "errorType": "load",
    9. "path": "/success",
    10. "status": "200-ok",
    11. "duration": "7",
    12. "response": "{'ok'}",
    13. "params": ""
    14. }

    白屏时长

    白屏时间过长,会造成不好的用户体验。白屏就是页面上什么都没有

数据结构

  1. {
  2. "title": "前端监控系统",
  3. "url": "http://localhost:8000",
  4. "timestamp": "1523223",
  5. "useAgent": "Chrome",
  6. "kind": "stability",
  7. "type": "blank",
  8. "emptyPoints": "0",
  9. "screen": "1920x1080",
  10. "viewPoint": "2048x994",
  11. "selector": "HTML BODY #container"
  12. }

参数:

  • screen:返回当前window的screen对象,当前渲染窗口中和屏幕有关的属性
  • innerWidth:window的innerWidth属性,只读。返回以像素为单位,窗口内部的宽度
  • innerHeight:window的innerHeight属性,只读。返回以像素为单位,窗口内部的高度
  • layout_viewport:
  • elementsFormPoint:可以获取到当前视口内指定坐标处,由里到外排列的所有元素

performance 性能指标

阶段计算

字段 描述 计算方式 意义
unload 前一个页面卸载时长 unloadEventEnd - unloadEventStart 前一个页面卸载时长
redirect 重定向时长 redirectEnd-redirectStart 重定向时长
appCache 缓存耗时 domainLookupStart - fetchStart 缓存耗时
dns DNS解析耗时 domainLookupEnd-domainLookupStart 观察域名解析服务是否正常
tcp TCP连接耗时 connectEnd-connectStart 建立连接的耗时
ssl SSL安全连接耗时 connectEnd-secureConnectionStart 建立ssl安全连接的耗时
ttfb Time to First Byte[TTFB]
网络请求耗时
responseStart-requestStart 页面发出请求到接收到响应数据的第一个字节,消耗的毫秒数
response 响应数据传输耗时 responseEnd-responseStart 观察网络是否正常
dom DOM解析耗时 domInteractive-responseEnd 观察DOM结构是否合理,是否有js阻塞页面解析
dcl DOMContentLoaded 事件耗时 domContentLoadedEventEnd-domContentLoadedEventStart 当HTML文档被完全加载和解析完成DOMContentLoaded事件被触发,无需等待样式表、图片、和子框架的加载
resources 资源加载耗时 domComplete-domContentLoadEventEnd 可观察文档流是否过大
domReady DOM阶段渲染耗时 domContentLoadEventEnd-fetchStart DOM树和页面资源加载完成时间
FP 首次渲染耗时 responseEnd-fetchStart 加载文档到看到第一帧非空图像的时间,也叫白屏时间
FID 首次可交互时间 domInteractive-fetchStart
首包时长 首包时长 responseStart-domainLookupStart DNS解析到响应返回给浏览器第一个字节的时间
页面完全加载时间 页面完全加载时间 loadedEventStart-fetchStart
onLoad onLoad事件耗时 loadedEventEnd-loadedEventStart

性能指标

  • PerformanceObserver.observe
  • entryType
  • paint-timing
  • event-timing
  • LCP
  • FMP
  • time-to-interactive | 字段 | 描述 | 备注 | | —- | —- | —- | | FP | First Paint 首次绘制 | 包括了任何自定义的背景绘制,不一定是DOM。表示首次将像素绘制到屏幕的时刻 | | FCP | First Content Paint 首次内容绘制 | 浏览器将第一个DOM渲染到屏幕的时间,可以是文本、图形、SVG等,这其实是白屏时间 | | FMP | First Meaningful Paint 首次有意义内容绘制 | 页面有意义内容渲染时间 | | LCP | Largest Contentful Paint 最大内容渲染 | 代表在viewport中最大的页面元素加载的时间 | | DCL | DomContentLoaded DOM加载完成 | 当HTML文档被完全加载和解析完成DOMContentLoaded事件被触发,无需等待样式表、图片、和子框架的加载 | | L | onload | 当依赖的资源全部加载完毕之后才会触发 | | TTI | Time to Interactive 可交互时间 | 用于标记应用已进行视觉渲染并能可靠响应用户输入的时间点 | | FID | First Input Delay 首次输入延迟 | 用户首次和页面交互(点击链接、按钮、输入框等)到页面响应交换的时间 |

资源下载:链接: https://pan.baidu.com/s/19HcFa3Fo0G4zbjYfdgfopQ 提取码: 95f2