197KB 单文件前端到底慢不慢?用 Playwright 实测一个零依赖单词配对应用
【摘要】 用 Playwright 实测一个 197KB 单文件前端:外部请求只有 1 个、DOMContentLoaded 28ms、主题切换小于 3ms。拆解单文件架构在请求瀑布、解析成本、离线可用上的真实收益,以及缓存粒度、长列表渲染、可维护性三方面的代价,并给出该放弃单文件的 5 条判断标准。
// 只读 state,不读 DOM
// 选中态、匹配态、进度条全部由 state 推导
}
好处立刻显现:**切词表、切模式、重置进度,复用的是同一套逻辑**,因为它们本质上都只是「改 state 然后 render」。不会出现某个路径漏清理的状态。
这也让乱序模式变得很简单——乱序不需要改动 DOM 顺序,只要在渲染前对卡片数组做一次 shuffle。
## 六、几个具体的性能取舍
### 取舍一:内联 SVG 图标而不是图标字体
图标字体要下载一个 20-100KB 的字体文件,还会造成 FOUT(图标先显示成方块)。内联 SVG 只在用到的位置多几十字节,且**不产生额外请求**。代价是 HTML 体积微增、复用麻烦一些。
### 取舍二:不用框架
React/Vue 的最小运行时也要 40-140KB。这个应用的状态模型只有 5 个字段、渲染逻辑不到 200 行,手写 render 函数完全够用,而且**没有虚拟 DOM 的 diff 开销**。
框架的价值在状态复杂、组件多、多人协作时。这个项目三个条件都不满足。
### 取舍三:数据内联,不做接口
词表数据直接内联在 HTML 里。多一次接口请求,就多一次网络往返 + 一次等待,而数据本身很小(5% 的内容)。
代价是**加词表要改文件**,不能后台配置。对个人工具完全可接受。
## 七、什么时候该放弃单文件
我把判断条件写清楚,供参考。**满足任意两条,就该拆**:
1. **有频繁发版**:需要细粒度缓存,不能每次全量重下
2. **多人协作**:单文件必然冲突
3. **体积超过 1MB**:解析成本开始明显,首屏会出现可感知的白屏
4. **需要按需加载**:多个功能模块、用户只用到一小部分
5. **有服务端状态**:需要接口、鉴权、数据同步
WordsMatch 一条都不满足,所以单文件是合适的选择,不是偷懒。
## 八、这套思路能迁移到哪
「单文件 + CSS 变量 + 状态驱动」这个组合,适合这些场景:
- **内部工具**:一堆小脚本、小页面,每个都是独立 HTML,扔进共享盘就能用
- **Demo / 原型**:给客户看效果,一个文件发过去,不用配环境
- **离线工具**:现场没网、或者安全要求不能连外网
- **教学示例**:学生打开就能读全部代码,不用理解构建工具链
不适合的也很明确:任何需要长期演进、多人维护、有后端的产品。
## 九、小结
这次测量最反直觉的一点是:**197KB 的「大文件」比 5 个 40KB 的「小文件」更快**。因为请求数和依赖链才是前端性能的主要成本,字节数在局域网或已缓存场景下几乎不构成瓶颈。
当然这个结论有边界——它成立的前提是:没有要加载的第三方资源、数据量小、不需要按需加载。一旦有了这些需求,单文件立刻变成负债。
写代码时最难的从来不是选「先进的方案」,而是判断**当前规模到底需不需要那个方案**。
---
项目地址:github.com/zlZayn/WordsMatch(MIT)
在线试玩:zlZayn.github.io/WordsMatch
作品页:开发者作品展览馆
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)