真降级必须在资源层切换:用小尺寸原图替代大图或前端动态生成低质缩略图;仅CSS缩放会导致模糊、不省带宽、lazy失效。

直接用 <img> 标签加 CSS 缩放不是降级,是糊图。真降级必须在资源层切换:用小尺寸原图替代大图,或前端动态生成低质缩略图。
为什么不能只用 width/height 或 CSS 缩放
浏览器拉伸像素会模糊、失锐度,尤其文字和线条图;带宽没省——还是下载了整张大图;loading="lazy" 对这种写法基本无效,因为 src 没变,浏览器照常请求原图。
- 错误写法:
<img src="big.jpg" width="120" height="80"> - 错误写法:
<img src="big.jpg" style="width:120px; height:80px"> - 正确思路:要么换 src 为真实小图,要么用
srcset+sizes让浏览器选小图
用 srcset + sizes 实现响应式缩略图降级
这是 HTML 原生最稳妥的降级方式,不依赖 JS,兼容性好(IE11+ 支持 srcset,sizes 需要 polyfill)。
-
sizes必须写,否则浏览器默认按100vw选图,大概率加载过大资源 - 缩略图尺寸建议提前生成好(如
thumb-120.jpg、thumb-240.jpg),别指望浏览器“自动压缩” - 示例:
<img src="thumb-120.jpg" srcset="thumb-120.jpg 120w, thumb-240.jpg 240w, thumb-480.jpg 480w" sizes="(max-width: 480px) 100vw, (max-width: 768px) 50vw, 25vw" width="120" alt="缩略图">
JS 动态替换 src 实现运行时降级
适合已有大图 URL、但想临时降级展示的场景(比如列表页统一用缩略图,点开才加载高清图)。
立即学习“前端免费学习笔记(深入)”;
- 先检查设备像素比:
window.devicePixelRatio > 1.5时可优先加载 @2x 缩略图 - 用
Image实例预加载缩略图,成功后再替换 DOM 中的src,避免空白闪烁 - 失败时 fallback 到占位图或保留原
src,别让缩略图逻辑阻塞主图显示 - 注意:不要在
onload里直接改img.src,会触发二次加载;应改另一个<img>或用data-src中转
Canvas 生成临时缩略图作为兜底方案
当后端没提供缩略图,又不能上传原图时,才启用此方案——它不是“降级”,而是“现场生成”,有性能和兼容成本。
- 必须等
Image.naturalWidth可读后再计算缩放比,否则按 0×0 绘制,canvas 为空白 - iOS Safari 加载相册图片时
files[0].type常为空,得靠文件扩展名判断:name.match(/\.(jpg|jpeg|png|gif)$/i) - EXIF 方向未修正会导致横拍照片竖着显示,需额外解析 EXIF(可用
exif-js或piexifjs) - 生成 JPEG 比 PNG 小 40%~60%,推荐用
canvas.toDataURL('image/jpeg', 0.8)
最容易被忽略的是:缩略图不是“看起来小就行”,而是资源尺寸、加载时机、视觉保真度三者平衡的结果。很多项目卡在“以为 CSS 缩放就是缩略图”,结果首屏加载慢、LCP 差、用户放大看不清细节——这些都不是样式问题,是资源策略错了。



















