前端图片优化
序号 | 名称 |
---|---|
1 | 骨架屏(Skeleton Screens)与占位图 |
2 | 使用 img 标签的 sizes 属性 |
3 | 图片懒加载 (Lazy Loading) |
4 | 预加载关键图片 |
5 | 利用浏览器缓存策略(nginx 协商缓存 - Cache-Control) |
6 | 使用 Fetch API 加载 Blob 图片 |
7 | 使用 Intersection Observer API |
8 | 使用 Caches API |
9 | 响应式图片处理(使用 picture 元素配合 source 元素) |
10 | 进行图片压缩和优化- 如 WebP 图片格式 |
11 | HEIC 图片解码(wasm WebWorker) |
12 | canvas 优化 - 直接使用 rgba 绘制 |
13 | webgl 优化(GPU 加速) |
使用 img 标签的 sizes 属性
在响应式网页设计中,使用<img>
标签的sizes
属性是一种优化图片加载、提升页面性能的关键技术。它允许开发者为不同的屏幕尺寸指定最合适的图片资源,确保用户在任何设备上都能获得最佳的视觉体验,同时避免不必要的数据传输。
基本概念
sizes
属性用于指定图片在不同布局条件下的显示宽度,与srcset
属性配合使用。srcset
属性定义了一组图片资源及其各自的宽度描述符(例如,500w
表示图片宽度为 500 像素)。浏览器会根据sizes
属性给出的条件,选择最合适的图片资源加载。
使用方法
定义 srcset: 在
img
标签中使用srcset
属性,列出不同分辨率的图片资源及其对应的宽度描述符。设置 sizes: 通过
sizes
属性指定不同视口宽度下图片应占的最大宽度。可以使用媒体条件(如min-width
或max-width
)来定义这些规则。指定默认 src: 为了向后兼容不支持
srcset
和sizes
属性的浏览器,还需要使用src
属性指定一个默认的图片资源。
示例代码
假设有一个网站布局,在屏幕宽度小于 600px 时,图片应占满整个屏幕宽度;在屏幕宽度介于 600px 到 900px 之间时,图片应占屏幕宽度的一半;在屏幕宽度超过 900px 时,图片宽度固定为 450px。相应的img
标签代码如下:
<img
src="default.jpg"
srcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w"
sizes="(max-width: 600px) 100vw, (max-width: 900px) 50vw, 450px"
alt="示例图片"
/>
工作原理
- 当浏览器解析到
img
标签时,它会查看设备的屏幕宽度,并与sizes
属性中定义的条件进行匹配。 - 根据匹配结果,浏览器会从
srcset
中选择一个最接近所需宽度的图片资源加载。如果有多个候选,浏览器会选择最接近且稍微大一点的图片,以避免加载过小而影响图片质量的资源。 - 如果浏览器不支持
srcset
和sizes
,则会回退到src
属性指定的图片资源。
优势
- 性能优化: 通过加载与显示尺寸最匹配的图片,减少不必要的数据传输,加快页面加载速度。
- 用户体验: 确保在各种设备和屏幕尺寸上都能获得最佳的视觉效果。
- 灵活性: 通过媒体查询和宽度描述符,提供了一种非常灵活的图片资源管理方式,允许精细控制图片在不同条件下的选择逻辑。
结合使用srcset
和sizes
属性,可以显著提高响应式网站的性能和用户体验,是现代前端开发中不可或缺的技术之一。
图片懒加载 (Lazy Loading)
图片懒加载(Lazy Loading)是一种优化网页加载时间和性能的技术,它通过延迟加载页面上的非关键图片来实现。具体来说,只有当用户滚动到页面的某个部分,使得这些图片即将进入视口(Viewport)时,这些图片才开始加载。这种策略减少了初次页面加载时的请求数量,从而加快了首屏加载速度,并减少了未被立即查看内容的数据传输,节省了用户的数据使用量。
懒加载的实现方式
使用原生 HTML 属性
HTML5 引入了一个非常简单的懒加载实现方式:loading
属性。只需要在img
标签上设置loading="lazy"
,浏览器就会自动延迟加载这些图片,直到它们接近进入视口。
<img src="example.jpg" loading="lazy" alt="示例图片" />
这种方法的优点是实现简单,无需任何额外的 JavaScript 代码。但是,它的缺点是并不是所有的浏览器都支持loading="lazy"
属性,尽管主流的现代浏览器都已经开始支持。
使用 JavaScript
在loading="lazy"
属性得到广泛支持之前,懒加载主要通过监听滚动事件并计算图片位置来实现。这种方法虽然兼容性好,但实现较为复杂,需要考虑性能优化(例如,防抖或节流滚动事件处理函数)。
- 监听滚动事件: 在
window
对象上添加scroll
事件监听器。 - 计算图片位置: 在事件处理函数中,计算每张图片相对于视口的位置。
- 加载图片: 当图片即将进入视口时,通过将图片的
data-src
属性(通常用于暂存图片真实 URL 的自定义属性)的值赋给src
属性,触发图片加载。
使用 Intersection Observer API
Intersection Observer API
提供了一种性能更优的方式来实现懒加载。通过创建一个IntersectionObserver
对象来观察目标元素是否进入了父容器(或视口)的某个区域内,从而避免了监听滚动事件和手动计算元素位置。
- 创建
IntersectionObserver
实例: 在回调函数中,判断目标元素是否进入视口,如果是,则加载图片。 - 观察目标元素: 将需要懒加载的图片作为观察目标。
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.getAttribute("data-src");
observer.unobserve(img); // 图片加载后取消观察
}
});
});
document
.querySelectorAll("img[data-src]")
.forEach((img) => observer.observe(img));
懒加载的优点
- 提高性能: 减少初次页面加载的时间,提升用户体验。
- 节省资源: 减少未查看内容的数据传输,为用户和服务器节省资源。
- 搜索引擎优化(SEO): 合理使用懒加载不会对 SEO 造成负面影响。尤其是原生的
loading="lazy"
,被搜索引擎更好地理解和支持。
注意事项
- 兼容性: 对于不支持
loading="lazy"
或Intersection Observer API
的浏览器,应提供回退方案。 - SEO: 对于对 SEO 非常重要的图片,慎用懒加载,或确保搜索引擎能够索引到这些图片。
- 用户体验: 懒加载的实现不应影响用户的正常浏览体验,避免出现明显的加载延迟或布局抖动。
预加载关键图片<link rel="preload" as="image">
在前端性能优化中,预加载关键资源是一个重要的策略,尤其是对于影响页面加载速度的大型图片或关键视觉元素。使用<link rel="preload">
标签预加载图片,可以显著改善用户的浏览体验,确保重要的图片能够尽快地展示给用户。这个方法通过告诉浏览器页面加载时优先获取指定的资源,而不是等到浏览器解析到相应的资源链接时才开始下载。
使用<link rel="preload">
预加载图片
<link rel="preload">
是一个 HTML 标签,用于指定浏览器应该预加载的资源。当使用as="image"
属性时,它告诉浏览器预先加载指定的图片资源。这种预加载对于改善页面的首次绘制时间(First Paint)和首次有内容的绘制时间(First Contentful Paint)尤为关键。
语法示例
<link rel="preload" href="important-image.jpg" as="image" />
在<head>
部分添加上述标签,可以确保important-image.jpg
被优先加载,即使在 HTML 文档的后续部分才使用到这个图片。
为什么使用图片预加载
- 提高性能: 预加载可以确保关键图片在 HTML 解析过程中尽早开始下载,减少了页面完全加载所需的时间。
- 改善用户体验: 对于用户视觉上非常重要的图片,如页面顶部的 banner 图或关键的产品图片,预加载可以确保它们能够快速显示,减少用户的等待时间。
- 更好的资源管理: 预加载提供了一种机制,允许开发者更精确地控制资源的加载顺序和时机。
最佳实践
- 优先考虑关键资源: 只预加载对用户体验影响最大的图片。过多的预加载可能会浪费带宽,尤其是对于移动用户而言。
- 限制预加载数量: 避免同时预加载过多资源,以免占用过多的网络带宽和资源,影响到其他资源的加载。
- 使用媒体查询优化: 通过
media
属性,可以根据设备的屏幕大小或分辨率条件性地预加载图片,优化跨设备体验。html<link rel="preload" href="large-hero.jpg" as="image" media="(min-width: 600px)" />
- 考虑浏览器兼容性: 尽管
<link rel="preload">
在现代浏览器中得到了广泛支持,但仍有一些旧版本浏览器不支持。为这些用户提供回退方案或保证网页也能在不预加载的情况下正常使用。
总结
通过合理使用<link rel="preload">
标签来预加载图片,可以在不牺牲用户体验的情况下优化页面加载性能。这个技术使得开发者可以更精确地控制页面加载过程中的资源优先级,确保关键视觉元素能够快速呈现给用户。