前端性能优化之网络负载

网络优化

配置优化:通过调整构建工具(如WebpackVite)的配置,比如代码压缩、Tree Shaking和代码分割,减少打包体积和加载时间。

访问优化:包括图片懒加载、预加载关键资源,以及优化DOM操作,减少渲染阻塞,提升用户体验。

通过减少HTTP请求、启用HTTP/2、使用CDN和缓存策略,提升资源加载速度。

避免巨大的网络负载是Lighthouse的一个审计指标,它指的是前端文件通过网络传输的总大小

需要实施一个全面的Web性能优化流程:识别特定问题、可视化HTMLCSS文件、压缩和精简代码、减小字体和图片的体积等。

网络负载是指页面从自身服务器或第三方服务器通过互联网下载的所有文件的总和。

优化网络负载

需要减少资源的总大小:

  1. 移除不必要的资源
    • 找出那些对用户体验没有显著影响的资源,并将它们从页面中移除。
    • 未使用的CSSJavaScript文件、过大的图片等
  2. 减小资源的下载大小
    • 使用压缩工具(如GzipBrotli)压缩HTMLCSSJavaScript文件。
    • 优化图片和字体大小,采用现代格式(如webPwoff2)。
  3. 延迟加载资源(Lazy Loading)
    • 仅在用户需要某些资源时才进行下载。
    • 使用loading="lazy"属性为图片和iframe添加懒加载。

Lighthouse记录的是页面初始加载时的网络负载。这意味着报告显示的资源大小是页面首次加载时所有请求的总和。

根据Lighthouse的文档,当网络负载满足以下条件时,就会被认为是“巨大”:

根据HTTP Archive的数据,网络负载的中位数在17001900``KiB之间。为了突出最重的网络负载,Lighthouse会标记那些总网络请求超过5000``KiB的页面。

  1. 黄色警告标志的触发条件

    • 当网络负载超过2667KB时,Lighthouse会触发黄色警告标志(yellow flag)。
    • 低于这个值,则显示灰色信息标志(grey flag),表示通过。
  2. 永远没有绿色标志

  3. 没有红色标志

    • 即使网络负载非常高,Lighthouse也不会触发红色标志(red flag)。它只会显示黄色标志,提示需要优化。
  4. 灰色标志:表示通过审计,但仅限于网络负载低于2667KB的情况。

  5. 黄色标志:表示未通过审计,网络负载超过2667KB

  6. 红色标志:不会触发,即使网络负载非常高。

  • 灰色标志=成功:网络负载低于2667KB
  • 黄色标志=失败:网络负载高于2667KB

因此,优化目标是让网络负载尽可能小,以达到灰色标志的标准。

巨大的网络负载会对Web性能产生严重影响,不仅会导致页面加载变慢,有时还会引发意外的布局偏移问题。

  1. 对核心Web指标的影响

