使用 jsDelivr 免費加速 GitHub Pages 博客的靜態資源

挺久以前就有網友給我的 GitHub Pages 博客模板提 Issue,說希望能增加 CDN 用於加速靜態資源的加載,由於懶,一直沒有動。

最近偶爾要打開自己博客看下 Wiki 的時候,要等挺久,比較痛苦,碰巧昨天晚上看到這樣一篇帖子:GitHub 圖牀的正確用法,通過 jsDelivr CDN 全球加速,感覺很適合我的需求場景,於是決定趁這幾天休假將這個改造一下。

先看效果

以下改造前後的加載情況都是在 Edge 瀏覽器禁用緩存後錄製的,錄製時間段很接近,從本地訪問兩個 GitHub Pages 服務的原始響應速度應該類似。

改造前加載

before use cdn

注:由於改造前沒有保留加載圖,所以這是截的一個使用相同模板的朋友的首頁加載情況。

可以看到耗時最長的兩個請求時間達到了 12 秒左右,而且很多資源的加載時間在 1 秒以上,頁面完成加載時間長達 15 秒多……估計一般的訪客是沒這個耐心等待的。

改造後加載

after use cdn

這樣一對比效果還是很明顯的。改造過後耗時最長的是兩個沒辦法走 CDN 的請求,而走 CDN 的那些資源加載時間基本都沒超過 60 毫秒,頁面完成加載時間縮短到了 3 秒以內。

當然,因爲頁面自身還是在 GitHub Pages 託管,有時候首個請求還是會挺久才返回。

改造後的效果可以打開 https://mazhuang.org 體驗。

方案考慮

優化獨立博客的加載速度有一些不同的思路,對應不同的方案:

  1. 優化博客代碼,精簡需要加載的資源;
  2. 將博客部署到國內訪問快的服務器上;
  3. 部署到國內的代碼託管平臺,比如 Gitee 和 Coding 等;
  4. 採用 CDN 加速;
  5. 等等。

其中 2 和 3 我不想考慮,還是期望只在 GitHub 上管理博客,所以 1 和 4 是優化方向,本文對應的就是 4 的部分。

而採用 CDN 加速的方案,可以考慮

  • 將公共庫改爲直接引用公共 CDN 鏈接;

  • 自己編寫和修改的靜態資源自己去託管在一個 CDN 服務上。

    有一些 CDN 服務商提供一定的免費額度,可以按喜好選用,或者選擇付費服務。這裏我沒有糾結,看完文首提到的那篇文章,去看了下 jsDelivr 的介紹後覺得靠譜:它原生支持使用 GitHub 項目裏的資源,什麼都不用配置,更重要的是免費,在國內有節點,而且速度還不錯(官網上也把 works in China 作爲一個賣點的),遂決定直接用它。

jsDelivr 支持的 GitHub 資源的方式

jsDelivr 對 GitHub 的支持是作爲重要特性來宣傳的,官網的介紹鏈接:https://www.jsdelivr.com/features#gh,以下是一些認爲需要了解的知識的小結:

這裏以我託管博客的 GitHub 倉庫爲例,地址是 https://github.com/mzlogin/mzlogin.github.io,那它裏面的資源可以直接以 https://cdn.jsdelivr.net/gh/mzlogin/mzlogin.github.io/ + 倉庫裏的文件路徑 來訪問。

比如倉庫裏有一個 js 文件 assets/js/main.js,那麼它可以用 CDN 鏈接 https://cdn.jsdelivr.net/gh/mzlogin/mzlogin.github.io/assets/js/main.js 來訪問。

另外還支持一些高級用法,比如:

  1. 指定 release 版本號/提交 sha1/分支名稱,例如指定獲取該倉庫的名稱爲 1.2.0v1.2.0 的 release 版本資源:

    https://cdn.jsdelivr.net/gh/mzlogin/[email protected]/assets/js/main.js
    

    如果指定版本爲 1 或者 1.2,那它會自動匹配到這個範圍內的最新版本號。

    也可以不指定版本或者指定版本爲 latest,這樣總是使用最新版本的資源。

  2. 壓縮資源,在 js/css 文件後綴前面加上 .min

    https://cdn.jsdelivr.net/gh/mzlogin/[email protected]/assets/js/main.min.js
    
  3. 合併多個文件,用 combine/file1,file2,file3 格式的鏈接:

    https://cdn.jsdelivr.net/combine/gh/mzlogin/[email protected]/assets/js/main.min.js,gh/mzlogin/[email protected]/assets/js/simple-jekyll-search.min.js
    

壓縮資源、合併文件的 CDN 鏈接在第一次有人訪問時可能比較慢,後面再有人訪問就快了。

其它知識點:

  • 可以通過 https://cdn.jsdelivr.net/combine/gh/mzlogin/mzlogin.github.io[@<版本號>]/[<文件夾>/] 這樣的路徑瀏覽緩存文件列表;
  • 可以訪問 https://purge.jsdelivr.net/gh/mzlogin/[email protected]/assets/js/main.js 來清除指定文件的緩存;(將引用的 CDN 鏈接裏的 cdn 改成 purge 就是了)
  • 可以訪問 https://data.jsdelivr.com/v1/package/gh/mzlogin/mzlogin.github.io 來查看 CDN 上的 tags 和 versions 列表,更多數據接口參數參見 https://github.com/jsdelivr/data.jsdelivr.com

改造步驟

下面是記錄具體改造博客模板的步驟:

  1. 在 _config.yml 文件中添加控制開關:

    # 對 css 和 js 資源的 cdn 加速配置
    cdn:
        jsdelivr:
            enabled: true
    
  2. 修改 _layouts 裏的文件,給名爲 assets_base_url 的變量賦值,用它來代表加載靜態資源的根路徑:

    {% raw %}

    {% assign assets_base_url = site.url %}
    {% if site.cdn.jsdelivr.enabled %}
        {% assign assets_base_url = "https://cdn.jsdelivr.net/gh/" | append: site.repository %}
    {% endif %}
    

    {% endraw %}

  3. 修改以前直接用 {% raw %}{{ site.url }}{% endraw %} 拼接的靜態資源引用鏈接,替換爲 {% raw %}{{ assets_base_url }}{% endraw %},比如 _includes/header.html 裏:

    {% raw %}

    - <link rel="stylesheet" href="{{ site.url }}/assets/css/posts/index.css">
    + <link rel="stylesheet" href="{{ assets_base_url }}/assets/css/posts/index.css">
    

    {% endraw %}

這樣萬一哪天 CDN 出了點什麼狀況,我們也可以很方便地通過一個開關就切回自已的資源鏈接恢復服務。

主要就是這類修改,當然涉及的地方有多處,以上只是舉一處例子記錄示意,改造過程和改造後的代碼可以參考我的博客倉庫 https://github.com/mzlogin/mzlogin.github.io

現存問題

  • 如果項目曾經打過 tag,那麼新增/修改靜態資源後,需要刷新 CDN 緩存的話,需要打個新 tag;

    一般發生在修改了博客模板的 js/css 以後。我也還在摸索如何省去這一步的方法。

    Update: 我後來採用的解決方法是刪除了所有的 tag,這樣以前的 release 就變成了 Draft,對外是不可見的,因爲我這個倉庫不需要對外可見的 release,所以這個問題也就解決了,不需要再操心刷新 CDN 的問題了。

參考鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章