年请停止相信公共CDN能提升性能
请注意,本文探讨的核心对象是公共 CDN,而非自建 CDN 或云厂商提供的 CDN。许多人至今仍抱着“公共 CDN 能够加速网站”的旧有认知,但到了 2026 年,这一观念确实需要重新审视与评估。

公共 CDN 已不再具备缓存优势,对用户而言,实际加载的数据量并未减少
过去公共 CDN 能够提升性能的逻辑很简单:当用户访问过任意使用相同资源的网站,其本地浏览器会缓存该库文件,再次访问你的站点时可直接命中缓存,无需重新下载。然而,在当今的浏览器机制与前端生态下,这一套方案早已失效。
第一,自 Chrome 86 起,浏览器启用了缓存分区机制,Firefox、Safari 等主流浏览器也陆续跟进。不同站点的缓存被彼此隔离,用户仍需为每个网站单独下载脚本——所谓的缓存优势,已然不复存在。
第二,即便用户仍在使用 Chrome 86 以下的旧版本,当下的环境也已今非昔比。如今早已不是清一色 jQuery 的时代,前端构建已成为主流。想要恰好碰到用户之前访问的网站使用了同一家 CDN 供应商、同一个库、同一个版本、同一种格式?这种概率低到可以忽略不计。
对用户来说,实际加载的数据量可能反而更大
公共 CDN 提供的资源均为固定的全量打包产物。而现代前端工程的最大优势,正是能够基于业务场景进行极致的按需构建。进一步来说,所有构建层面的优化,公共 CDN 都无法享受。
Tree-shaking:项目中未使用的冗余代码、废弃逻辑可以大幅精简。公共 CDN 的全量包包含了库的所有功能代码,即使项目只用到了 10% 的能力,也必须加载 100% 的代码——冗余度极高,浪费严重。
打包:工程构建可以将多个小型同类依赖合并为单个 chunk,从而减少请求数量;也可根据路由或功能拆分资源粒度,实现按需加载。公共 CDN 的产物是固定的,无法适配项目专属的合并与拆分策略。
依赖自身的构建开关:大量主流库提供了环境裁剪、功能开关等构建配置,可以按需关闭无用模块和兼容代码,例如 Vue 的 __VUE_OPTIONS_API__。而公共 CDN 为了适配全网所有场景,只能保留所有功能、开启全量兼容,定制化裁剪根本无从谈起。
按条件加载:现代前端工程可以同时输出多份产物,让不同浏览器运行不同的代码版本。例如业界常用的 module/nomodule 方案可实现条件加载。但公共 CDN 大多仅提供统一的大包——要么产物非常臃肿,要么兼容性较差。
自动 polyfill 引入:一个优雅的构建过程会自动扫描依赖,然后注入所需的特定 polyfill。但外部依赖无法被扫描,要么全局引入 polyfill,要么只能人工判断处理。
深层依赖预加载:在使用动态 import 时,现代前端工程能够同时请求深层依赖。而使用公共 CDN 时,只有当前依赖请求完成后,才能知道有哪些深层依赖,无法预加载。
公共 CDN 的网络性能真的比主站好吗?我看未必
公共 CDN 的节点质量难以控制,运营商链路也不确定。在弱网环境、跨国访问、小众地区等场景下,它甚至可能比业务自研的 CDN 或源站更慢。而且,使用公共 CDN 还会带来额外的 DNS 解析、TLS 握手、TCP 连接建立、CORS 校验等开销。
如果主站已经采用了 HTTP/2 或 HTTP/3 的多路复用,同域访问更能提升连接复用效率,这之间的差距只会越拉越大。
就日常的上网体验而言,加载缓慢的网站几乎都在使用 jsDelivr——这个现象本身就很有说服力。
增加供应链安全风险
你的小网站可能引不起黑客的兴趣,但公共 CDN 却是黑客眼中的“香饽饽”。历史上开源供应链攻击层出不穷,公共 CDN 极易面临劫持、篡改、停服、投毒等风险。
为了防御,我们被迫使用 SRI(Subresource Integrity)。但 SRI 是一把双刃剑——一旦 CDN 资源被篡改或者哈希不匹配,浏览器会直接拒绝加载。这就好比为了防止食物中毒,直接把所有外卖都倒进垃圾桶。结果是什么?用户看到的是页面白屏。
于是,为了保障用户体验,我们又要编写“降级逻辑”:检测 CDN 挂了 → 加载本地备用资源。绕了一大圈,不仅代码变复杂了,用户还多走了一条无效的失败路径,速度反而更慢了。这真是“捡了芝麻丢了西瓜”。
公共 CDN 与主站的 HTTPS 加密协议版本可能不同
HTTPS 的加密协议在不断更新,但存在一个核心矛盾:协议越安全,支持的范围越窄;支持范围越广,安全性越低。
当你的主站与公共 CDN 所使用的 HTTPS 加密协议版本不一致时,可能出现你的主站支持的用户更广,而公共 CDN 支持的用户更窄的情况——主站正常,CDN 却挂了,又需要降级处理。
更常见的是,公共 CDN 的域名并不在用户的 HSTS 列表中。用户信任我们,但不信任其他域名,这也可能导致 CDN 资源加载失败。
首屏大小问题
绝大多数人使用公共 CDN 的方式,都是在首页直接通过 script 全局引入。这种模式本质上就是最原始的手动维护依赖方式,完全违背了现代按需加载的工程理念。
如果是 jQuery 这类大概率首屏刚需的依赖,全局引入尚可接受。但如果是 lodash、工具类库、非核心组件库——这些大概率是页面二级、三级路由才会用到,或者应该动态按需引入的——将它们强行挂载到首页,会直接增大首屏资源体积、增加首屏请求数、阻塞页面渲染,白白拖慢首屏加载速度,完全得不偿失。
工程复杂度
如果在首屏使用,你可能会这样写:
');
}
// 上面代码虽然勉强实现降级,但是由于是同步加载,是牺牲性能的。
如果并非在首屏使用,还需要考虑失败降级、SRI、兼容性等问题——整体复杂度提升不止一个量级。这里不再展开,否则文章会偏离主题。简单列一个表格即可窥见其复杂度。
| 场景 | 处理方案 |
|---|---|
支持 type="importmap": integrity |
使用 importmap integrity |
| 支持 top-level-await 和 script integrity | 别名到一个虚拟模块,虚拟模块用 top-level-await 动态创建 |
| 不想使用构建技巧,就想使用原生 import | 基于原生 import 写模块化运行时,fetch 拿数据,运行时校验 integrity,运行时解析转化源代码,生成 blob url,创建 script module,里面使用 import * |
| 不支持 top-level-await 或原生 import | 使用传统模块化运行时 |
如果非要给出一个推荐方案,我会选择使用 top-level-await,不支持的浏览器则用传统模块化运行时做降级。
总结
公共 CDN 仅适合在首屏依赖且工程化不足的场景下使用。例如传统的 jQuery 项目:全局引入、手动 babel 转换,这种情况非常适合公共 CDN。但凡工程化能力较强,即便使用 jQuery 也能通过按需构建玩出更多花样。
题外话
如果是面试场景,主考官问到“如何优化前端性能”,我建议你还是回答使用公共 CDN。这不就是妥妥的八股题吗?你要是说公共 CDN 不好,岂不是打了面试官的脸?
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
科研人员必读:多肽、蛋白质、重组蛋白区别及定制指南
Section 01 多肽 VS 蛋白质 VS 重组蛋白 多肽、蛋白质和重组蛋白,本质上是同宗同源的东西——都是氨基酸串起来的生物大分子。三者的核心区别,说到底无非是三个维度:分子大小、折叠形态,以及生产方式。 接下来是一张清晰的对比图,帮你快速建立直觉: 
