
2 分钟#cloudflare #design
图床:缩略图、灯箱与边缘分发
照片不放仓库里,放 Cloudflare 的边缘;网页端只加载缩略图,双击进画廊看原图,元信息有则显示、无则省略。
照片和壁纸是两类东西:
- 壁纸是前端的资源,参与材质渲染,必须小、必须快、必须可缓存一辈子;
- 照片是内容,可能很大、会一直增加,应该交给边缘节点。
所以图床单独做。
三档尺寸
每张图在上传时就切成三档,构建时只负责生成索引:
gallery/
index.json # 构建产物:条目 + 尺寸 + 元信息
thumbs/<slug>.webp # 400w 列表用
preview/<slug>.webp # 1200w 灯箱先显示这张
full/<slug>.webp # 1600w 灯箱随后替换成这张
列表页只加载 thumbs,并带上 srcset。灯箱打开时先给 preview,等 full 加载完再换——眼睛几乎察觉不到,但首屏省下几百 KB。
双击进画廊
桌面端双击缩略图进入,单击不动作(防误触);触控端没有双击,改成单击;键盘用户按 Enter。
三种入口,一个动作。

灯箱里除了大图,还有一栏信息:
| 字段 | 有就显示 | 没有就不显示 |
|---|---|---|
| 标题 / 简介 | ✓ | ✓ |
| 日期 / 地点 | ✓ | ✓ |
| 相机 / 焦距 | ✓ | ✓ |
| 版权 | ✓ | 用站点默认许可 |
这条「空则省略」的规矩很重要——不然每张插画下面都会挂着「相机:—」,很像模板没填完。
为什么不用 Worker
图床不需要实时缩放:
- 缩略图是构建时(或上传时)一次性生成的;
- 边缘节点只负责把文件吐出去;
- 目录由
gallery/index.json描述。
一旦引入实时缩放,就多了一个会冷启动、会超时、会按请求计费的东西——而它解决的问题,一张预生成的 WebP 就能解决。
部署形态
全站依然是「只有 assets、没有 main」的 Worker:没有业务脚本,图片和 HTML 走同一套边缘缓存。
玻璃配方保持一致
相册卡片也是窗口:同样的圆角、同样的高光边、同样的悬停位移。
灯箱是玻璃层的「高潮态」——深色遮罩 + 强模糊 + 中央大图,但配色仍然取自同一套 token(--brand、--seal、--radius)。所以它看起来不像外挂组件,更像这块玻璃被举到了眼前。
剩下的问题
前三个是工程活,最后一个(手势缩放)是产品决定——双击已经被「进入画廊」占用了,再放大就得换手势。
先把能确定性做完的做掉。