前端性能优化

性能优化的目的是为了实现资源的快速加载和响应。性能优化前,需要先分析性能,目的是分析出包含页面渲染、网络传输和文件加载等时间指标,对该页面进行评估分析。找出影响性能的主要因素和瓶颈,对此给出性能优化解决方案。

1. 性能分析

1.1. Chrome 浏览器的 Performance

Chrome 浏览器的 Performance 选项卡主要用于对页面进行性能分析,以下是使用步骤:

  1. 开发者工具中,找到 “Performance” 标签。
  2. 在 Performance 选项卡下,点击录制,或重新加载可以录制整个网页加载过程。可以开启CPU 6倍降速,降低 6 倍性能。通过重新加载 https://developer.mozilla.org/ 页面可以看到具体的性能指标

performance摘要

从以上摘要可以看出:HTML(蓝色)、脚本(脚本)、样式表(紫色)、媒体文件(绿色)、其他资源(灰色/黑色)都标出了耗时。

performance-cpu-net

CPU 也按照时间线标出了HTML(蓝色)、脚本(脚本)、样式表(紫色)、媒体文件(绿色)、其他资源(灰色/黑色)的占用的空间。

网络也按照时间长短标出了具体是哪一个 js 占用更长等等。

但是这些信息还看不出具体的性能问题,需要进一步确认:

点击主要(main)中具体的任务(task),摘要下会显示警告,例如:

performance-main

提示:已强制自动重排,可能是性能瓶颈,点击进入可以参看具体的代码,找到并解决/优化。

1.2. performance.timing

通过 performance.timing,可以获取到一系列的性能指标,如页面白屏耗时、完全加载耗时、解析DOM树耗时等。这些指标对于分析和优化网页性能至关重要。通过对这些指标的分析,可以找出性能瓶颈,从而针对性地进行优化,提升用户体验。

例如:

performance-timing

列出了多个时间节点的具体时间戳,通过 responseEnd - responseStart 能够得到响应时间。

1.3. lighthouse

lighthouse 是 Google 开发和开源的 Web 性能测试的工具。能够对网页进行自动化的性能分析,收集现代性能指标,并提供关于开发者最佳实践的建议。

  1. 在 Chrome 浏览器开发者工具中找到 Lighthouse 选项
  2. 选择你想要进行性能测试的方向(例如桌面或移动)。
  3. 点击“Generate Report”生成报告。

例如还是访问 https://developer.mozilla.org/ 生成报告如下:

lighthouse

列出了性能(Performance)、可访问性(Accessibility)、最佳实践(Best Practices)、SEO、渐进式Web应用(PWA) 5 项指标分别的评分。

同时,底部还列出了诊断,提供解决方案:

lighthouse 诊断

2. 性能优化

2.1. 图片优化

前端开发中,图片占到了很大比重。

  • 减少图片

去掉毫无意义的装饰类的图片。比如可以用 icon 来替代一些小图标。

  • 通过 CSS 模拟图形

如果是纯图形,可以通过 CSS 代码生成。

  • 使用合适的图片格式

图片颜色较少、需要阴影,可以使用 png。相同质量下,WebP 格式比 JPEG 图像少 40% 左右。

2.2. 图片懒加载

让图片元素进入视口范围内才被加载。

2.3. DOM 优化

  • 减少重排和重绘

将结果缓存,避免重复计算。引入 DocumentFragument 文档片段,对 DOM 的操作先在该片段下再才做完成了在放置在 DOM 节点内。使用 classList 合并属性

  • 节流和防抖

2.4. WebWorker 介入数据密集型操作

Web Worker 为 JS 创建了多线程环境。可以将一些运算分配到子线程运算,减轻主线程压力,使得主线程和子线程之间互不干扰。

下面以后台数值计算为例演示:

// main.js
let worker = new Worker("./worker.js");

worker.postMessage({
    status: 0
});

worker.onmessage = function (event) {
    document.querySelector(".calc").innerHTML = event.data;
    worker.terminate(); // 主线程关闭
};
// worker.js
onmessage = function (event) {
    console.log(event);
    let status = event.data.status;
    if (status === 0) {
        startToCalc();
    }
}

function startToCalc() {
    let arr = [];
    for (let i = 1; i <= 1000; i++) {
        arr.push(i);
    }
    let tStart = new Date().getTime();
    let total = arr.reduce((sum, item) => sum + item);
    let tEnd = new Date().getTime();
    console.log(`耗时:, ${tEnd - tStart}, ms`);
    postMessage(`处理完成,耗时: ${tEnd - tStart} ms,和为:${total}`); // 使用中文可能会引起乱码
    self.close(); // 子线程关闭
}

2.5. Webpack 优化

  • 减少文件匹配范围

在 rules 中配置 exclude,减少 loader 的搜索范围。

module: {
  rules: [
    {
      test: /\.js$/,
      use: 'babel-loader',
      exclude: /node_module/,  // 指定排除掉的目录
      include: path_resolve(__dirname, 'src') // 指定要处理的目录
    }
  ]
}
  • 缓存 babel-loader 结果

将转义后的结果缓存到文件系统中,配置 cacheDirectory 选项:

rules: [
  {
    test: /\.js$/,
    use: 'babel-loader?cacheDirectory',
    exclude: /node_module/
  }
]
  • 优化模块配置

使用短路径 alias。

resolve: {
  alias: {
    "@components": path,resolve(__dirname, 'src/components')
  }
}

为了使用 src/components 下的组件,直接 import { x } from "@components";

  • 配置 parser

配置不希望被转换的文件:

rules: [
  {
    parser: {
      System: false  // systemjs 不被解析
    }
  }
]
  • 从 bundle 中摘除第三方库

增加 external 配置,可以摘除第三方库:

external: [
  /axios/, /lodash/
]

axios 和 lodash 可以通过 CDN 引入,提高加载速度。

  • 使用 url-loader 优化图片

url-loader 可以将较小的静态文件内联到静态文件中:

rules: [
  {
    test: /.(jpg|png|jpeg|gif)$/,
    loader: 'url-loader',
    options: {
      limit: 10 * 1024,  // 把小于 10KB 的图片内联到文件中
    }
  }
]

如果不配置, 则将获取一个文件,并放在 bundle 文件同级目录中。

性能优化是循循渐进的过程,不像 bug 那样一次性解决。

posted @ 2024-03-19 21:20  艾前端  阅读(94)  评论(0编辑  收藏  举报