全部文章

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)。所以它看起来不像外挂组件,更像这块玻璃被举到了眼前。

剩下的问题

前三个是工程活,最后一个(手势缩放)是产品决定——双击已经被「进入画廊」占用了,再放大就得换手势。

先把能确定性做完的做掉。

回到顶部