给卡帕多奇亚民宿做预订页,图片加载把我坑惨了
去年底接了个小外包,伊斯坦布尔一个做卡帕多奇亚洞穴民宿的老板,要一个能看房型、能看热气球日出照片的预订落地页。条件很朴素:客户在格雷梅,网是村里的 ADSL,游客一半用手机在机场里刷。我本地是 M1 加千兆,跑起来顺得像假的一样,上线第二天老板发来语音,说图片「一片一片地爬出来」。
先给上下文:一共 6 个房型,每间 8 到 12 张图,我按原图导出的 JPG 平均 2.8MB,总共 50 多张,直接 <img> 铺在卡片里。我自己用 Chrome DevTools 把网络限到 Fast 3G 才发现,首屏要等 4 秒以上才出第一张图,热气球那几张更是白框挂半天。
做法其实是把图先压到能用,再懒加载。压图用 sharp 一次性跑:
const sharp = require('sharp');
const fs = require('fs');
const files = fs.readdirSync('./src');
files.forEach(f => {
sharp(`./src/${f}`)
.resize({ width: 1280, withoutEnlargement: true })
.jpeg({ quality: 72, mozjpeg: true })
.toFile(`./out/${f.replace(/\.\w+$/, '')}.jpg`);
});
卡片图另出一份 640 宽的,用 srcset 让手机拿小图;首屏第一张房型图加 fetchpriority="high",其余全部 loading="lazy" 加 decoding="async"。房型详情里的大图改成点击后才加载,用 IntersectionObserver 挂载,没进视口就不发请求。
为什么这么做:洞穴民宿的照片是它唯一卖点,但游客在机场刷手机时根本不会等,图片就是首屏的 LCP,压掉字节比任何花哨交互都值。代价是画质变软,老板一开始嫌「不够通透」,我把 1280 宽 72 质的样图和原图并排发给他,他才接受——热气球本来就在逆光里,糊一点反而像真的。
哪里会失效:一是老安卓机对 srcset 的支持没问题,但我一开始忘了写 sizes,浏览器按 100vw 算,手机还是拉了 1280 的图,白压了;二是客户后来自己往后台传了 PNG 截图,sharp 那条流程没覆盖,又回退成几 MB 一张,这个坑我现在还留着;三是 loading="lazy" 放在首屏第一张图上,Chrome 会延迟加载反而拖慢 LCP,别学我第一版。
现在页面在 3G 下首屏 1.6 秒能出图,老板说机场的客人终于肯往下划了。但有个事我一直没底:这种小单的图,到底该在构建时压死,还是留给后台按上传时压?你们做 CMS 类项目时是怎么卡这道口的?
0 条评论
还没有评论,写下第一条。