自动使用jsdelivr CDN 加速hexo的图片等静态资源加载

独立博客的一个十分重要的问题就是图片等静态资源的加载速度,这对于访问博客的体验而言十分的重要,尤其在中国,如果使用国外的服务器而域名也没有备案的话,图片的加载速度能够让人怀疑人生。

而jsDelivr是一个著名的开源CDN项目,它闻名于免费的javascript CDN,全球部署尤其是在中国也有备案的站点。但是少有人了解它提供的其他免费服务,其中包括一项是对Github仓库的CDN加速,而这便可用来作为我们博客的图片CDN。

jsDelivr是什么

如上面所介绍的,jsDelivr为Github仓库、npm包、WordPress插件等提供了免费的CDN加速服务,它的资金来源于包括Cloudflare在内的众多Sponsors,使用了多家CDN厂商的站点组成了自己的全球混合CDN。如Figure 1所示,从w3techs网站目前的调查来说,在已知使用javascript CDN的网站中,12.4%的网站选择jsDelivr的javascript脚本的CDN加载服务。虽然不如使用使用cdnjs的网站多,但乘以庞大的基数,仍然有不可计量的网站使用了jsDelivr。而其jsDelivr比起cdnjs的巨大优势就是在中国境内也有备案的CDN(由网宿科技提供,jsDelivr的sponsors之一),访问延迟和速度在国内均优于cdnjs。因此本站的所有javascript脚本和CSS样式表都使用jsDelivr加载。

Figure 1

Figure 1: 使用各javascript CDN的网站比例,灰色条代表占所有网站的比例,绿色条代表占统计中的网站的比例

另外和本文最相关的是,jsDelivr提供对Github的全公开仓库CDN加速,意思是只要是Github上有的公开仓库,你都可以通过jsDelivr的CDN链接访问。

举个例子,如果你的仓库中的某个文件的url为

1
https://github.com/<username>/<repo>/blob/master/<filename>

则你可以通过下面的jsDelivr的url访问,其中version可以是commit id

1
https://cdn.jsdelivr.net/gh/<username>/<repo>[@version]/<filename>

那么聪明的你一定想到,这样我们就可以结合Github和jsDelivr,给自己的网站创造一个免费的CDN,所有的js脚本、CSS样式表、图片等静态资源都可以通过jsDelivr的CDN来访问。

自动化部署到CDN

知道了原理之后,最简单的使用方法就是,在Github上创建一个仓库,然后将需要在网站上使用的图片push上去,再在文章中直接使用CDN上对应该文件的url。

这种方法对于图片不是很多时还是比较方便的,但是我的想法是,虽然jsDelivr目前不太可能解散,但是我们还是要做好准备。我们需要一种能够方便的切换是否使用jsDelivr的CDN的方法。

因此我开发了一个hexo的插件hexo-cdn-jsdelivr,可以自动地将原来文章的本地图片推送到Github的仓库上,并且将生成的html文件中的图片链接替换为CDN链接。另外,还可以指定需要上传的静态资源文件夹,将其中的文件都上传到Github。还可以使用模板方法修改网页中的javascript脚本、CSS样式表和图片等的url为CDN url。

如果感兴趣的话,更详细的信息可以去阅读该项目的readme文档。

为了写这个插件,我通过阅读Hexo相关项目的源代码来学习node.js,因此估计还是会有不少地方是不合理的设计。Hexo的项目代码只有最基本的文档,不存在比较详细的API文档,因此经常是要写某个相关的功能,就去看一看用到类似功能的源码是怎么写的,我为此大概下载了10个hexo相关的仓库源码。

现在,我网站上除了html文件外的所有静态资源都会自动推送到Github仓库,然后使用jsDelivr的CDN链接来加载静态资源。访问的延迟和下载速度有肉眼可见的提升。

图片展示

既然有了这样一个出色的CDN,就算我本来不需要用太多图片,这篇文章也是要展示一下功能的,下面上图。所有的图片都是至少4K级别,用了一定的压缩,每张图片的大小在1~2MB。

其中第一张图片是我自己渲染的,用到了n+e的青花纹理。其他的图片都是来自于开放使用的免费图库。

fig1

fig2

fig3

fig4

fig5

fig6

fig7

不知道你加载完这些图片用了多久,Figure 2显示了我的浏览器加载这些图片的时间,此时我用的是4G的手机热点来上网,延迟属于比较大的状态,在不到2.4秒内所有图片都已经下载完成了,我不确定我测试时jsDelivr的CDN有没有cache这些图片,毕竟是我刚刚上传的。如果你的在国内,并且你的代理上网工具不够强劲的话,我想直接访问会比代理访问更快。

fig8

Figure 2: 加载完图片的用时统计,已禁用浏览器缓存

闲话一句,这些图是我个人认为比较含有于我而言的美感的图片,如果让我实地去旅游观景,我的肉眼未必能够捕捉到这样的光影效果和美感,即使是没有调色的摄影照片,我也认为我的肉眼可能是捕捉不到那样的构图与画面的。但是如果你让我去做这个捕捉瞬间的摄影师,我尊重他们的工作,却认为我可能不适合。

当我拿起镜头的时候,我就站在捕捉画面的角度来观景选景,而不会以自身的审美体验作为第一出发点。我也许能够捕捉到一些尚可的画面,但是我自己却缺失了一段不带目的性的审美体验。因此我自己是倾向于体验式的审美而非记录式的审美。

这是否属于对服务的滥用

根据jsDelivr的Github仓库下的issue #18229,开发者之一Dmitriy Akulov目前对使用Github和jsDelivr作为CDN的回应是

I agree, we need to make this clearer. I think we already have a task for this. To answer your question it depends. In most cases if its allowed by Github then it is by jsDelivr as well. If you host thousands of images of your dog and use Github+jsDelivr as an alternative to Dropbox then that is against the rules. But if its javascript, css and images requires for the site to operate then its fine.

We will try to make this clearer

意即,目前还没有明确的使用规则确定清晰的使用界限,但是他认为凡是Github允许的jsDelivr也应该允许。他举个例子说,如果把Github和jsDelivr当作网盘存几千张狗的照片,应该属于滥用;但是如果只是存网站需要的一些文件如js脚本、CSS、图片那应该是允许的。

在他的观念中,只要我们不存过分多的文件,那应该是没有问题的,但是多少是过分多呢?这就需要将来更明确的使用规则推出了(这都多少年了还没有个使用条款,不可思议,说明没多少人滥用到把jsDelivr干倒下)。不过我想个人博客用的资源应该是不构成问题的。

可见的未来中还不用担心这个CDN突然不能用了,一是jsDelivr关闭的可能性很小,二是目前它的开发人员应该不认为在博客中使用其作为CDN是滥用行为。

最后

感谢jsDelivr提供了这样一个出众的开源CDN项目,让个人博客可以在全球各地都有出色的访问体验。