图片懒加载与压缩:减少请求与传输体积

FreeGuideOnline 最新 2026-06-15

图片懒加载与压缩

为什么需要优化图片

图片通常是网页中体积最大的资源,占用大量带宽。未优化的图片会直接导致页面加载缓慢、用户体验下降,尤其在移动网络下更为明显。通过懒加载(按需请求)与压缩(减小传输体积),可以显著降低首屏加载时间、节省服务器流量,并提升 Core Web Vitals 等性能指标。

本教程将从零讲解图片懒加载与压缩的核心概念,并提供可直接上手的实现方案,帮助你立即改善网站性能。


图片懒加载

懒加载是什么

懒加载是一种延迟加载策略:只有当图片即将进入浏览器可视区域时,才去加载对应的图片资源。未出现在屏幕范围内的图片不会被请求,从而减少首屏并发请求数和传输体积,加快页面初始渲染。

实现方式一:使用 loading="lazy" 属性

现代浏览器原生支持懒加载,这是最简单的方法。只需在 <img> 标签上添加 loading="lazy" 即可。

<img src="photo.jpg" alt="示例图片" loading="lazy" />

属性值说明

  • lazy:延迟加载图片,直到图片距离视口一定距离时开始加载。
  • eager(默认):立即加载图片,无论是否在视口内。

注意事项

  • 浏览器兼容性:Chrome 77+、Firefox 75+、Edge 79+ 等均支持,Safari 从 15.4 开始支持。对于不支持的浏览器,可配合 JavaScript 方案兜底。
  • 不要对首屏关键图片使用 lazy,否则可能延迟首屏展示,影响 LCP 指标。

实现方式二:使用 Intersection Observer(JavaScript)

当需要更精确的控制或兼容旧浏览器时,可以借助 Intersection Observer API 手动实现懒加载。

核心思路

  1. 将图片的真实地址存储在 data-src 属性中,src 可设置占位图或留空。
  2. 创建一个 Observer 实例,监听目标图片是否进入视口。
  3. 当图片进入视口时,将 data-src 的值赋值给 src,触发加载。
  4. 加载完成后取消监听,避免重复操作。

代码示例

<img class="lazy" data-src="photo.jpg" src="placeholder.jpg" alt="懒加载图片" />
const lazyImages = document.querySelectorAll('img.lazy');

if ('IntersectionObserver' in window) {
  const observer = new IntersectionObserver((entries, obs) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        const img = entry.target;
        img.src = img.dataset.src;
        img.classList.remove('lazy');
        obs.unobserve(img);
      }
    });
  }, {
    rootMargin: '50px 0px', // 提前50px开始加载,提升体验
    threshold: 0.01
  });

  lazyImages.forEach(img => observer.observe(img));
} else {
  // 兜底方案:直接加载所有图片或使用旧式滚动监听
  lazyImages.forEach(img => {
    img.src = img.dataset.src;
  });
}

要点解释

  • rootMargin 可以设置触发偏移,让图片在即将进入视口前就开始加载,避免用户滑动时看到空白。
  • threshold 表示可见比例达到多少时触发回调,一般设为接近 0 即可。
  • 对于不支持 Intersection Observer 的浏览器(如 IE),需要提供降级处理,比如直接加载所有图片。

实践建议

  • 所有非首屏图片均开启懒加载,包括列表、文章正文配图等。
  • 给图片设置明确的宽高属性或使用 aspect-ratio 预留空间,防止加载后页面发生布局跳动,改善 CLS(累积布局偏移)。
  • 对于背景图片懒加载,可通过 JavaScript 监测元素可见性后动态修改 CSS background-image

图片压缩

压缩的核心概念

图片压缩的目的是在可接受的视觉质量下,尽可能减小文件体积。压缩可分为两类:

  • 有损压缩:通过丢弃部分视觉信息来大幅减小体积,会不可逆地损失画质。常用于照片、渐变色丰富的场景。
  • 无损压缩:仅通过优化编码方式减小体积,完全保留原始画质。适合图标、Logo、简单图形等对清晰度要求极高的场景。

选择正确的图片格式

不同的图片格式具有不同的压缩效率和应用场景,选用正确格式本身就能显著减少体积。