巨大的网络负载可能会增加以下三个核心Web指标的得分,从而降低用户体验:

  • 最大内容渲染时间(Largest Contentful Paint, LCP
    当网络负载较重时,关键内容(如首屏内容)需要更长时间才能出现在屏幕上,直接导致LCP得分变差。

  • 交互到下一次渲染时间(Interaction to Next Paint,INP
    JavaScript文件下载和编译速度变慢,会拖延交互反馈时间,影响用户的操作流畅性。

  • 累计布局偏移(Cumulative Layout Shift,CLS
    如果浏览器需要下载并处理更多文件,不同的布局元素可能会以非线性的顺序出现,导致更多的意外布局偏移。

分析网络负载

  1. 使用Lighthouse报告
    LighthouseAvoid Enormous Network Payloads审计可以快速判断你的页面是否通过了网络负载的审计,并提供网络负载的整体结构概览。
  2. 使用高级性能分析工具
  • 资源的请求瀑布图(Request Waterfall

解读瀑布图

  • 每个资源的大小
  • 加载优先级
  • 加载持续时间
  • 加载顺序

通过分析这些信息,你可以

  • 找到不必要的资源,考虑移除
  • 针对某些资源进行重构或替换
  • 将低优先级资源推迟加载(如图片、非关键CSSJS
  1. DebugBear的功能亮点
  • 资源排序:根据请求的优先级、持续时间、大小和下载顺序对资源进行排序。
  • 域名分析:查看浏览器连接的所有第三方域名。
  • 资源过滤:按文件类型(HTMLCSS、脚本、图片、字体等)过滤资源,快速定位目标资源。
  • HTTP请求细节检查
    • 请求头和响应头
    • 请求体内容
    • 请求链(Request Chain
  1. 优化思路
  • 移除不必要的资源:检查哪些资源是可以完全去掉的。
  • 推迟加载非关键资源:如懒加载图片和脚本
  • 合并或精简资源:减少资源的体积和数量
  • 优化第三方资源:检查是否有过多的第三方请求,优先优化它们

减少HTML文件的下载大小

如何判断HTML文件是否过大?

  • 使用LighthouseDebugBear的审计功能,检查文件是否超标(通常基于压缩后的体积)。
  • 分析文件中的具体问题:
    • 内联样式:过多的<style>
    • 内联脚本:嵌入过多的<script>内容

优化方法

  1. 分离内联内容
  • 将内联的样式和脚本移至外部文件
  1. 启用HTTP压缩
  • 在服务器端启用GzipBrotli压缩,进一步减小传输体积。
  1. 删除无用内容
  • 检查冗余注释、多余空格和不必要的meta标签,减小文件大小。

避免过大的CSS文件

  1. 冗长的选择器
    • 复杂的CSS选择器增加文件体积
  2. 未使用的样式规则
    • 项目中未被使用的CSS代码
  3. Base64编码的嵌入资源
    • 内嵌的图片或字体会显著增加文件体积,可将它们替换为外部文件
  4. 过长的变量名
    • 变量命令过长会累积大量不必要的字节数

优化方法

  1. 清理未使用的样式
    • 使用工具如PurifyCSSUNCSS检测和移除未被引用的规则。
  2. 压缩CSS文件
    • 借助cssnanoPostCSS删除多余空格、注释等内容。
  3. 分割与按需加载
    • 通过代码分割技术,将CSS文件拆分为仅需加载的部分。
  4. 优化变量命名
    • 将过长的变量名替换为更简短的名称。

压缩文本文件

优化网络负载的一个关键步骤是压缩HTMLCSSJavaScriptJSON等文本文件。通过服务器端压缩,可以显著减少文件体积,加快网页加载速度。

常见的文本压缩算法

  1. Gzip
    • 支持的压缩级别:19
    • 优点:几乎所有浏览器都支持
    • 缺点:压缩效率稍逊于BrotliZstandard
  2. Brotli
    • 支持的压缩级别:111
    • 优点:更高的压缩效率,全球浏览器支持率达97.65%
    • 缺点:部分旧版浏览器可能不支持
  3. Zstandard
    • 支持的压缩级别:-722
    • 优点:超高的压缩效率,适合对性能要求极高的场景
    • 缺点:浏览器支持仅70.41%(Safari不支持)

压缩级别的权衡

  • 低压缩级别(如Gzip 1Brotli 1Zstandard -7
    • 压缩速度更快,但效率较低
  • 高压缩级别(如Gzip 9Brotli 11Zstandard 222
    • 压缩效率更高,但需要更多的CPU时间

选择压缩级别需要根据服务器性能和网络传输需求平衡。大多数常见推荐使用中高压缩级别(如Brotli 6-8)。

如何检查压缩情况

使用工具DebugBear可以检测页面加载的所有资源及其对应的压缩算法:

  • 显示文件所用的压缩方式(如GzipBrotli
  • 提示是否存在未压缩的文本文件

精简HTMLCSSJavaScript文件

在压缩文本文件的基础上,进一步对HTMLCSSJavaScript文件进行精简(Minify),可以显著减少文件体积。当压缩和精简结合使用时,文件体积的总体减少可以达到90%

精简与压缩的区别

特点 压缩Compression 精简(Minification
作用 使用GzipBrotliZstandard等算法对文本文件进行编码。 移除代码中的多余空格、换行符、分号和注释等冗余内容。
执行位置 在服务器端编码,浏览器端解码;通过HTTP Header协商支持的算法。 在构建流程中或上传到服务器前完成,浏览器可直接解析精简文件。
输出文件格式 不可读,文件后缀通常为.gz.br.zst等(保留原始扩展名) 可读,文件后缀不变,但通常添加.min标识,如.min.css
工具 服务器端编码器如GzipBrotliZstandard 构建工具如WebpackRollup或独立精简工具如HTML Minifier

减少未使用的CSSJavaScript

除了压缩和精简,审查并移除未使用的CSSJavaScript是进一步降低页面体积的关键步骤。

  1. 审查未使用的代码

    • 使用Chrome DevToolsCoverage面板,识别未使用的CSSJS
    • 借助DebugBear等工具,分析未使用代码的比例。
  2. 移除未使用的CSS

    • 使用工具如PurifyCSSUNCSS自动移除未使用样式。
    • 按需加载特定页面的样式
  3. 减少未使用的JavaScript

    • Tree Shaking:通过模块打包工具移除未使用的代码
    • 动态加载
1
2
3
import('./style.css').then(() => {
console.log('样式加载完成');
});
1
import('./module.js').then(module => module.init());

优化第三方代码

对于第三方库(如Bootstrap),避免直接修改其代码,但可以通过代码分割等技术只加载必要部分。

优化图片体积

图片优化方法

  1. 避免不必要的大图片

    • 实施响应式图片策略:为同一位置提供多种分辨率的图片,让浏览器根据设备选择最合适的版本。
      1
      2
      3
      4
      5
      6
      <img
      srcset="small.jpg 480w, medium.jpg 800w, large.jpg 1200w"
      size="(max-width: 800px) 100vw, 800px"
      src="medium.jpg"
      alt="example"
      />
  2. 延迟加载屏幕外图片

    • 使用loading="lazy"属性,延迟加载用户未访问到的图片
    • 利用IntersectionObserver``API实现更精细的控制
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      const observer = new IntersectionObserver(entries => {
      entries.forEach(entry => {
      if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;
      observer.unobserve(img);
      }
      });
      });
      document.querySelectorAll('img[src]').forEach(img => {
      observer.observe(img);
      });
  3. 使用现代图片格式

    • 使用WebPAVIF等新一代图片格式,减少文件体积。
    • 优势:支持度高,压缩率显著优于JPEGPNG

优化字体体积

字体优化方法

  1. 优先使用系统字体
    • 如果页面设计不需要自定义字体,使用常见的Web安全字体(如ArialVerdana),它们已经安装在用户的设备上,无需额外下载。
  2. 限制字体家族数量
    • 每个页面最多下载两种字体家族,避免加载过多字体样式。
  3. 压缩字体文件
    • 使用WOFF2格式,这是目前性能最优的字体压缩算法,可显著减少文件体积。
  4. 加载所需字符集
    • 针对特定语言或场景加载所需字符集。例如,英语网站仅需加载拉丁字符集,无需包含希腊或阿拉伯字符。
  5. 设置font-display属性
    • 使用font-display: fallbackfont-display: optional,在网络较慢时优先显示系统字体,确保用户体验流畅。

拆分长页面

将较小的页面拆分为更短的页面,可以减少网络负载。

拆分长页面还可以帮助你改进其他Lighthouse审计,例如避免过多的DOM大小警告。

实现静态资源的浏览器缓存

浏览器缓存可以让返回用户直接从本地加载静态资源(如字体、样式表和脚本),较少服务器请求,提升加载速度。

设置缓存规则

  • Apache:通过.htaccess文件
    1
    ExpiresByType text/css "access plus 1 year"
  • Nginx:通过nginx.conf文件
    1
    2
    3
    location ~* \.(js|css|png|jpg)$ {
    expires 1y;
    }