先记住这个答案
srcset 给浏览器一组同内容、不同分辨率的图片。1x、2x 这类密度描述符适合图片在布局中宽度基本固定的场景;浏览器可按像素密度选择。400w、800w 描述的是资源固有宽度,浏览器还需要 sizes 告知预计显示宽度,再结合 DPR 估算合适候选。最终选择权在浏览器,不能把 srcset 当成“命中某个视口就严格下载某个文件”的规则。
x描述符表示候选的像素密度w描述符表示图片固有宽度w候选要配合sizes声明显示宽度- 浏览器可结合环境选择合适候选
固定显示宽度:用密度候选
例如头像在页面中始终显示为 80 个 CSS 像素宽,可以准备 80 像素和 160 像素两份资源。高 DPR 屏幕需要更多设备像素,浏览器通常会倾向更高分辨率版本。这里无需知道页面视口是 390 还是 1440 像素,因为头像本身宽度相对固定。
<img
src='/avatar-80.png'
srcset='/avatar-80.png 1x, /avatar-160.png 2x'
width='80'
height='80'
alt='用户头像'
>src 仍提供默认资源和兼容回退;在密度描述符场景中,它也可作为相当于 1x 的候选。width、height 帮浏览器预留布局空间,减少加载前后的跳动。这里的 2x 不代表 CSS 把图片显示成两倍宽,而是同样显示面积里使用更多源像素。
宽度会变:用 w 加 sizes
文章封面在窄屏几乎占满视口,在宽屏则只占内容栏的一半。此时单靠 1x、2x 无法说明图片到底显示多宽。给资源写真实固有宽度,例如 400w 和 800w,再用 sizes 描述各视口下的预计布局宽度。浏览器据此把资源宽度换算成有效像素密度。
<img
src='/cover-800.jpg'
srcset='/cover-400.jpg 400w, /cover-800.jpg 800w'
sizes='(max-width: 600px) 100vw, 50vw'
alt='文章封面'
>视口 500 CSS 像素时,第一条条件预计显示宽度约 500 CSS 像素;若 DPR 为 2,理想源宽接近 1000 像素,现有候选里 800w 可能更合适。浏览器也会考虑自身的资源选择策略,所以这个数字只是解释计算思路,不保证每次都选同一 URL。若 sizes 写成与实际 CSS 布局差很多的值,浏览器就可能下载过大或过小的资源。
哪些事情 srcset 不负责
srcset 的这两种模式主要用于分辨率切换:展示相同内容的不同尺寸文件。想在手机端换一个裁剪构图,或按格式支持情况提供 AVIF、WebP 等来源,应考虑 <picture> 与 <source>。不能把 w 和 x 候选混在同一套描述符中,也不要把宽度描述符写成与图片真实像素宽度不符的数字。
浏览器可能在缩放、设备旋转、网络状况改变后重新评估候选。调试时用开发者工具查看实际加载的资源和元素的 currentSrc,不要只读取 HTML 中的 src 就断言最终图片。srcset 是向浏览器提供候选和提示,图片是否合适还取决于真实布局与文件质量。
容易答错的地方
- 把 400w 当成 400px 断点
400w描述资源的固有宽度,不是媒体条件。视口 400px 时可能选更大资源,视口更宽时也可能因布局较窄而选小资源。- 认为 sizes 控制 CSS 显示尺寸
sizes告诉浏览器预估的资源选择宽度,不负责真正给元素设置布局宽度。元素最终多宽仍由 CSS 和 HTML 尺寸规则决定,两者应保持一致。
面试官还会怎么问?
固定 80px 头像还需要写 sizes 吗?
使用 1x、2x 密度描述符时,通常不需要 sizes;它主要和 w 宽度描述符配合,告诉浏览器候选对应的布局槽宽。
为什么 DPR 为 2,却没选 2x 候选?
浏览器有自己的资源选择策略,也可能使用缓存或考虑网络条件。先确认资源描述符、布局宽度和实际加载记录,再判断是否有问题。
怎样知道浏览器最后用了哪张图?
查看图片元素的 currentSrc 或开发者工具网络记录。src 是默认地址,不一定是当前实际显示的候选 URL。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。