移动设备的屏幕宽度与像素密度跨度大,单一主图难以同时满足清晰度与体积要求。商品主图位于首屏,还要兼顾加载时机与 CDN 缓存命中。按四个步骤推进即可收敛。

第一步:按断点换构图
窄屏给方图或竖版裁切,宽屏给横版或留白版。构图差异属于 source 的职责,交给 media 条件判断。
<source media="(max-width: 600px)" srcset="cover-square-640.webp">
第二步:同一构图内按像素密度换清晰度
同一份构图再按设备像素比出 1x 与 2x 两套,避免高分屏拿到糊图、普通屏下载超量资源。
<img
src="cover-640.jpg"
srcset="cover-640.jpg 1x, cover-1280.jpg 2x"
width="640" height="640"
alt="商品主图">
第三步:给 WebP 机会,保留兜底
source 自上而下匹配,格式优先的 source 放在前面,末尾 img 保留 jpg 地址作为兜底。
<picture>
<source media="(max-width: 600px)" type="image/webp" srcset="cover-square-640.webp">
<source media="(max-width: 600px)" srcset="cover-square-640.jpg">
<img src="cover-640.jpg" srcset="cover-640.jpg 1x, cover-1280.jpg 2x" width="640" height="640" alt="商品主图">
</picture>
第四步:收口缓存与尺寸
- CDN 缓存键要把 Accept 头纳入 Vary,否则 WebP 会被发给不支持的客户端,或被反向污染;
- img 必须写 width 与 height,避免加载后产生布局跳动;
- 首屏主图不加 loading=”lazy”,需要抢占带宽时补 fetchpriority=”high”;
- 缩略图走独立尺寸,不用 CSS 把大图缩成小图。
验收顺序
- 断点取图片在版式中的实际列宽,不取设备宽度;
- 同一构图的候选宽度成倍差,便于 CDN 命中同一套派生资源;
- WebP 源排在 jpg 源之前,末尾 img 的 src 不带动态参数;
- 在开发者工具的 Network 面板核对实际下载的资源与体积,确认没有重复请求;
- 压缩率与清晰度做一次人工比对,据此定下最终的候选数量。
