2022-11-24 基于竞速的 CDN 资源加载方案–以 Vite 插件为例
参考:
vite:https://cn.vitejs.dev/guide/
vite-plugin-fast-cdn-import:https://github.com/CaoMeiYouRen/vite-plugin-fast-cdn-import
前言
关于写插件这个想法,最早可以追溯到 jsdelivr 在中国大陆暂时停止服务的时候(2022 年 5 月,现在貌似恢复了),当时因为笔者大部分网页都或多或少有使用过 jsdelivr 作为 CDN 来加载 js、css、img 资源,因此 jsdelivr 暂时无法访问对笔者的网页基本上是毁灭性的打击。
经过此事后,我就在想,如果能够自动选择最快(且有效)的 CDN,那么就可以规避这个问题,也能解决不同 CDN 加载速度差异的问题,故写了这个插件。
开始
本插件名为 vite-plugin-fast-cdn-import
,意为“最快的 CDN”,表达了本插件对于速度的追求。
安装方式同一般的 npm 插件。
1 | npm install vite-plugin-fast-cdn-import |
浏览器要求情况(同 vite3)
- Chrome >=87
- Firefox >=78
- Safari >=13
- Edge >=88
使用
1 | // vite.config.ts |
基本原理
在指定的多个 CDN 源中,会使用 fetch
对第一个包的地址进行一次 HEAD
请求,得出最快的源(同时未返回的请求会直接 abort
,中断请求),剩余的包不再竞速,直接采用该结果。
第一次的竞速结果会缓存在 localStorage
中,直到包的数量或版本号发生了改变,此时缓存失效,重复上述流程。
存在的问题
凡事都有代价,本项目虽然解决了一个问题,但仍有其他问题。
由本项目的竞速原理可知,只会对第一个包进行竞速,因此可能会出现第一个包在某个 CDN 源是存在的,后续的包不存在,导致加载失败,故需要开发者手动对所有 CDN 源进行校验,确保所有的包都能在所有 CDN 源加载。可在配置中设置allRace
为true
启用全量竞速,会对每一个包都单独竞速。虽然可以解决包不存在的问题,但也多了竞速的耗时,请开发者自行权衡。- 由于用到了
fetch
,所以在不支持fetch
的浏览器下无法竞速,也就无法加载包。fetch
支持情况请参考:https://caniuse.com/fetch
- 由于用到了
Promise.race
、Promise.any
,所以在不支持Promise.race
、Promise.any
的浏览器中需要polyfill
才能使用-
Promise.race
支持情况请参考:https://caniuse.com/mdn-javascript_builtins_promise_race -
Promise.any
支持情况请参考:https://caniuse.com/mdn-javascript_builtins_promise_any
-
- 当缓存里的 CDN 源失效时,无法自动检测出失效的 CDN 源,此时会出现加载资源失败的情况。—— 该问题可通过手动修改
cacheKey
来解决。
本文作者:草梅友仁
本文地址: https://blog.cmyr.ltd/archives/42e02b35.html
版权声明:转载请注明出处!