Skip to content

性能监控

前端性能监控是指通过监控前端应用的性能指标、响应时间、资源加载情况等,实时掌握用户体验和应用性能的状况,及时发现潜在问题并优化。前端性能监控是确保应用高效、流畅运行的重要环节,尤其在大型应用中至关重要。

前端性能监控的主要指标

  1. 加载时间

    • 页面加载时间:从请求开始到页面渲染完成所需的时间。
    • 首屏加载时间:即用户看到页面内容的时间,通常指的是 HTML 和主要资源(如 CSS、JS、图片)的加载时间。
    • 资源加载时间:每个资源(CSS、JS、图片等)加载的时间。
  2. 响应时间

    • 首次响应时间(First Response Time, FRT):从用户发起请求到浏览器收到响应的时间。
    • 时间到交互(Time to Interactive, TTI):页面加载完成并且用户可以与页面进行交互的时间。
  3. 渲染性能

    • 帧率:通常以 FPS(每秒帧数)来衡量,理想的帧率是 60 FPS(16ms/帧),低于此帧率会导致页面卡顿。
    • 重绘和回流:浏览器在渲染页面时会对元素进行重绘或回流,频繁的回流和重绘会导致性能下降。
  4. JavaScript 性能

    • 执行时间:JavaScript 的执行时间,过长的执行时间会导致页面卡顿。
    • 事件处理器执行时间:用户与页面交互时,事件处理器的执行时间也会影响响应速度。
  5. 网络请求和带宽

    • API 响应时间:请求 API 时,网络延迟、服务器响应速度等都会影响性能。
    • 请求数量:页面加载时发起的 HTTP 请求数量,过多的请求会增加加载时间。
  6. 错误监控

    • JavaScript 错误:捕捉页面中出现的 JavaScript 错误,影响页面的执行和用户体验。
    • 资源加载失败:如 CSS、JS、图片等资源加载失败的监控。

性能监控的主要技术

  1. Performance API

    • 浏览器提供的原生 Performance API 可以获取页面加载时间、资源加载时间、脚本执行时间等指标。
    • 常用的 API:
      • performance.now():返回高精度的时间戳,通常用于测量代码执行的时间。
      • performance.mark()performance.measure():可以手动标记代码执行的时间节点并计算时间间隔。
  2. Window.performance

    • 提供了获取页面加载信息的方法,如 performance.timing,该属性包含了各种与页面加载相关的时间信息。
    • 常用属性:
      • performance.timing.navigationStart:页面导航开始的时间。
      • performance.timing.loadEventEnd:页面加载完成的时间。
  3. Google Lighthouse

    • Lighthouse 是一个开源的自动化工具,可以评估网页的性能、可访问性、SEO、PWA 等。
    • 它提供了详细的性能报告,包括关键性能指标(如 FCP、LCP、FID、CLS)以及优化建议。
    • 适用于在开发阶段或部署后对应用进行性能检测。

An image

  1. Web Vitals

    • Web Vitals 是 Google 推出的一个指标集合,旨在帮助开发者监控和优化用户体验。
    • 主要包括三大核心指标:
      • Largest Contentful Paint (LCP):页面最大内容绘制时间,衡量页面的加载性能。
      • First Input Delay (FID):首次输入延迟,衡量用户与页面交互的响应时间。
      • Cumulative Layout Shift (CLS):累计布局偏移,衡量页面内容布局的稳定性。
    • 通过 web-vitals 库可以轻松集成并收集 Web Vitals 数据。
  2. 监控服务集成

    • 使用第三方监控服务,如:
      • Sentry:除了错误监控,Sentry 也提供性能监控,能够捕捉到页面加载性能、用户互动时间等。
      • New Relic:提供前端性能监控,支持 JavaScript 事务追踪、页面性能监控、API 性能监控等。
      • Datadog:前端性能监控、日志记录和应用追踪,能够帮助开发者深入了解应用的性能瓶颈。
特性SentryNew RelicDatadog
主要功能错误监控 + 性能监控性能监控 + 事务追踪性能监控 + 日志管理 + 基础设施监控
适用场景错误排查和基础性能监控企业级应用的全面性能监控全栈应用的性能监控与日志管理
功能亮点错误追踪、JavaScript 错误捕获强大的 APM 支持,全面的事务追踪完整的监控平台,支持分布式追踪
优点易于集成、支持多平台、详细的错误堆栈精确的性能监控、事务追踪能力强全面的性能监控与日志管理,适合复杂环境
缺点性能监控较基础,功能不够全面学习曲线较陡,价格较高对小型应用可能过于复杂,定价较高
适用规模中小型应用、开发阶段中大型企业级应用大型应用、微服务架构、全栈监控
价格免费套餐,按需计费需要付费,高级功能较为昂贵按需计费,价格较高