格式 压缩类型 透明度支持 典型适用场景
JPEG 有损 不支持 照片、复杂图像、截图
PNG 无损(也可有损) 支持 图标、透明背景图、界面元素
WebP 有损/无损/透明 支持 几乎所有场景,体积比 JPEG/PNG 小 25%~35%
AVIF 有损/无损/透明 支持 新一代高效格式,体积更小,质量更高
SVG 矢量(可无损) 支持 图标、插图、可缩放图形

格式选择建议

  1. 优先使用 WebP 作为主力格式,现代浏览器支持率超过 97%。
  2. 如果需要更优压缩,可考虑 AVIF,但注意 Safari 等兼容性。
  3. 对于矢量图形,优先使用 SVG,它可缩放且文件极小。
  4. 在需要透明度且 WebP 不可用时,使用 PNG
  5. JPEG 仍可作为照片的兜底格式。

压缩工具与方法

手动压缩(开发阶段使用)

  • 在线工具:Squoosh、TinyPNG、JPEGmini。Squoosh 支持 WebP、AVIF 导出,可实时预览质量。
  • 命令行工具
    • imagemagickconvert input.jpg -quality 80 output.jpg
    • cwebp(WebP 官方工具):cwebp -q 80 input.png -o output.webp
  • 图像处理软件:Photoshop(存储为 Web 所用格式)、GIMP 等导出时调节质量参数。

自动化压缩(构建流程集成)

推荐将图片压缩集成到项目构建流程中,避免手动操作。

使用 Webpack 的 image-webpack-loader

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        use: [
          {
            loader: 'file-loader',
          },
          {
            loader: 'image-webpack-loader',
            options: {
              mozjpeg: { progressive: true, quality: 75 },
              optipng: { enabled: true },
              pngquant: { quality: [0.65, 0.8], speed: 4 },
              webp: { quality: 75 }
            }
          }
        ]
      }
    ]
  }
}

使用 Gulp + 插件imagemin 命令行工具也能实现类似效果。

服务端动态压缩

如果用户上传图片,可以在服务器端自动生成压缩版本或多尺寸响应式图片。例如使用 Node.js 的 sharp 库:

const sharp = require('sharp');

sharp('input.jpg')
  .resize(800)
  .webp({ quality: 80 })
  .toFile('output.webp');

可以结合 CDN 服务(如 Cloudinary、Imgix)动态转换图片格式与尺寸,无需自行处理。

响应式图片与压缩结合

利用 <picture>srcset 属性,根据屏幕宽度和像素密度加载不同尺寸的图片,避免在小屏幕上加载大尺寸原图。

<picture>
  <source srcset="photo-large.avif" type="image/avif" media="(min-width: 800px)" />
  <source srcset="photo-medium.avif" type="image/avif" media="(min-width: 400px)" />
  <source srcset="photo-large.webp" type="image/webp" media="(min-width: 800px)" />
  <source srcset="photo-medium.webp" type="image/webp" media="(min-width: 400px)" />
  <img src="photo-small.jpg" alt="响应式图片" loading="lazy" />
</picture>

这样浏览器会按优先级选择支持的格式和合适的尺寸,既压缩了体积,又兼顾了清晰度。


懒加载与压缩的组合策略

前端整体加载流程

  1. HTML 中使用 loading="lazy" 或 data-src 占位,并预设尺寸占位元素。
  2. 构建时压缩所有图片,生成多种格式(JPEG/WebP/AVIF)和多种尺寸。
  3. 通过 <picture> + srcset 提供响应式资源。
  4. 浏览器仅加载进入视口的图片,并自动拣选最优格式。
  5. 首屏关键图片(如Hero Banner)使用 eager 加载,避免延迟。

性能收益评估

  • 请求数量:懒加载可减少 50~70% 的首屏图片请求,尤其适合长页面。
  • 传输体积:WebP/AVIF 相比 JPEG 可节省 30~50%,加上多尺寸响应式可再减半。
  • 指标提升:LCP 优化,CLS 降低,首屏载入时间明显缩短。

注意事项

  • 不要过度压缩导致图片失真,建议采用 75~85% 的质量系数,并使用实际人眼评估。
  • 为每个 img 标签定义 widthheight 属性,或使用 CSS aspect-ratio,是防止布局偏移的关键。
  • 对于首屏大图,可考虑使用渐进式 JPEG 或先显示低质量模糊预览(LQIP),提升感知速度。

通过懒加载与压缩的组合应用,你可以用最简单的手段获得巨大的性能回报。推荐从当前项目入手,先启用原生懒加载,再逐步引入自动化压缩和现代格式,让网页图片既轻又快。