网站图片懒加载,降低服务器带宽消耗
网站图片懒加载的核心思路是:首屏只加载用户马上能看到的图片,其余图片等滚动到附近再请求,从而减少一次性下载量、降低服务器带宽消耗。它对图片较多的资讯站、商城列表页和博客效果最明显,配置本身不复杂,零基础用户按下面的步骤就能落地。
## 先确认你的页面是否真的需要懒加载
懒加载不是所有网站的必选项。如果站点本身图片很少、单页总大小不到几百 KB,改动收益有限,可以先不做。
适合优先处理的场景包括:
- 列表页每页展示十几张以上图片
- 图片单张体积偏大,首屏加载慢
- 服务器带宽经常跑满,或 CDN 流量费用偏高
- 移动端访问占比高,用户对加载速度敏感
需要提前准备的东西不多:能编辑主题模板或安装插件的站点后台权限、一份可回滚的备份,以及浏览器开发者工具用来验证结果。
## 用原生 loading 属性做最简懒加载
现代浏览器已经原生支持懒加载,只需要给图片标签加上 `loading="lazy"`,不需要写 JavaScript。
找到输出图片的模板位置。以常见 PHP 站点为例,图片标签通常长这样:
```html
```
改成:
```html
```
几个关键点:
- `loading="lazy"` 表示延迟加载,浏览器会在图片接近视口时才发起请求
- 首屏主图建议用 `loading="eager"`,避免关键图片被延迟
- 补上 `width` 和 `height` 能减少滚动时的布局跳动
如果站点用 WordPress,不想改模板,可以在主题的 `functions.php` 里加过滤,或用插件批量给内容图片补属性。宝塔面板用户可进入“文件”,定位到站点目录下的主题文件再编辑,改前先复制一份原文件。
## 图片多、结构复杂的页面用 IntersectionObserver
当图片是动态插入、或需要更精细控制时,原生属性可能不够用,可以用 `IntersectionObserver` 监听图片是否进入视口。
思路是把真实地址放在 `data-src`,等进入视口再赋给 `src`:
```html
```
```javascript
const imgs = document.querySelectorAll('img.lazy');
const io = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
io.unobserve(img);
}
});
});
imgs.forEach((img) => io.observe(img));
```
这段脚本放到主题的 JS 文件里,或通过后台的“自定义代码”位置引入。加载后滚动页面,未进入视口的图片不应出现在网络请求里。
## 配合 Nginx 和 CDN 检查是否真的省了带宽
懒加载只是减少请求时机,图片本身的大小仍会消耗带宽。建议同时做两件事:
- 用 Nginx 开启图片压缩或配合 CDN 做 WebP 转换
- 检查缓存头,避免图片被反复回源
在 Nginx 站点配置里确认静态资源缓存,例如:
```nginx
location ~* \.(jpg|jpeg|png|gif|webp)$ {
expires 30d;
add_header Cache-Control "public";
}
```
改完执行 `nginx -t` 检查语法,通过后再 `nginx -s reload` 重载。宝塔面板用户可在“网站 - 设置 - 配置文件”里修改,保存前先备份。
## 避坑与效果验证
**常见坑一:首屏图片也加了 lazy。** 这会让用户先看到空白,反而变慢。首屏关键图保持默认加载。
**常见坑二:只加属性没设尺寸。** 图片陆续加载时页面高度变化,滚动位置跳动,体验很差,务必补 `width`、`height` 或 CSS 占位。
**常见坑三:JS 懒加载和原生属性同时用。** 可能造成重复请求或图片不显示,选一种方式即可。
验证方法是打开浏览器开发者工具,切到 Network 面板,刷新页面并缓慢滚动。未滚动到的图片不应出现在请求列表,滚动后再逐个出现,说明生效。再对比改动前后的首屏传输量,通常能看到明显下降。
如果站点同时做图片压缩和懒加载,带宽消耗的下降会更稳定。遇到图片不显示时,优先检查 `src` 是否被正确赋值、脚本是否被缓存,清一次缓存再测。
```
改成:
```html
```
几个关键点:
- `loading="lazy"` 表示延迟加载,浏览器会在图片接近视口时才发起请求
- 首屏主图建议用 `loading="eager"`,避免关键图片被延迟
- 补上 `width` 和 `height` 能减少滚动时的布局跳动
如果站点用 WordPress,不想改模板,可以在主题的 `functions.php` 里加过滤,或用插件批量给内容图片补属性。宝塔面板用户可进入“文件”,定位到站点目录下的主题文件再编辑,改前先复制一份原文件。
## 图片多、结构复杂的页面用 IntersectionObserver
当图片是动态插入、或需要更精细控制时,原生属性可能不够用,可以用 `IntersectionObserver` 监听图片是否进入视口。
思路是把真实地址放在 `data-src`,等进入视口再赋给 `src`:
```html
```
```javascript
const imgs = document.querySelectorAll('img.lazy');
const io = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
io.unobserve(img);
}
});
});
imgs.forEach((img) => io.observe(img));
```
这段脚本放到主题的 JS 文件里,或通过后台的“自定义代码”位置引入。加载后滚动页面,未进入视口的图片不应出现在网络请求里。
## 配合 Nginx 和 CDN 检查是否真的省了带宽
懒加载只是减少请求时机,图片本身的大小仍会消耗带宽。建议同时做两件事:
- 用 Nginx 开启图片压缩或配合 CDN 做 WebP 转换
- 检查缓存头,避免图片被反复回源
在 Nginx 站点配置里确认静态资源缓存,例如:
```nginx
location ~* \.(jpg|jpeg|png|gif|webp)$ {
expires 30d;
add_header Cache-Control "public";
}
```
改完执行 `nginx -t` 检查语法,通过后再 `nginx -s reload` 重载。宝塔面板用户可在“网站 - 设置 - 配置文件”里修改,保存前先备份。
## 避坑与效果验证
**常见坑一:首屏图片也加了 lazy。** 这会让用户先看到空白,反而变慢。首屏关键图保持默认加载。
**常见坑二:只加属性没设尺寸。** 图片陆续加载时页面高度变化,滚动位置跳动,体验很差,务必补 `width`、`height` 或 CSS 占位。
**常见坑三:JS 懒加载和原生属性同时用。** 可能造成重复请求或图片不显示,选一种方式即可。
验证方法是打开浏览器开发者工具,切到 Network 面板,刷新页面并缓慢滚动。未滚动到的图片不应出现在请求列表,滚动后再逐个出现,说明生效。再对比改动前后的首屏传输量,通常能看到明显下降。
如果站点同时做图片压缩和懒加载,带宽消耗的下降会更稳定。遇到图片不显示时,优先检查 `src` 是否被正确赋值、脚本是否被缓存,清一次缓存再测。