建设前端性能监控系统

前端性能监控系统,先打造一个检测错误和性能的 SDK,再通过 ELK 来收集数据,最后通过 Grafana 来展示可视化界面,当然,Prometheus 比 ELK 更牛逼

SDK 分三部分:错误、性能、元数据

性能方面多看 google 的标准,例如 web-vitals(LCP、FID)等东西

如何打造一个 SDK 呢?

如何上报数据?

四种方案

  • 同步 XMLHttpRequest
  • img.src
  • navigator.sendBeacon
  • fetch keepalive

打造 SDK

下载

异常监听

四种

  • JS 执行异常
    • try-catch
      • 特点:可预见情况的错误监控
      • 缺点:捕获不到具体语法错误和异步错误
    • window.onerror
      • 推荐:捕获预料之外的错误
      • 缺点:捕获不到资源加载异常或接口异常
  • 资源加载异常
    • addEventListener('error', callback, true)
  • Promise 异常
    • addeventListener('unhandledrejection',callback)
  • React 异常
    • 错误边界(Error Boundaries)
      • getDerivedStateFromError
        • 作用:渲染备用 UI(展示组件错误时的 UI)
        • 捕获所有子组件错误的方法
        • 特点:在 render(渲染)阶段调用,不会出现副作用
      • componentDidCatch
        • 作用:打印错误信息
        • 特点:后代组件错误时调用
        • 缺点:不会捕获事件处理器和异步代码的异常;会在 commit 阶段被调用,会有副作用
    • 注意错误边界仅可以捕获其子组件的错误,它无法捕获其自身的错误。如果一个错误边界无法渲染错误信息,则错误会冒泡至最近的上层错误边界,这也类似于 JavaScript 中 catch {} 的工作机制。
    • 错误边界有几个场景无法捕获:
      • 事件处理
      • 异步代码(入 setTimeout 和 requestAnimationFrame 回调函数)
      • 服务端渲染
      • ErrorBoundary 自身抛出的异常(并非来自子组件)

错误边界

以前,组件内的 JavaScript 错误会导致 React 内部状态被破坏,并且在下一次渲染时产生可能无法追踪的错误

部分 UI 的 JavaScript 错误不应该导致整个应用奔溃,为了解决这个问题,React 16 引入了新的概念——错误边界

错误边界是一种 React 组件,这种组件可以捕获发生在其子组件树任何位置的 JavaScript 错误,并打印这些错误,同时展示降级 UI

错误边界有几个场景无法捕获:

  • 事件处理
  • 异步代码(入 setTimeout 和 requestAnimationFrame 回调函数)
  • 服务端渲染
  • ErrorBoundary 自身抛出的异常(并非来自子组件)

错误边界,在组件奔溃的时候降级展示,整个应用中可在多个地方展示

getDerivedStateFromError 展示降级 UI

componentDidCatch 上报错误日志给服务器

错误边界的工作方式类似于 JavaScript 的 catch {},不同的地方在于错误边界只针对 React 组件

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // 更新 state 使下一次渲染能够显示降级后的 UI
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // 你同样可以将错误日志上报给服务器
    logErrorToMyService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // 你可以自定义降级后的 UI 并渲染
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}

React 异常

getDerivedStateFromError

componentDidCatch

前端容灾

localstorage

把数据存在 localstorage 中

cdn

每次更新备份一份静态数据

service worker

离线存储

sourceMap

sourceMap 是什么?sourceMap 就是一个文件,里面储存着位置信息

这个文件里保存的,是转换后代码的位置,和对应的转换前的位置

参考资料

Last Updated:
Contributors: johan