2026年了,请停止相信“公共 CDN 能提升性能”

发布时间:2026/7/7 2:30:05

2026年了,请停止相信“公共 CDN 能提升性能” 注意今天我们要讨论的是公共 CDN而不是自建 CDN 或云厂商的 CDN。公共 CDN 已经没有缓存优势对用户来说该加载数据量一点不会减少。早年公共 CDN 能提速的核心逻辑非常简单用户访问过任意使用同款 CDN 资源的网站本地就会缓存该库再次访问你的网站可以直接命中缓存、零下载。但这套逻辑在现代浏览器机制和前端生态下早已荡然无存。第一Chrome 86 正式启用浏览器缓存分区机制Firefox、Safari 等主流浏览器也同步跟进。不同站点的缓存是被隔离的用户仍然需要重新下载脚本所以公共CDN的那点缓存优势早已过时。第二即便退一步来说用户使用 Chrome86 以下的老旧版本现在已经不是千篇一律的jQuery时代了现在是前端构建时代要碰巧遇到之前访问过的网站刚好用了同供应商、同库、同版本、同格式的概率也比较低。对用户来说要加载数据量有可能更大公共 CDN 提供的资源都是固定全量打包产物。而现代前端工程最大的优势就是可以基于业务场景做极致按需构建。进一步说一切构建优化公共 CDN 都无法享用。tree-shaking项目中未使用的冗余代码、废弃逻辑大幅精简资源体积。公共 CDN 的全量包包含库的全部功能代码哪怕项目只用到 10% 能力也需要加载 100% 的代码冗余度极高。打包工程构建可将多个小型同类依赖合并为单个 chunk减少请求数量也可根据路由、功能拆分资源粒度实现按需加载。公共 CDN 是固定打包产物无法适配项目专属的合并、拆分策略。依赖自身的构建开关大量主流库提供了环境裁剪、功能开关的构建配置可按需关闭无用模块、兼容代码。比如 Vue 的__VUE_OPTIONS_API__。公共 CDN 为了适配全网所有场景只能保留全部功能、开启全量兼容无法做定制化裁剪。按条件加载现代前端工程可同时输出多份产物不同浏览器运行不同产物。比如业界常用 module/nomodule 实现条件加载。公共 CDN 大多只提供统一大包要么产物臃肿要么兼容性差。自动 polfill 引入一个优雅的构建过程是会自动扫描依赖然后注入特定polyfill的。但是外部依赖就无法扫描到了要么就全局引入polyfill要么只能人肉判断polyfill。深层依赖预加载在动态import时现代前端工程能够同时请求深层依赖。使用公共 CDN只有当前依赖请求完才知道有哪些深层依赖。公共 CDN 的网络真就比主站好吗我看未必公共 CDN 节点质量不可控、运营商链路不确定。弱网、跨国、小众地区可能比业务自研 CDN / 源站更慢。使用公共CDN还会带来额外的DNS解析、TLS握手、TCP连接建立、CORS校验等开销。如果主站已经用了HTTP/2、3的多路复用同域更能提升连接复用效率进一步拉开差距。就我个人平时的上网体验来看打开慢的网站几乎都在用jsDelivr。增加供应链风险你的小网站可能黑客不感兴趣但公共 CDN 可是黑客眼中的香饽饽。历史上开源供应链攻击层出不穷公共 CDN 极易面临劫持、篡改、停服、投毒风险。为了防御我们被迫使用SRI (Subresource Integrity)。但 SRI 是把双刃剑。一旦 CDN 资源被篡改或者哈希不匹配浏览器会直接拒绝加载。这就像是为了防止食物中毒直接把所有外卖都倒进垃圾桶。用户结果是什么页面白屏。于是乎为了用户体验我们又要写“降级逻辑”检测 CDN 挂了 - 加载本地备用资源。绕了一大圈不仅代码变复杂了用户还多走了一条无效的失败路径速度反而更慢了。这真是“捡了芝麻丢了西瓜”。公共 CDN 和主站的 https 加密协议版本可能不同。HTTPS 的加密协议在不断更新但有一个核心矛盾协议越安全支持面越窄支持面越广越不安全。当你的主站和公共 CDN 的 https 加密协议版本不同时有可能你的主站支持的用户更广公共 CDN 支持的用户更窄导致主站正常CDN 挂了又要降级了哎。更常见的是公共 CDN 的域名不在用户的 HSTS 列表中。这等于是用户相信我们但不相信别人也会导致CDN 挂了。首屏大小绝大多数人使用公共 CDN 的方式都是在首页直接通过 script 全局引入。这种模式本质上就是最原始的手动维护依赖方式完全违背现代按需加载的工程理念。如果是 jQuery 这类大概率首屏刚需的依赖全局引入尚且可以接受。但如果是 lodash、工具类库、非核心组件库大概率是页面二级、三级路由才会用到或动态按需引入。将非首屏依赖强行挂载到首页会直接增大首屏资源体积、增加首屏请求数、阻塞页面渲染白白拖慢首屏加载速度完全得不偿失。工程复杂度如果在首屏你可能通常这样写scriptsrchttps://code.jquery.com/jquery-3.7.1.min.jsintegritysha384-这是一个示例哈希故意不匹配crossoriginanonymous/scriptscriptif(!self.$){document.write(script src/res/jquery.min.js/script); } // 上面代码虽然勉强实现降级但是由于是同步加载是牺牲性能的。/script如果不在首屏的话还要考虑失败降级、SRI、兼容性整个复杂度提升不是一点半点。这里我就不展开说了展开文章就跑题了。我简单地列一个表格就能窥见其复杂度。场景处理方案支持typeimportmap: 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不好岂不是打面试官的脸吗

相关新闻