性能监控的实践技巧

  1. 按需加载资源

    • 采用懒加载、按需加载技术,减少页面初次加载时的资源请求数量,缩短页面加载时间。
    • 使用动态 import() 实现按需加载 JS 文件,使用 IntersectionObserver 实现懒加载图片。

      专题版块详见 懒加载图片

    js
    // 需要时才加载模块
    button.addEventListener("click", () => {
      import("./largeModule.js").then((module) => {
        module.loadData();
      });
    });
  2. 优化 JavaScript 执行

    • 将 JavaScript 代码拆分成多个小模块,使用 Webpack、Vite 等构建工具进行代码分割(code splitting)。
      • Webpack 支持几种不同的代码拆分方式:入口拆分、块拆分和 动态拆分。
    • 避免长时间运行的 JavaScript 任务,使用 Web Workers 进行后台处理。
      • 长时间运行的 JavaScript 任务(例如复杂的计算、大量数据处理)可能会导致浏览器卡顿,影响用户体验。使用 Web Workers 可以将这类任务移至后台线程,在不阻塞主线程的情况下处理大量数据或复杂计算。

    创建和使用 Web Worker

    在主线程中,通过 Worker 构造函数来创建一个新的 Web Worker 实例。Web Worker 会在后台线程中执行脚本,主线程与 Worker 通过 postMessageonmessage 事件进行通信。

    js
    // main.js
    const worker = new Worker("worker.js");
    
    // 向 Worker 发送数据
    worker.postMessage("Start processing");
    
    // 接收 Worker 返回的数据
    worker.onmessage = function (e) {
      console.log("Result from worker:", e.data);
    };
    
    // worker.js
    onmessage = function (e) {
      console.log("Worker received:", e.data);
      // 处理任务
      let result = performComplexCalculation();
      postMessage(result); // 将结果传回主线程
    };
    
    function performComplexCalculation() {
      // 假设这是一个复杂的计算
      return 42;
    }

    注意

    • 在浏览器中,Worker 是原生支持的,因此没有问题。
    • 在 Node.js 环境中,Worker 需要通过 worker_threads 模块来实现多线程功能。

    如果你希望在浏览器环境中使用 Web Worker,而又不想让代码在 Node.js 中报错,可以通过条件判断来判断代码运行环境:

    js
    // 这将确保代码在浏览器中正常执行,而在 Node.js 环境中不会报错。
    if (typeof Worker !== "undefined") {
      const worker = new Worker("worker.js");
    } else {
      console.log("Web Workers are not supported in this environment");
    }
  3. 优化网络请求

    • 使用 HTTP/2 或 HTTP/3 协议,减少请求的延迟。
    • 压缩资源文件,如使用 Gzip(源于 1992 年)、Brotli(2015 年首次发布) 压缩 JS、CSS 文件。
      • Gzip 和 Brotli 都是常用的文件压缩算法,Brotli 是相较于 Gzip 更高效的压缩算法,尤其在文本文件压缩方面具有更高的压缩比。
      • Brotli 压缩 能显著提升 Web 应用的加载速度,尤其对于大型静态资源文件(如 JS、CSS、HTML 文件)。
    • 减少 HTTP 请求的数量,合并 CSS 和 JS 文件,使用图片精灵(sprites)等技术。
特性GzipBrotli
压缩率较低,通常比 Brotli 差 20-30%较高,比 Gzip 提供更好的压缩率
速度较快,压缩和解压速度较高相对较慢,特别是压缩速度较低
支持度几乎所有的浏览器、Web 服务器和 CDN 都支持现代浏览器支持较好(Chrome、Firefox、Edge、Safari)
使用场景适用于压缩速度较为敏感的场合,且兼容性要求较高适用于需要优化带宽和加载时间的场合,尤其是 HTTP/2 和 HTTP/3 中
主要应用用于 Web 页面和文件的 HTTP 压缩用于 Web 页面、文件的 HTTP 压缩和更高效的带宽利用
优化方法原理应用场景实现方法
HTTP/2 / HTTP/3多路复用、头部压缩、服务器推送,减少延迟并发请求多、数据传输效率要求高的场景配置服务器支持 HTTP/2 或 HTTP/3。
资源压缩使用 Gzip 或 Brotli 压缩算法减少文件体积,提升加载速度所有静态资源(JS、CSS、HTML)配置服务器支持 Gzip 或 Brotli,构建工具压缩资源。
减少请求数量合并文件、使用图片精灵(英语:Sprite,又称“雪碧图”)等技术减少 HTTP 请求次数静态资源多且独立、图标和小图片的场景配置 Webpack、Parcel 进行资源合并,使用图片精灵工具。

Nginx 配置 Brotli

  1. 安装 Brotli 模块
bash
# 如果你是通过 apt 安装的 Nginx,可以使用以下命令来安装 Brotli 模块
sudo apt-get install nginx-module-brotli
  1. 在 Nginx 配置文件中启用 Brotli: 在 nginx.conf 中启用 Brotli 压缩:
nginx
http {
  brotli on;
  # brotli_comp_level 设置 Brotli 压缩的级别(1-11,数字越大,压缩率越高,但性能开销越大)。
  brotli_comp_level 5;
  # brotli_types 指定哪些 MIME 类型的文件需要使用 Brotli 压缩。
  brotli_types text/plain text/css application/javascript application/json application/xml application/xhtml+xml image/svg+xml;

  server {
    listen 80;
    server_name example.com;

    location / {
      root /var/www/html;
    }
  }
}
  1. 重启 Nginx 服务器: 完成配置后,重启 Nginx 使设置生效:
bash
sudo systemctl restart nginx

Vite 配置 Brotli

  1. 安装 vite-plugin-compression 插件:
bash
npm install vite-plugin-compression --save-dev
  1. 配置 Vite 启用 Brotli:
js
import ViteCompression from "vite-plugin-compression";

export default {
  plugins: [
    ViteCompression({
      algorithm: "brotli",
      threshold: 10240, // 只有大于 10KB 的文件才会压缩
    }),
  ],
};

如何查看浏览器对 Brotli 的支持情况

  1. 使用浏览器开发者工具检查响应头
    • 打开浏览器的开发者工具(F12)。
    • 在 Network(网络)选项卡中,加载你的页面或资源。
    • 选择某个静态资源(如 JS、CSS 文件等),查看它的响应头(Response Headers)。
    • 检查 Content-Encoding 字段:
      • 如果响应头中包含 Content-Encoding: br,则表示该资源使用了 Brotli 压缩。
      css
      content-encoding: br;
  2. 使用浏览器支持情况工具 你也可以通过工具查看浏览器对 Brotli 的支持情况。常见的工具是 Can I use,它会显示不同浏览器对 Brotli 的支持情况。
    • 访问 Can I use 查看详细的浏览器支持情况。

哪些网站是开启 Brotli 压缩的?

An image

  1. 优化渲染性能

    • 避免不必要的重绘和回流,减少 DOM 操作。

    • 使用 requestAnimationFrame() 进行动画优化,避免阻塞渲染线程。

      • requestAnimationFrame() 是浏览器提供的一个 API,用于请求浏览器在下一次重绘之前执行动画操作。
      • 高效调度:requestAnimationFrame() 会在浏览器的重绘周期内执行,避免了过多的 JavaScript 执行,这有助于降低 CPU 和内存的负担。
      • 减少卡顿:因为它在刷新率匹配的时间点执行,所以动画会平滑且流畅。
      js
      function animate() {
        // 更新动画状态
        const element = document.getElementById("box");
        const currentLeft = parseFloat(element.style.left || 0);
        element.style.left = currentLeft + 1 + "px";
      
        // 请求下一帧动画
        requestAnimationFrame(animate);
      }
      
      // 启动动画
      requestAnimationFrame(animate);
    • 使用 CSS3 动画替代 JavaScript 动画,提升性能。

      • CSS3 动画通常比 JavaScript 动画更高效,因为它们由浏览器的渲染引擎直接处理,避免了 JavaScript 的计算开销和频繁 DOM 操作。CSS 动画可以利用 GPU 加速,尤其是当涉及到 transformopacity 时。
      css
      /* CSS3动画 */
      @keyframes moveRight {
        0% {
          left: 0;
        }
        100% {
          left: 100px;
        }
      }
      
      #box {
        position: absolute;
        animation: moveRight 2s infinite linear;
      }
  2. 前端性能监控的自动化

    • 定期使用 Lighthouse、Web Vitals 等工具进行性能检测,并根据分析报告进行优化。
    • 将性能监控集成到 CI/CD 流程中,自动化性能回归检测,确保每次发布都不会影响性能。
      • 可以使用 Lighthouse CI 集成到 CI/CD 流程中,自动化运行 Lighthouse 检测,生成报告并与之前的性能基准进行对比。

性能监控应用场景

  1. 实时监控应用性能

    • 适用于需要实时监控前端性能的应用,能够第一时间发现并解决性能瓶颈。
    • 常见应用:电商网站、社交媒体平台、大型 SaaS 应用等。
  2. 大规模网站和应用的性能评估

    • 适用于大规模、高流量网站或应用,能够帮助开发者了解不同用户设备和网络环境下的性能表现。
    • 常见应用:新闻网站、视频平台、金融平台等。
  3. 提升用户体验

    • 通过实时监控和优化前端性能,提升页面加载速度和交互响应速度,改善用户体验。
    • 常见应用:新闻网站、博客平台、在线商店等。

总结

前端性能监控是提升应用用户体验的关键部分,通过对页面加载时间、资源加载、JavaScript 执行、网络请求、渲染性能等多个指标的监控,帮助开发者及时发现并优化性能瓶颈。结合 Performance API、Web Vitals、Lighthouse 等工具,开发者可以有效监控和优化前端性能,提升用户体验。