srcset写着1920w,服务器给的是同一张140宽的图

srcset写着1920w,服务器给的是同一张140宽的图
张文保 更新 29 分钟阅读 1,806 阅读
本文目录
  1. 你在HTML里写下的那个宽度,谁会去核对?
  2. 这和alt写错不是一回事
  3. 这次量了什么?尺子先自己过一遍
  4. 先证明这把尺子测得准,也测得出反例
  5. 两次尺子失效,都是自己先撞上的
  6. SVG必须整批剔除
  7. 122个站的首页,图片对浏览器说了些什么?
  8. 写了的那些数,有多少压根不算数
  9. 看起来像bug但其实没事的那一类
  10. srcset里那五个档位,是五张图吗?
  11. 把一组档位整个下下来,会看到什么
  12. 浏览器拿到这份清单会怎么办
  13. 为什么偏差全是“说大了”,一条“说小了”都没有?
  14. 所以中招的几乎都是小图标
  15. 换一家图片服务,这个数就准了吗?
  16. width和height写错,到底会不会跳?
  17. 那35%的绝对值偏差,是另一笔账
  18. 这两个数到底该填什么
  19. 扩展名写.jpg,送来的是WebP,这算问题吗?
  20. 顺手撞出来的一件事
  21. 还有16张图,声明了尺寸却根本取不回来
  22. 自己站上怎么查,按什么顺序修?
  23. 三件不值得做的事
  24. 这次测量没做到的几件事
  25. 常见问题解答
  26. srcset的w描述符写错了,Google会因此降权吗?
  27. 我的站用Shopify,需要担心这件事吗?
  28. width和height属性不是早就不用了吗?
  29. 那23.5%一个尺寸都没写的图,是不是都得补上?
  30. 怎么知道我用的图片CDN会不会在原图不够时放大?
  31. 扩展名跟真实格式不符,会影响图片被搜索引擎收录吗?
  32. 如果只能改一处,改哪个?
  33. 权威参考资料
摘要:把122个海外品牌站首页的10641张图片挨个下下来读文件头,拿到1353条对账记录。srcset里那个w描述符,可对账的927条里有12.8%大于文件的真实宽度,中位数差1.7倍、最大差14倍;反过来说小了的只有3条。bellroy的导航图列了320w到1920w五个档位,五个地址下回来是同一张140像素宽的图。30.3%的站至少有一处width或height写成了浏览器根本不认的值——百分比、小数、空字符串。

bellroy.com的首页导航里有一段再标准不过的响应式图片写法:一个srcset,列了320w、640w、960w、1280w、1920w五个档位,配一句sizes="100vw"。教科书上就是这么教的。

我把这五个地址挨个下下来,从文件头里读它们的真实宽度。五张图,都是140像素宽。同一张。

这不是抽样撞上的巧合。同一个站另外两组导航图,也是五档全部返回同一张;换到govee,一组srcset排了15个档位、从200w一直写到3000w,真正下回来的只有两种宽度。

这件事的麻烦之处在于,页面上什么都看不出来。图片正常显示,控制台不报错,Lighthouse不会因此扣分,PageSpeed也照样给你一个体面的分数。唯一的后果是:在一块2倍屏上,浏览器以为自己挑了张1920宽的图,结果拿到的是140宽的那张,放大十几倍糊在屏幕上——而它至死都不知道自己被骗了。

你在HTML里写下的那个宽度,谁会去核对?

响应式图片这套机制的前提,是浏览器不去下载图片就得决定下载哪一张。这不是设计上的偷懒,是逻辑上的必然:如果要先把候选图都下下来量一遍再挑,那挑不挑就没意义了。

所以HTML规范给了它一个替代品——你自己报。srcset里每个地址后面那个1920w,规范管它叫宽度描述符,语义是这个文件的固有宽度是1920像素(这套写法的完整分工,MDN的响应式图片指南讲得比规范易读)。浏览器把它当作事实收下,配合sizes算出的显示宽度和设备像素比,选出第一个够用的档位。

