# 小工具性能预算与降级规范 > 本文提供移动端 WebView 的设计预算与降级要求。Skill 只能检查静态产物和代码设计,不能从源码推断真实帧率、内存或真机表现;没有运行数据时必须明确标记“未实测”。 ## 目录 - §1 交付门禁 - §2 静态数据与长列表 - §3 图片、音频与视频 - §4 WebGL 资源与降级基线 - §5 运行时降级与兜底 - §6 交付检查 --- ## 1. 交付门禁 | 项目 | 门禁 | 原因 | | --- | --- | --- | | 最终 zip | **不超过 10 MiB**;建议不超过 2 MiB | 10 MiB 是上传上限,不是性能目标 | | 单个 `.html` / `.css` / `.js` / `.json` | 不设硬上限;超过 2 MiB 触发风险提示 | 大源码会增加读取、解析、编译和峰值内存;即使压缩后很小也一样 | | 上述文本文件解压后合计 | 不设硬上限;超过 5 MiB 触发风险提示 | 用于发现把数据库或生成产物塞进代码包的情况 | | 单条 Base64 | 解码后不超过 1 MiB;超过 100 KiB 提示风险,超过 1 MiB 视为大 Base64,必须改成独立包内文件 | Base64 体积约增加 1/3,还会产生字符串与解码副本 | 先检查可用运行时,有哪个就用哪个;两个脚本均为单文件且只使用各自标准库,不要为了审计临时安装 Node、Python 或第三方依赖: ```bash # 有 Node 18+:脚本零第三方依赖 node /scripts/audit_artifact.mjs ./dist node /scripts/audit_artifact.mjs ./tool.zip # 有 Python 3:脚本只用标准库,并可检查 zip 内部文本 python3 /scripts/audit_artifact.py ./dist python3 /scripts/audit_artifact.py ./tool.zip ``` 两个运行时都可用时任选其一;Python 版可额外读取 zip 的文件清单与解压后体积。Node 版对产物目录做完整体积审计,对最终 zip 只检查包体,因此必须在压缩前先审计目录。脚本只依据文件系统和 zip 元数据做确定性检查:zip 超过 10 MiB 报 `ERROR`;zip 超过建议的 2 MiB、单个或合计文本较大报 `WARN`。 脚本不解析或猜测 JS / HTML / CSS 语义。Base64、WebGL 结构与降级策略由本规范约束,并在 §6 按代码逻辑审查。仓库发布检查会把两个脚本复制到无项目依赖的临时目录实际执行;依赖 pip / npm 包或相对模块时发布失败。 如果 Node 与 Python 都不可用,仍须人工完成 §6 清单,并至少:查看最终 zip 文件大小;确认 Base64 资源的生成来源与实际字节数;检查最大的 HTML / CSS / JS / JSON 是否混入大型数据;逐项检查 WebGL 预算与降级。交付说明中标记“未运行自动审计”及人工检查结果,不得直接声称审计通过。不要通过改后缀或运行时解压字符串来隐藏大数据,这只会把开销推迟到运行时。 --- ## 2. 静态数据与长列表 `.js` / `.json` 是静态资源,不是数据库。**不要把数万条记录、完整业务库、日志或抓取结果生成成 JS 数组。** JSON 与 JS 分文件只能改善组织,不能消除下载、解析和内存成本。 优先按以下顺序缩减: 1. 只保留完成核心功能必需的字段和记录,删除重复字段、长描述和历史快照。 2. 能预计算的统计、搜索索引和分类结果在构建期生成;不要在首屏对全量数据反复遍历。 3. 大型只读数据集改为摘要、分段样例或让用户通过 `` 按需导入。若完整离线数据不可删且仍超门禁,应明确说明该需求不适合小工具,而不是继续打包。 4. 用户产生或导入的数据写入 IndexedDB;IndexedDB 用于运行期持久化,不用于掩盖巨大的内置种子数据。 渲染列表时: - 首屏只创建可见项;长列表使用分页或虚拟滚动,不一次性拼接整份 `innerHTML`。 - 搜索输入按交互频率和数据规模采用防抖,避免每次按键都触发完整查询;最终输入应及时执行。数据量较大时可预先建立小型索引,避免反复扫描所有字段。 - 非首屏工作分批执行并主动让出主线程,避免把解析、计算和渲染集中在同一个同步流程中。 - 不在循环中反复读写布局属性;批量生成 DOM 后一次挂载。 --- ## 3. 图片、音频与视频 - 小型图片、图标等可以使用 Base64;单条解码后超过 100 KiB 时应优先改为包内文件,超过 1 MiB 不允许内嵌。 - 图片按真机展示尺寸缩放并压缩,优先 WebP;不要为了 300 px 展示区域打包 4K 原图。 - 音视频先裁剪时长,再降低分辨率、帧率和码率。5 分钟视频通常不适合随小工具离线交付;优先改为短片段、封面 + 交互说明,或让用户运行时自行选择本地视频。 - 视频设置 `preload="metadata"` 或 `preload="none"`,提供 `poster`;未进入播放页前不要创建或解码媒体。 - 同时只保留必要的媒体实例;离开页面后暂停播放、清空不再使用的 `src` 并释放对象 URL。 `FileReader.readAsDataURL()` 可用于用户刚选择的小文件预览或 JSBridge 明确要求 data URI 的短暂转换;大文件不要把结果持久写回静态源码,优先用对象 URL 预览,并在不用时 `URL.revokeObjectURL()`。注意:即使体积很小,`