浅谈前端性能优化之图片优化

381 阅读7分钟

本文首发微信公众号:前端徐徐。欢迎关注,获取更多前端技能。

前言

在现代网站开发中,图片往往是页面加载速度的主要瓶颈之一。随着高分辨率设备和丰富媒体内容的广泛使用,优化图片的加载和呈现变得越来越重要。本文将探讨各种图片优化技术,帮助开发者在保持视觉质量的同时显著提升网站性能。

1. 选择适当的图片格式

image.png

选择合适的图片格式是优化图片的第一步。不同格式在压缩方式、支持的特性以及适用场景上各有优劣。下面是 4 种常见图片格式的对比:

  • JPEG (Joint Photographic Experts Group)
    • 优点: 适合照片等复杂图像,可以在较小文件大小下保持良好的图像质量
    • 缺点: 不支持透明度,对于文字和图形等锐利边缘的图像效果较差
    • 使用场景: 照片、复杂的图像
  • PNG (Portable Network Graphics)
    • 优点: 支持透明度,适合需要透明背景的图像,对于文字和图形等有锐利边缘的图像效果好
    • 缺点: 文件大小通常大于 JPEG
    • 使用场景: logo、图标、需要透明背景的图像
  • WebP
    • 优点: 同等质量下比 JPEG 和 PNG 文件更小,支持有损和无损压缩,支持透明度
    • 缺点: 旧版浏览器兼容性问题
    • 使用场景: 现代网站的通用图片格式
  • SVG (Scalable Vector Graphics)
    • 优点: 矢量图形,可无损缩放,文件小,适合图标和 logo
    • 缺点: 不适合复杂的图像
    • 使用场景: 图标、logo、简单的图形

当然,图片格式还有非常多,不过上面四种图片应该是应用最多的图片格式,只要知道了他们的优缺点,肯定对前端的一些图片优化的场景有帮助。

2. 压缩图片

压缩图片是优化图片的关键步骤,通过减少图片的文件大小,可以显著提升网页的加载速度。

  • 有损压缩: 通过删除部分图像数据来减小文件大小,如 JPEG 压缩。虽然会有一定程度的质量损失,但在合适的压缩比下,肉眼难以察觉质量变化。
  • 无损压缩: 在不丢失图像数据的前提下减小文件大小,如 PNG 压缩。这种方法通常适用于对图像质量要求较高的场景。
工具推荐
  • TinyPNG: 在线压缩工具,能够高效地压缩 PNG 和 JPEG 文件,保持良好的图像质量。
  • ImageOptim: 一款 Mac 平台上的桌面应用,支持多种图片格式的压缩与优化。
  • gulp-imagemin: 适用于自动化构建流程的 Gulp 插件,可以在项目构建过程中自动压缩图片。

3. 响应式图片

响应式图片是针对不同设备和屏幕尺寸提供不同分辨率的图片,确保在各种环境下都能高效加载合适的图片资源。

  • srcset 属性: 允许在 <img> 元素中定义多个图片源,浏览器会根据设备分辨率和屏幕宽度选择最合适的图片。这种方法既能节省带宽,又能保证图片质量。
<img srcset="small.jpg 300w, medium.jpg 600w, large.jpg 900w"
     sizes="(max-width: 300px) 300px, (max-width: 600px) 600px, 900px"
     src="fallback.jpg" alt="responsive image">

上面的代码大概工作步骤:

  1. 浏览器首先检查 sizes 属性来确定在当前视口下图片将被渲染的大小。
  2. 然后,它会查看 srcset 属性中列出的图片,选择一个最接近但略大于所需大小的图片。
  3. 如果浏览器不支持这些特性,它会回退到使用 src 属性中指定的图片。
  • ** 元素**: 提供更高级的响应式图片支持。通过 <picture> 元素,可以根据不同的屏幕尺寸或其他条件提供特定的图片源,从而进一步优化加载效果。
<picture>
  <source media="(min-width: 800px)" srcset="large.jpg">
  <source media="(min-width: 400px)" srcset="medium.jpg">
  <img src="small.jpg" alt="responsive image">
</picture>

上面的代码大概工作步骤:

  1. 浏览器会按照 <source> 元素的顺序进行评估。
  2. 它会使用第一个媒体查询条件匹配的 <source> 元素。
  3. 如果没有 <source> 元素匹配,或者浏览器不支持 <picture>,则会使用 <img> 元素。

4. 延迟加载