widthheight属性是同一个逻辑的另一半。它们今天早已不负责把图缩放到多大(那是CSS的活),唯一的作用是让浏览器在图片还没到之前,先按这两个数算出宽高比、把位置占住,免得图一到就把下面的内容顶下去。

两个机制、四个声明位,共同点只有一个:写下就生效,写错不报错。没有任何一方会拿文件本身去核对一遍。

这和alt写错不是一回事

alt写错了,读屏软件念出来是错的,人能听出来;文件名写错了,也就是个名字,谁都不会当真——这两件事站内都专门算过账,图片alt到底是不是排名因素那篇给出的结论是它帮不上排名。

宽度不一样。它是一个参与运算的输入值。它错了,浏览器不会显示错,而是会算错——算错选哪一档,算错留多大的位。错误被算法吸收掉,变成一个看起来很正常的结果。这类错误最难查,因为它从来不以“错误”的形态出现。

这次量了什么?尺子先自己过一遍

样本是131个海外品牌站的首页,实际取回122个(另外9个持续返回403或429,进不去)。对每个页面,我把所有<img><source>拆开,记下四个声明位:

  • srcset里的w描述符;
  • widthheight属性;
  • 图片地址里点名要的尺寸参数,比如?width=1600
  • 地址末尾的扩展名,.jpg还是.png

然后是真身。对每个图片地址发一个Range请求,只取前64 KB,从文件头的字节里直接读真实宽高和真实格式——PNG的IHDR、JPEG的SOF段、WebP的VP8X、AVIF的ispe盒子,各有各的位置。一共发出1353次核对请求,1335次读出了真实宽高。

先证明这把尺子测得准,也测得出反例

任何“某某比例是多少”的结论,发表之前都得先证明尺子本身没坏。这次做了三重验证:拿已知尺寸的图去量,量出来分毫不差;把只读64 KB的结果和整个文件下下来的结果并排比,逐条一致;自研的字节头解析器和Pillow的读数逐条比对,也一致——只有SVG是Pillow读不了而自研解析器能读的。

更要紧的是证明它测得出对的。aloyoga的导航缩略图声明100×100,真身就是100×100;Salesforce Commerce平台上的44条样本,条条对得上。尺子如果只会报错,那它报的所有错都不可信。

两次尺子失效,都是自己先撞上的

第一次:解析<img>属性时我用了个偷懒的正则,直接在标签里搜width=。结果它命中了src属性里内联SVG的data URI——那串东西内部写着width='20'。于是arcteryx.com这类站被判出成片的“非法宽度值”,全是假的。改成逐个属性扫描之后,这一类全部清零。

第二次更隐蔽。我想统计“地址里点名要的尺寸,CDN有没有照做”,就顺手写了个正则去路径里捞800x600这样的片段。Storyblok的地址长这样:/f/187315/3436x3436/hash/name.jpg/m/270x270/——前面那个3436x3436是原图尺寸的标注,后面/m/270x270/才是这次要的。正则捞到了前一个,于是算出“Storyblok 32条没有一条照做”这种荒唐结论。改成只认查询参数和明确的变换段之后,Storyblok是32条全部照做。

这两次的共同点是:错误的读数并不长得像错误,它长得像一个可以直接写进文章的发现。这也是为什么下面每一个反常的数字,我都回到原始HTML里亲眼看过一遍。

SVG必须整批剔除

1335条真身里有108条是SVG,全部不参与尺寸对账。矢量图的width属性说的是“我打算显示成多大”,文件里的viewBox说的是“我的坐标系有多大”,两者本来就不需要相等。ikea的品牌logo属性写88.641宽、文件里是98——这不是错,是两个不同的东西。不剔掉它们,偏差率会凭空虚高一倍。

122个站的首页,图片对浏览器说了些什么?

