此前折腾 WordPress 时,利用 WP Super Cache + 七牛镜像存储 完美实现了 CDN 加速(教程)。迁移到 Ghost 后,也想这么做。研究一番后,也确实做到了,这里简单介绍一下研究过程,以 Ghost v0.5.3
及其默认主题 Casper v1.1
为例。
Asset Helper
修改主题时发现很多静态资源是通过 {{asset "css/screen.css"}}
加载的(文档)。如果将 asset
的返回改为 CDN 的地址,就可以实现 CDN 加速了。由于 Ghost 尚未发布插件功能,所以只能直接修改源码了。
几经搜索,终于在 core/server/helpers/asset.js
找到了这个函数。简单改改就可以返回 CDN 地址啦。
修改前:
asset = function (context, options) {
var output = '',
修改后:
asset = function (context, options) {
var output = 'http://netputer.qiniudn.com',
// 将「netputer」替换为你的七牛 CDN 域名,结尾不要加「/」
访问首页观察效果,这种方法确实可以实现 CDN 加速静态资源,但仅限被 asset
处理过的静态资源文件,并不完美。于是继续研究。
Base Tag
观察网页源码,发现几乎所有静态资源都是相对路径。通过 <base>
给这些相对路径的静态资源指定基准域名为 CDN 的域名,从而实现所有静态资源都能被 CDN 加速。
修改方法也不难,对于默认主题来说,只需修改 content/themes/casper/default.hbs
的 <head>
部分:
修改前:
<meta name="HandheldFriendly" content="True" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="shortcut icon" href="{{asset "favicon.ico"}}">
修改后:
<meta name="HandheldFriendly" content="True" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="http://netputer.qiniudn.com/">
<!-- 将「netputer」替换为你的七牛 CDN 域名 -->
<link rel="shortcut icon" href="{{asset "favicon.ico"}}">
访问首页观察效果,发现静态资源确实全都被 CDN 加速了,上传的图片也不例外。但是很多链接是相对路径的,都被指向 CDN 域名了,这并不是我们所期望的。
不过只要把这些相对路径都替换为绝对路径,就可以避免这个问题了。由于涉及的改动比较零散,可以参考我的 Diff 进行修改。
再次访问首页观察效果,现在的效果已经接近完美了。
Advanced
既然是进阶,不需要太过详细,简单表达一下思路。
CDN Cache
Ghost 是通过 URL 加参数避免缓存( screen.css?v=123456
),但这对七牛 CDN 来说就没有作用了。如果将来我们修改了静态资源文件,该如何更新呢?
其实可以将 asset
返回的路径的文件名修改为唯一不重复的(类似 screen.123456.css
),再配合 Nginx 规则将其指向正确位置。但是挺麻烦的,还不如每次修改就到后台删掉此前已被缓存的资源。所以就没有继续研究下去了。
HTTPS CDN
七牛 CDN 也是支持 HTTPS 的,但不是 *.qiniudn.com
。你需要到后台绑定 dn-*.qbox.me
的域名才可以使用 HTTPS CDN 。
Development Environment
以上修改的方法是对所有运行环境生效的,可能会对本地调试会造成影响。好在 Ghost 源码中可以通过 isProduction
判断当前运行环境是否为生产环境。
对于第一种方法,可以在 core/server/helpers/asset.js
中加上这么一段逻辑:
if (utils.isProduction) {
output = 'http://netputer.qiniudn.com';
}
对于第二种方法,可以将 <base>
加到 core/server/helpers/ghost_head.js
中:
if (require('./utils').isProduction) {
head.push('<base href="http://netputer.qiniudn.com/">');
}
其实还有第三种方法,也是最一种彻底的方法:找到最终输出页面内容的函数,对静态资源路径进行替换。但是感觉那样容易误杀,就没有那么去做。
P.s. 将研究过程整理成文后发现,这些方法都很蛋疼。只能期待 Ghost 的插件功能早日发布了。