延迟加载是一种只在图片进入视口时才加载的技术,能够显著减少页面首次加载的资源消耗,提升用户体验。

  • Intersection Observer API: 利用这一 API,可以高效监测图片元素是否进入视口,并在需要时加载图片。相比传统的滚动事件监听,Intersection Observer 提供了更高效和准确的实现方式。
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const image = entry.target;
      image.src = image.dataset.src;
      observer.unobserve(image);
    }
  });
});

document.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));
  • lazysizes 库: 是一个流行的延迟加载库,简化了延迟加载的实现过程,并提供了多种配置选项以满足不同的需求。
<img data-src="image.jpg" class="lazyload" alt="lazy loaded image">

5. CDN 加速

image.png 内容分发网络 (CDN) 是通过将图片资源分布在全球各地的服务器上,从而加快图片加载速度的技术。当用户请求图片时,CDN 会将请求路由到距离用户最近的服务器,从而减少延迟,提高加载速度。CDN 还可以缓解源服务器的压力,提升网站的可扩展性和稳定性。 关键步骤如下:

  • 选择CDN服务商 选择一个可靠的、覆盖范围广的CDN服务提供商。
  • 配置CDN 设置自定义域名,配置HTTPS,选择合适的节点。
  • 优化图片 使用现代格式(如WebP),压缩图片,设置自动调整大小。
  • 设置缓存策略 配置适当的缓存时间和刷新机制。
  • 实施前端优化 使用响应式图片技术,实施懒加载,预连接到CDN。
  • 监控和调整 定期检查CDN性能,根据数据分析调整策略。

6. CSS Sprites

CSS Sprites 是将多个小图片合并为一张大图片的技术,通过减少 HTTP 请求次数来优化页面加载性能。

  • 实现方法: 将多个图标或背景图片合并成一张大图片,然后通过 CSS 的 background-position 属性来显示所需的部分。这种方法特别适合需要加载大量小图标或背景图的场景。
.icon {
  background-image: url('sprites.png');
  width: 16px;
  height: 16px;
}
.icon-home { background-position: 0 0; }
.icon-user { background-position: -16px 0; }

7. 字体图标或 SVG 图标

使用字体图标或 SVG 图标可以进一步减少图片文件的加载需求,并提供更高的灵活性和可扩展性。

  • 字体图标: 例如 Font Awesome 等图标库,提供了丰富的矢量图标,可以通过简单的 CSS 类名来使用。
  • SVG 图标: 可以直接嵌入 HTML 文档中,或通过外部链接引用。SVG 图标不仅体积小,而且可以通过 CSS 和 JavaScript 进行动态操作。
<!-- 字体图标 -->
<i class="fas fa-user"></i>

<!-- SVG图标 -->
<svg viewBox="0 0 100 100" width="20" height="20">
  <path d="M50 0 L100 100 L0 100 Z" />
</svg>

8. 缓存策略

设置适当的缓存策略可以显著减少图片的重复加载次数,提高页面加载速度和用户体验。

  • Cache-Control 头的设置: 通过设置 HTTP 头中的 Cache-Control,可以控制浏览器缓存图片的时间。对于静态图片资源,建议设置较长的缓存时间。
# Nginx配置示例
location ~* \.(jpg|jpeg|png|gif|ico)$ {
  expires 30d;
  add_header Cache-Control "public, no-transform";
}

9. 预加载关键图片

在页面加载时提前请求和加载关键图片资源,可以减少首次加载的延迟。

  • **使用 **: 通过在页面中添加 <link rel="preload"> 标签,可以在页面解析和渲染之前预加载关键图片资源,从而优化用户首次访问的体验。
<link rel="preload" as="image" href="important-image.jpg">

10. 移除不必要的元数据

图片中常常包含一些不必要的元数据(如 EXIF 数据),这些数据可能会增加文件大小,但对展示并无实际作用。

  • 工具推荐: 使用 ExifTool 等工具可以轻松移除图片中的所有元数据,从而进一步减小文件大小,提升加载速度。
exiftool -all= image.jpg

结语

图片优化是一项多层次的工作,涉及选择合适的格式、压缩、响应式设计、延迟加载、CDN 加速等多个方面。通过合理地组合这些技术,开发者可以在不牺牲图片质量的前提下,显著提升网站的加载性能和用户体验。方案很多,根据场景选择合适的方案才是最重要的,总有一款适合你。

原文链接

mp.weixin.qq.com/s/ZdalnHN7g…