10641张图片,中位数是每站49张(misen.com一个首页塞了1310张,是个异类)。四个声明位的使用情况:

  • srcsetw描述符的:67站(54.9%),4822张(45.3%);
  • widthheight都写了的:91站(74.6%),6790张(63.8%);
  • 只写了宽或只写了高的:20站,1095张——这种写法等于没写,浏览器算不出比例;
  • 三样都不写的:2498张,占全部图片的23.5%,涉及86个站。

近四分之一的图片,对浏览器一个字都没说。其中有15个站是彻底的——首页五张图以上,没有一张写了尺寸或srcset,包括anker、shein、philips、glossier、notino、farfetch这些量级不小的站。这批站里有相当一部分把图片交给了前端框架去渲染,而JS渲染这一层实测下来,真正会丢的东西和大家担心的并不是一回事。

写了的那些数,有多少压根不算数

HTML标准里对img元素的定义很硬:widthheight必须是非负整数,不带单位,不接受任何CSS写法。不合格的值不是“按CSS解释”,而是整条属性被丢掉,跟没写一样。

122个站里,37个(30.3%)至少有一处不合格的值。分布是这样的:

  • 百分比780处,8个站。casetify.com一个站就贡献了663处width="100%"——它显然是把这个属性当CSS在用;
  • 小数287处,17个站,比如height="1109.5888888888887",一看就是某个除法的输出直接塞进去了;
  • CSS关键字226处,10个站,写的是auto
  • 空字符串146处,4个站;
  • 带px之类单位的17处,5个站。

weber.com那两处空字符串值得单独看一眼。原文是这样的:src="[object Object]" loading="eager" width="" height=""。一个JavaScript对象被当成字符串拼进了地址栏,连带宽高一起塌了。同一个站另一处则写着width="9449" height="9449"——九千多像素见方,大概是哪个默认值没兜住。

看起来像bug但其实没事的那一类

buckmason.com有70处属性长这样:width="300 ",数字后面跟着两个空格。看着别扭,但它是合法的——HTML解析器在把属性值转成数字之前会先去掉两端空白。这条特意写出来,是想说明一件事:看起来不对劲的东西,有一半查到最后是自己吓自己。判据得先立住,再拿去数数。

srcset里那五个档位,是五张图吗?

这是这次最想弄清楚的一件事。927条带w描述符的位图样本,来自69个站:

  • 声明与真身完全相等:805条,86.8%;
  • 声明大于真身(说大了):119条,12.8%,涉及21个站;
  • 声明小于真身(说小了):3条,0.3%,只有一个站。

说大了的那119条,倍数中位数是1.7倍,最大14倍。落到具体的站上:

  • bellroy.com:九张导航图,每一张都列了320w到1920w五档,每一张的真身都在140到234像素之间。这个站三条以上样本条条对不上;
  • dollarshaveclub.com:三张保障图标声明600w,真身分别是43、53、58像素——差10到14倍;
  • govee.com:分类图标的srcset排了15个档位,从200w一直排到3000w,而文件真身只有360像素宽;
  • ruggable.com与drinkolipop.com:同样是条条对不上。

把一组档位整个下下来,会看到什么

上面那些数字是每张图抽一档量出来的,只能说明“某一档对不上”。要证明更狠的那句——一组档位其实是同一张图——就得把整组地址全下一遍。挑了六个站做这件事,结果分两类:

  • bellroy的三组导航图,每组五档(320w到1920w),每组都只返回一种宽度,分别是234、140、140;
  • ruggable的两组各八档(640w到3840w),也是全组返回同一个宽度296;第三组九档返回三种;
  • govee的两组各十五档(200w到3000w),一组只返回200和360两种宽度,另一组返回200、400、540三种——也就是说十五档里有十二三档是重复的;
  • fahertybrand那组更夸张:19个档位,真身只有200、300、301三种宽度

然后是对照组,用来证明这把尺子不是只会报“全都一样”:

  • arcteryx的三组各七档,七档返回七种不同宽度,档档对得上
  • bugaboo的三组各二十档,分别返回17、14、17种不同宽度。

