一项能力能否长期维护,不取决于演示是否成功,而取决于团队能否解释每个状态、每次重试和每一份残留数据。 一次把整文件读成 ArrayBuffer 会让内存随文件大小增长;在主线程逐块哈希又会产生长任务。正确流水线由固定读取窗口、Worker 增量状态和最终摘要组成。
浏览器能力由版本、权限、页面可见性和设备策略共同决定。实现需要能力探测与可解释降级,不能把某一台开发机上的 API 存在当成产品契约。
设计时必须回答的问题
实现之前先列出不可违反的不变量,再为性能与体验留出调节参数。参数可以灰度,身份、权限和终态规则不能在运行时随意漂移。
- 读取固定大小块并转移 ArrayBuffer 所有权,Worker 处理后再释放额度。
- 进度按时间节流而非每块 postMessage,防止消息风暴重新压垮主线程。
- 取消消息带任务版本,Worker 清空摘要状态并拒绝旧读取回调。
Worker 只解决线程占用,窗口、所有权和取消才解决资源边界。三者一起设计,摘要计算才能成为可靠传输的一部分。
边界情况不是附加项
最值得优先排查的是会静默留下错误事实的故障:界面看似恢复,底层队列、权限或计数却已分叉。这类问题通常在下一次动作才暴露。
- 传输与哈希各自读取同一文件,磁盘和内存带宽重复消耗。
- 缓冲转移后主线程仍保存视图,重试时读取 detached buffer。
- 一个全局 Worker 同时混合两个任务,摘要状态和进度彼此污染。
用证据确认它真的可用
测试不能以“最后成功了”结束。还要测量经历了多少次副作用、等待多久、是否泄露内容,以及失败后再次执行能否从干净基线开始。
- 用大于可用内存的文件运行,峰值必须跟窗口大小而非文件大小增长。
- 在每个块边界取消并立即启动新任务,确认旧摘要绝不回调新任务。
- 测量输入延迟与长任务,确保哈希期间页面交互和屏幕观看保持流畅。
可以上线的标准是:用户知道当前发生了什么,系统在异常后能停止或恢复,资源不会无界增长,运维也能从最小必要证据定位阶段。