双倍图(2x image)是为高DPI屏幕提供物理尺寸翻倍的图片资源,使图像在2倍设备像素比下仍清晰;需通过<img>的srcset="xxx.png 1x, xxx@2x.png 2x"显式声明,浏览器依dpr自动选择,<source>中写2x无效。

什么是双倍图(2x image)
双倍图本质是为高 DPI 屏幕(如 Retina、Windows HiDPI)提供更高分辨率的图片,让图像在物理像素密度翻倍的设备上依然清晰。浏览器不会自动“放大”普通图来适配——它需要你明确告诉它:这张图有 2x 版本可用。
<picture> 本身不直接处理「倍率」,它靠 srcset 和 sizes 配合 <source> 的 media 或 type 来做响应式选择;真正触发 2x 加载的是 srcset 中带 2x 描述符的语法。
用 <source> + srcset="... 2x" 实现双倍图
最常用且兼容性好的方式:在 <source> 或 <img> 上用 srcset 列出不同倍率的资源,浏览器按设备像素比(dpr)自动选。注意:<source> 的 srcset 只支持宽度描述符(100w),不支持 2x;所以双倍图逻辑必须落到 <img> 标签自身。
-
<picture>用来做格式切换(如 WebP / AVIF fallback)或宽高比切换(如横屏/竖屏图),不是双倍图的必需容器 - 真要兼顾格式 + 倍率,得在
<source>里用srcset(仅宽描述符)+sizes,再在<img>里补上srcset(含2x)和src(兜底) - 常见错误:把
2x写进<source>的srcset—— 浏览器会忽略它,降级到<img>的src
<picture>
<source type="image/webp" srcset="hero-800w.webp 1x, hero-1600w.webp 2x">
<source type="image/jpeg" srcset="hero-800w.jpg 1x, hero-1600w.jpg 2x">
<img src="hero-800w.jpg"
srcset="hero-800w.jpg 1x, hero-1600w.jpg 2x"
alt="Hero">
</picture>
为什么不能只靠 CSS background-image + background-size
CSS 的 background-image 无法让浏览器感知「这是张双倍图」,background-size: cover 只缩放渲染区域,不触发资源选择。即使你写 @media (-webkit-min-device-pixel-ratio: 2) 切换背景图,也绕不开手动 JS 检测或重复请求问题。
立即学习“前端免费学习笔记(深入)”;
- 无法利用浏览器原生的资源优先级调度(
<img>的双倍图会在 HTML 解析阶段就预加载) - 无法被
loading="lazy"或decoding="async"控制 - 无障碍属性(
alt)、SEO、打印样式全部失效
实际部署要注意的三个细节
双倍图不是“只要放两张图就完事”,容易在真实项目中翻车:
- 文件名别只靠后缀区分,比如
icon@2x.png和icon.png—— 某些 CDN 或构建工具会把@2x当作无效字符过滤或重命名 - 确保 2x 图的物理尺寸确实是 1x 图的 2 倍(比如 1x 是 400×300,2x 就得是 800×600),否则
2x描述符会误导浏览器,导致模糊或拉伸 - 服务端开启
Cache-Control: immutable很重要——因为 1x 和 2x 是不同 URL,但内容强相关,一旦缓存错乱,用户换设备后可能长期看到低清图
真正麻烦的从来不是怎么写标签,而是图源管理、构建流程是否能稳定输出匹配的尺寸对、以及 CDN 是否正确识别 srcset 中的资源路径。



