同一个脚本、同一把尺子,在这两批站上给出的答案截然相反。这说明前面那些“全组同一张”不是测量方法的产物,是这些站上真实发生的事。

浏览器拿到这份清单会怎么办

它会老老实实按规范里那套图片选择算法办事:先用sizes算出这张图要占多宽的CSS空间,乘上设备像素比,得到一个需求值,然后在w描述符里挑第一个不小于需求值的档位。

在一块2倍屏上,bellroy那张占满屏宽的导航图,需求值轻松超过1280,于是浏览器选了1920w那一档。它相信自己拿到了1920像素的素材。实际到手的是140像素,被拉伸到十几倍宽。

要命的地方在于,这个后果不体现在任何一项性能指标上。字节数没有多,因为图本来就小;加载没有变慢,因为文件更小了;CLS那一套布局稳定性指标也不会动,因为占位是另一套机制在管。它只影响一件事——用户眼睛看到的清晰度。而清晰度没有仪表盘——这一点和跨源资源在性能监控里被抹成一排零是同一种处境:出了事,你的报表上什么都不会亮。

为什么偏差全是“说大了”,一条“说小了”都没有?

927条里说小了的只有3条,还全出自同一个站。这种一边倒的分布通常意味着背后有个机制,而不是一堆人各自犯错。

机制是这样的:模板生成srcset的时候,走的是一份写死的断点清单——320、640、960、1280、1920,或者200、400、600、800、1600。它给每个断点拼一个带尺寸参数的地址,再把断点数字原样抄成描述符。整个过程里,模板不知道原图有多大

另一头,图片服务的默认语义几乎清一色是只缩不放。imgix在fit参数的文档里写得明明白白:fit=max按给定尺寸等比缩放,但绝不超过原图尺寸。Shopify的image_url过滤器width参数的处理同理。你要1920,原图140,它就给你140,不报错、不警告,静静地给。

两头一对接,结果就注定了:描述符写的是“我要的”,文件是“我拿到的”,前者只可能大于等于后者。

地址参数那一层的数据完全佐证了这条:982条里CDN没照做的有139条,其中130条是“真给的更小”,只有9条是给大了。同一个机制的两个观测面。

所以中招的几乎都是小图标

把那119条按图片用途扫一眼,出问题的绝大多数是logo、支付图标、导航缩略图、分类小图——原图本来就只有几十到几百像素。真正的大图,首屏hero、产品主图,反而条条对得上,因为素材本身够大,CDN缩到哪一档都缩得出来。首屏那张图值不值得单独下功夫,关键渲染路径那篇算过一笔更完整的账。

这就有点讽刺了:响应式图片这套机制,在最不需要它的地方失效得最彻底。一个140像素的图标,本来写srcset就是多余的;写了,还写错了,反倒制造出一个查不出来的模糊问题。

换一家图片服务,这个数就准了吗?

把927条样本按图片托管方分组,命中率的差距大到不像同一件事:

  • Salesforce Commerce:44/44,100%;
  • Amplience:15/15,100%;
  • 自建或其他:59/64,92%;
  • Shopify:603/662,91%;
  • Sanity:30/33,91%;
  • Storyblok:22/30,73%;
  • Contentful:16/32,50%;
  • imgix:14/30,47%;
  • Next.js内置的Image组件:2/17,12%。

这份榜单不该读成“谁家更好”。它读出来的是各家在“原图不够大”这件事上的默认处置方式不同:有的会把描述符按实际能给的尺寸重写,有的干脆不生成超出原图的档位,还有的照单全收、要多少写多少。这不是技术能力的差距——把描述符按实际能给的尺寸写回去,技术上并不难。差的是有没有人在设计这个接口时想到过原图会不够大。

Next.js那12%尤其值得做前端的人看一眼。/_next/image?url=...&w=1440这个接口在原图不足1440时会返回原图,而生成srcset的那段代码照样把1440抄成描述符。两段代码都没写错,接在一起就错了。这种框架站的渲染与资源处理默认行为,往往是整站统一犯一个错,改一处就能全好。

