IMAGE SPEEDUP · 2026-07-19 · DEPLOYED PROOF

图照旧,传输账轻了

全站可信 CDN 图片统一在“显示出口”转 WebP;原始 R2 文件、数据库 URL、引用对象和下游 payload 一字不改。存量外链能救的持久镜像,源站已经失效的则诚实记失败。

显示覆盖 PASS · 镜像根因修复 PASS · 存量外链只回收可取回部分
THE ANSWER FIRST

同样的画面,三类代表图都明显变小

素材 PNG
−93.0%

329,283 B → 23,142 B

故事板 PNG
−88.0%

2,187,925 B → 261,998 B

成片封面 JPG
−35.8%

52,233 B → 33,526 B

同 campaign 裸图
10 → 0

最终浏览器资源账 36/36 转换,裂图 0

不是改原图。 转换只发生在浏览器读图这一刻;下游要原文件时仍拿 canonical URL,不会误拿缩略 WebP。

ONE URL · TWO DESTINATIONS

显示变轻,协议不变

FETCH WRITE DISPLAY DISPATCH EXTERNAL外站图片source URL MIRRORR2 持久镜像fetch · store CANONICAL原始 R2 URLDB · refs · payload BROWSERWebP 显示 URLquality 82 DOWNSTREAM原始 URL 下发0 transform URL LEGEND 本次焦点原始协议显示路径canonical 路径
判断:性能优化的边界不是“把 URL 全改掉”,而是把转换锁在最后一厘米。这样浏览器少下载,下游仍拿到可编辑、可抽帧的原文件。
BYTE LEDGER

三张真图,原图和转换图逐字节对账

代表图原始响应转换响应减少判定
素材 PNG200 · image/png · 329,283 B200 · image/webp · 23,142 B306,141 B · 93.0%PASS
故事板 PNG200 · image/png · 2,187,925 B200 · image/webp · 261,998 B1,925,927 B · 88.0%PASS
成片封面 JPG200 · image/jpeg · 52,233 B200 · image/webp · 33,526 B18,707 B · 35.8%PASS

请求均带 Accept: image/avif,image/webp。不加 width,保留原尺寸;页面只负责传更合适的编码。

COVERAGE

不是抽几个组件:同一 campaign 裸显示从 10 处归零

改前

  • 显示属性 42
  • 已转换 32
  • 裸 CDN 10
  • 漏口集中在 cdn-asia 故事板、动态 DOM 与管家缩略图

改后

  • 显示属性 61
  • 已转换 61
  • 裸 CDN 0
  • 新浏览器资源账 36/36,brokenImages=[]

61 比 42 多不是重复请求。 同一 campaign 在两次部署间增加了任务数据,所以只用“裸显示属性 10→0”做硬断言。

REAL UI

改的东西本身,六张部署态截图

MIRROR ROOT CAUSE

漏镜像不是没调用,是 20 路各开一个数据库连接

旧 fast-search 会并发镜像视频与封面,但每个资产都新建 Neon client,20 路连接风暴把尾部 UPDATE 静默打掉。现在 fetch / R2 仍并发,只共享 runner 已有的 SQL client,并等所有 UPDATE 收口后再关连接。

run接纳素材视频镜像封面镜像口径
4edcf656…1065BEFORE
56d5501f…191012BEFORE
dac6dfa6…161015BEFORE
1e817192…444AFTER · DONE

样本量如实写 4/4。 模型这轮只接纳 4 条,不为凑施工图预估的 10 条放水,也不把 4/4 冒充 10/10。

BACKFILL · HONEST BOUNDARY

可取回的补回 R2;源站拒绝的明确报失败

竞品封面

  • 首批 3/3 成功
  • 缺封面 backlog 205 → 202
  • 视频先镜像成功才抽帧
  • 未镜像视频不硬抽

外链封面

  • 过期 / 封出口样本 5/5 失败,真实计数
  • 稳定 pbs 样本 1/1 成功
  • external 204 → 203
  • Wikimedia 在 Worker 出口 403,日志可见

权限红线守住。 无 cookie 与真实 INGEST_TOKEN bearer-only 调 backfill 都是 401;只接受 admin session cookie。

PROTOCOL PROOF

管家画的是 WebP,发的仍是原引用

同一枚 chip

data-bchat-asset-url 保持原始 CDN URL;嵌套 img.src 才加 /cdn-cgi/image/…webp/

picker 74/74 转换,S.refPickerRows / item.thumb 源值不改。

拦截发送,不真发

临时拦截浏览器 WebSocket send,捕获 1 帧后恢复原函数。帧里只有引用对象类型与 UUID。

containsUrl=false · containsTransform=false

{
  "type": "chat.send",
  "refs": [{
    "object_type": "asset",
    "object_id": "c51ea96d-bf50-4edb-90fb-bc167b89c607"
  }]
}
DEPLOY & CHECKS

两笔 commit,测试站一次真实收口

15af233

23 文件主改:展示出口全覆盖、共享 SQL 镜像、竞品抽帧、cookie-only backfill。

57a75d0

只补 public/butler-chat.js 六个显示出口与 pm-shell 指纹;服务端管家上下文 0 diff。

VERSION · a3b92469…

只部署 material-board-sozai-st / sozai-st-test / st/test;生产零触碰,rollout 挂账。

STATIC · PASS

typecheck exit 0;git diff --check 0;六条下发路径转换 URL 命中 0。

页面HTTPTTFB下载体积
tuning2000.704s430,984 B
plans2000.500s309,958 B
deliverables2000.667s267,022 B
guidance2000.459s102,582 B