由于cdn.jsdelivr.net在国内不太稳定,替代的jsd.cdn.zzko.cn稳定性稍好,但是也不是100%稳定,因而需要一个脚本实时切换到合适的CDN。freecdn-js能实现这个需求。freecdn-js是纯前端的,使用service worker,只需要插入一段js代码就可以,因此改造成本很低。但是我的文件(图片、js等)储存在GitHub图床,而freecdn-js本身需要被加速的文件的hash值,因此需要自己写脚本处理下载图片并计算。因为图片等文件的cdn链接是直接写在.md文件中的,所以写了一个正则脚本来提取cdn的链接。
脚本使用方法
我写的脚本发布在GitHub上,匹配了、{%link%}、{%image%}、headimg四个tag。脚本请到GitHub下载。
可以屏蔽相关cdn(更改host或用v2rayN路由屏蔽)测试freecdn-js是否能切换备用cdn。
扩展教程在这里:使用npm空间存放图片和html并利用cdn加速
需要的包版本
1 | urllib3 1.25.11 |
以下引用GitHub上的README.md文件
Windows的大坑!
此为大坑!务必阅读
如果利用Windows来写博客,那么提交git的时候会出现LF will be replaced by CRLF the next time Git touches it的提示,CR(回车)就是\r,LF(换行)就是\n,Windows平台默认换行符就是CRLF(\r\n),此变换会导致本地文件的hash和存放在npm或者git空间的文件的hash不一致;需要运行以下命令行:
1 | #提交检出均不转换 |
适用于Windows系统,且只在Windows上开发的情况。在提交、检出时不会对CRLF/LF换行符进行转换
接入透明模式【可选】
建议暂时不配置
经过一段时间的观察,透明模式会起到严重的“减速”作用,FCP延后非常多。
本来想试试http2服务器一次性推送freecdn.js和相关的txt的,结果发现chrome从106版本就不支持http2服务器推送了。谷歌给出的替代方案是使用103 early hints,但是nginx现在还不支持。谷歌给出的另一个代替方案是传统的link rel=preload。link rel=preload确实可以在一次性推送freecdn.js和相关的txt,但是在安装了Service Worker之后依然会再次加载freecdn.js和相关的txt,结果就是速度没变,流量还浪费不少。又或者是我设置的问题,,,
配置透明模式
freecdn透明模式的优势和配置文件看下面的链接
博客使用render.com托管静态资源;因为freecdn的透明模式仅仅提供了nginx配置,而且render刚刚好也支持docker,那就直接用nginx-docker吧。
render.com免费提供每月100g流量、750小时实例时间、500min构建时间、0.1cpu和512mRAM
Render spins down a Free web service that goes 15 minutes without receiving inbound traffic. Render spins the service back up whenever it next receives a request to process.Learn more
首先在你的博客根目录下的source创建Dockerfile文件。(生成博客的时候会把source内的文件移动到将要被上传到repo的文件夹内)
1 | FROM nginx |
然后下载freecdn的两个配置文件,freecdn-boot.conf和nginx.conf,同样放在博客根目录,只需要改动nginx.conf。
1 | events { |
br和gzip压缩在render平台自动开启,见官网docs。
上传到GitHub reop(hexo d)后,在render.com创建一个web service,然后选择你的repo部署就可以了。
白嫖到底!
由于免费的render web service会在15分钟之内没有连接访问的情况下断开,并在下一次访问之后重启启动,而重新启动需要较长时间;因此用cf worker去定时访问网站。
需要一个cf账号,没有的先去注册
点击左侧的worker and page,创建一个worker,这个时候不能改动代码,先确认创建。之后点击触发器标签,并找到Cron 触发器,填入3/13 * * * *,这行代码表示在每个小时过3分钟之后触发一次定时器,然后每过13分钟再触发一次(如果和每个小时过3分钟这一条件冲突,则重置触发器,即在每个小时过3分钟之后再次触发,如此反复)。设置效果如下图所示
之后编辑worker。点击快速编辑,写入以下代码
1 | export default { |
async scheduled表时当触发器触发时运行代码(题外话:这是不是可以当作一个免费的攻击服务器??),fetch代表访问你的网站的资源,await似乎是必需的,因为没有await的话在render的log里面看不到worker的访问记录。