width和height写错,到底会不会跳?

898条能对账的位图里,属性数值和真实像素完全相等的只有315条(35.1%)。这个数字乍看很糟,但它其实无关紧要。

因为浏览器根本不在乎绝对值。它拿这两个数只做一件事——算比值,然后按这个比值给图片留一块占位。属性写300×400还是1800×2400,占出来的位一模一样,因为比例都是3:4。

真正的判据是比例对不对。按这个口径重算:826条(92.0%)宽高比一致,只有58条(6.5%,12个站)比例明显不符。会不会跳,全看这6.5%:

  • joolz.com:属性100×100,方的;真身576×1057,竖的。浏览器按正方形占位,图一到变成竖长条,下面的内容全被顶下去;
  • everlane.com:属性2880×1620(16:9横图),真身750×1334(竖图)——这是首屏hero,跳起来最显眼;
  • brooklynbedding.com:属性550×550和750×750,真身都是493×271左右的宽幅图;
  • lookfantastic.com:属性900×250,地址里也明确写了width=900&height=250&fit=cover,CDN给回来的是1408×250。这一条是少数几个“真给的更大”的例子。

那35%的绝对值偏差,是另一笔账

比例对了不等于没事。真实宽度达到属性宽度两倍以上的有145条(16.1%,18个站),四倍以上的83条(9.2%)。这些图会正常显示、不会跳,但送来的像素是要摆的位置的四倍——按面积算就是十六倍的解码开销和字节量。这笔字节账最后会落到抓取上,而304这类本该省下抓取预算的机制,在这批站上没几个接得住。

这是带宽和解码时间的账,不是布局的账,两笔账要分开算。想把这两件事一次性看清,站内那篇讲一页图片的alt与属性怎么批量体检的工具文里有现成的检查清单;如果要顺带把图片本身的体积压下来,图片压缩这一层的坑也得一起看,那篇里有个135字节的图标被压成560字节的真实案例。

这两个数到底该填什么

填真实像素最省心,因为它同时满足比例正确和数值诚实。填CSS显示尺寸也完全可以,只要比例跟真身一致。唯一不能做的是一个填真实像素、另一个填显示尺寸——那个比值就是凭空捏造出来的,比不填还糟,因为不填至少浏览器知道自己不知道。

顺带一提,把loading="lazy"挂在首屏图上是另一个常见的自伤动作。这次122个站里有93个用了lazy,覆盖6987张图(65.7%),而用了fetchpriority去纠正优先级的只有54个站。这两个属性的分工,fetchpriority那篇讲得比这里细。

扩展名写.jpg,送来的是WebP,这算问题吗?

1194条有扩展名可比的样本里,925条(77.5%)扩展名与真实格式对不上,涉及80个站。形态很集中:jpg变WebP 425条,png变WebP 221条,jpg变AVIF 160条,png变AVIF 97条。

先说结论:这件事本身不是问题。这是内容协商——和服务器按Accept-Encoding挑压缩算法是同一套机制的两个面——CDN看请求头里的Accept,你的浏览器支持AVIF就给AVIF,支持WebP就给WebP,地址不用改,扩展名只是个历史遗留的名字。ikea那张.png结尾的首页海报,我这边收到的是AVIF,同一个地址换个客户端收到的可能就是PNG。

问题在配套的那一行声明。375条响应换了格式,却没有在 Vary响应头里声明accept,涉及35个站。这意味着中间任何一层缓存——CDN边缘节点、企业代理、甚至浏览器自己的缓存——都不知道这个地址的响应会因请求头而变,完全可能把AVIF版本喂给一个不认识AVIF的客户端。这类因为Vary头没配对而导致缓存串味的故障,排查起来极其费劲,因为它只在特定客户端组合下复现;而声明的Vary与实际响应变化对不对得上,是另一个可以单独量的维度。

