思考
在web应用中,我们常常会遇到图片加载过慢的问题,现在市面上的解决方案已经非常成熟了。我这边就先结合前人的思考,谈谈自己的一些想法。如果有什么错误,欢迎指正。
方案列表
CDN
首先说一下最简单的方案,那就是使用CDN。专业的事情交给专业的人,CDN(Content Delivery Network)为网站提供内容分发网络,把图片等静态资源放到CDN上,然后直接使用CDN上的资源。
优点
🚀 提升速度:可以降低自己服务器的压力,同时也可以提升访问速度。
✅ 稳定性强:虽然有时CDN会抽风,但总体上要比自建服务更稳妥一些。
缺点
📝 备案要求:CDN需要备案才能加速国内用户体验。
💰 费用问题:免费额度有限,访问量大时可能需要防盗链等措施来控制成本。
图片转换
图片转换是图片优化的常用手段,通过压缩、格式转换等方式来减少图片体积。
📷 WebP
WebP格式是谷歌推出的一种图片格式,支持有损压缩和无损压缩。有损压缩体积小但会降低图片质量。
🖼️ SVG
SVG是矢量图,可以放大缩小而不会失真。浏览器支持SVG格式,但IE不支持。
🔧 压缩图片
通过降低分辨率、颜色数等方式减少图片体积。优点是节省带宽和存储,提升加载速度。缺点是图片质量降低,且对用户上传图片可能增加开发复杂度。
🌈 雪碧图(CSS Sprite)
雪碧图把多张图片合并成一张,通过CSS的background-position定位,减少请求次数。
优点
🔍 减少请求:减少请求次数,提升访问速度。
缺点
⚠️ 定位麻烦:定位麻烦,图片大小和背景色需要一致。
📉 优势减弱:现在HTTP/2支持多路复用,雪碧图的优势减弱。
预加载和懒加载(lazy loading / pre-load)
预加载和懒加载常用于图片资源加载。
🚀 预加载
提前加载图片并缓存,适用于漫画和视差动画等场景,提升用户体验。
💤 懒加载
等图片出现在用户视野时才加载,适用于图片数量多的场景,如新闻和博客。虽耗费带宽,但能提升用户体验。
渐进式加载(Progressive Loading)
渐进式加载先显示大致轮廓,再逐步变清晰,提升用户体验。
🎨 我博客正在用的方案
js
import sharp from ‘sharp’;
import { globby } from ‘globby’;
import * as fs from ‘fs-extra’;
import * as path from ‘path’;
const PATH = ‘public/assets/images/**/*.{jpg,png}’;
/**
-
处理图片,将其转为渐进式,并替换原文件
-
@param {string} filePath - 输入文件的路径
*/
const updateProgressive = async (filePath)=> {
try {
const dir = path.dirname(filePath);
const ext = path.extname(filePath).toLowerCase();
const baseName = path.basename(filePath, ext);
const newFileName =${baseName}_progressive${ext}
;
const tempFilePath = path.join(dir, newFileName);
if (ext === ‘.jpg’ || ext === ‘.jpeg’) {
await sharp(filePath).jpeg({ progressive: true }).toFile(tempFilePath);
} else if (ext === ‘.png’) {
await sharp(filePath).png({ progressive: true }).toFile(tempFilePath);
} else {
throw new Error(未知格式的图片: ${ext}
);
}await fs.remove(filePath);
await fs.move(tempFilePath, filePath);
console.log(更新成功: ${filePath}
);
} catch (error) {
console.error(更新失败 文件 ${filePath}:
, error);
}
}
export const progressive = async () => {
const list = await globby(PATH)
return list.forEach(async (item) => {
return await updateProgressive(item);
});
};
这玩意的缺点
⚠️ 兼容性问题:目前svg,webp等格式图片是没有办法支持的。
🚧 开发复杂度:需要额外处理图片格式,且需要额外安装依赖。
总结
如果你有更好的解决方案,欢迎留言指出~