顺手撞出来的一件事

既然七成七的地址扩展名是假的,那么所有靠扩展名判断图片格式的工具,在这批站上有七成七的时候是错的——包括不少SEO审计工具生成的“你有多少张图还没转WebP”报表。响应头自己前后打架的情况也不罕见,同一批站的响应头自相矛盾那次量到的比例比这次还高。想知道真格式,只有两条路:看响应头的Content-Type,或者像这次一样直接读文件头的字节。另外还有141条地址(10.6%)压根没有扩展名,那类工具连猜都没法猜。

还有16张图,声明了尺寸却根本取不回来

这一类不多但很典型,6个站16条:

  • braun.com有四个支付图标的地址是https://us.braun.com//images.ctfassets.net/...——本该是绝对地址,少了协议头,于是被当成了本站的一个路径,稳定404;
  • allbirds.com的地址里带着没渲染的模板变量,字面量${userCountry}直接进了HTML;
  • weber.com那个[object Object]
  • italic.com的srcset拼接错位,把参数串接到了域名后面。

这几条的共同点是:属性写得一丝不苟,地址是坏的。宽高比声明得整整齐齐,图片永远不会来。这类问题在只看HTML的审计里全部隐形,必须真的把每个地址请求一遍才看得见——第三方域名依赖也是同一个道理,光读源码一个都数不出来;这和preconnect指着已经不存在的域名是同一类毛病,声明还在,被指的东西没了。

自己站上怎么查,按什么顺序修?

整套流程不需要任何工具,浏览器控制台就够。按下面的顺序做,先解决影响面大的——保哥自己按这个顺序跑过几轮,每次改动量最大、见效也最快的都是第一步。

第一步,把不合格的属性值挑出来。这一类修起来最便宜,收益最直接——因为它们现在等于完全没写。

[...document.images].filter(i => {
  const w = i.getAttribute('width'), h = i.getAttribute('height');
  const bad = v => v !== null && !/^\d+$/.test(v.trim());
  return bad(w) || bad(h);
}).map(i => [i.getAttribute('width'), i.getAttribute('height'), i.currentSrc]);

第二步,比对宽高比。图片加载完之后,naturalWidthnaturalHeight就是真身,拿它跟属性算出来的比值比一比,差5%以上的就是会跳的那些。

[...document.images].filter(i => {
  const w = +i.getAttribute('width'), h = +i.getAttribute('height');
  if (!w || !h || !i.naturalWidth) return false;
  const a = w / h, b = i.naturalWidth / i.naturalHeight;
  return Math.abs(a - b) > 0.05 * Math.max(a, b);
}).map(i => [i.getAttribute('width') + 'x' + i.getAttribute('height'),
             i.naturalWidth + 'x' + i.naturalHeight, i.currentSrc]);

第三步,验srcset的档位是不是虚的。这一步没法在页面里直接做,因为浏览器只会下载它选中的那一张。得把srcset里的地址逐个取出来,各发一个请求读真实宽度,再跟描述符对。判据很简单:如果一组档位里有两个以上返回的真实宽度相同,那后面那些档位就是假的。上面那六个站就是这么验出来的,一组十几档跑下来不到一分钟。

第四步,如果你的图片走内容协商,检查Vary里有没有accept。这一条通常在CDN配置里改一行就好,但没人会主动想起来去看。

三件不值得做的事

省下来的力气比多做的事更值钱:

  • 不必追求属性数值等于真实像素。可对账的样本里九成宽高比本来就是对的,这件事整体做得不差,绝对值差多少无所谓;
  • 不必因为扩展名和真格式不符去改文件名。那是内容协商在正常工作,改了反而破坏缓存。至于文件名本身对排名有没有用,图片SEO那套老规矩里早有定论;
  • 不必给每张小图标都配srcset。一个40像素的图标配五个档位,除了给自己制造这次说的这类错,没有任何收益。给它一个够大的单图,写清宽高,就完了。

这次测量没做到的几件事

把口径讲清楚,比多报几个数重要:

  • 只看了首页。产品页和类目页的图片模板往往是另一套,结论不能直接搬——同一批站的页面类型声明就呈现出首页和类目页两副面孔;
  • 每站最多对账16张图,不是全量普查。misen.com首页那1310张图,只抽到了16张;
  • 9个站始终取不回来(403或429),122这个分母里没有它们,而拦得住我的站往往技术投入也更高,样本可能偏保守;
  • 没有真的渲染页面。所以sizes属性写得对不对——那是响应式图片另一半的重头戏——这次完全没法验;
  • 只读文件头。能拿到真实宽高和真实格式,拿不到图片内容,所以“这张图该不该这么大”是判断不了的;图片里那些元数据还剩多少,也得换一套读法才量得出来。

常见问题解答

srcset的w描述符写错了,Google会因此降权吗?

不会有直接的排名惩罚。搜索引擎不会去核对这个数,跟浏览器一样。它的影响是间接的:图片模糊会影响用户体验和停留时间,而如果错误发生在首屏大图上,还可能拖累LCP的取值。图上那些字进不进得了文本层是另一件事,大图上62%的字页面里找不到那次量的就是它。页面速度到底怎么影响排名那篇里讲过这条链路有多长——不要指望修好它明天就涨排名。

我的站用Shopify,需要担心这件事吗?

Shopify这次的命中率是91%,属于中上。出问题的集中在手工写进主题模板的小图标:品牌logo、支付方式图标、导航分类图。这类图标常常是装App时顺手带进来的,而Shopify的App堆叠本身就是一笔性能与成本的账。这些图的原图往往只有一两百像素,而主题模板的srcset生成逻辑是通用的,照样给它排到1600w。产品图基本没事,因为Shopify要求上传的原图足够大。

width和height属性不是早就不用了吗?

2019年之后又回来了,而且比过去更重要。现在浏览器拿这两个数算aspect-ratio,在图片到达前把位置占住,这是防布局偏移最便宜的一招。它已经不管缩放了——缩放归CSS——但那个比值仍然必须诚实。

那23.5%一个尺寸都没写的图,是不是都得补上?

看它在不在首屏、会不会引起跳动。装饰性的小图、在固定尺寸容器里的图、已经用CSS aspect-ratio锁死了比例的图,都不用补。长列表里那些还没滚到的图,用content-visibility让浏览器整块跳过渲染比逐张调属性划算得多。真正要补的是那些高度由图片自己撑开的——尤其是首屏hero和商品列表里的主图。

怎么知道我用的图片CDN会不会在原图不够时放大?

拿一张你确定很小的图去试。取一个原图只有一两百像素宽的地址,把尺寸参数改成1600,请求回来读一下真实宽度。给回1600的说明它会放大(这也未必是好事,放大等于凭空多花字节),给回原图尺寸的说明它只缩不放——后者是绝大多数服务的默认行为。

扩展名跟真实格式不符,会影响图片被搜索引擎收录吗?

不会。搜索引擎抓图片时看的是响应头的Content-Type,不是地址里的扩展名。真正需要留意的是Vary那一行有没有配对,那影响的是缓存正确性,不是收录。

如果只能改一处,改哪个?

先把不合格的属性值扫一遍改成整数。这是唯一一类“现在完全没生效、改完立刻生效”的问题,30.3%的站有,成本几乎为零。srcset那类虚档位影响的是清晰度,重要但要动模板;宽高比不符的只有6.5%,范围小,可以排在后面。

权威参考资料

分享到
标签
版权声明

本文标题:《srcset写着1920w,服务器给的是同一张140宽的图》

本文链接:https://zhangwenbao.com/srcset-declared-width-vs-real-image-audit.html

版权声明:本文原创,转载与引用请注明作者与原文链接。许可协议: CC BY 4.0

继续阅读
发表评论
分享到微信 或在下方手动填写
支持 Ctrl + Enter 提交