讀者 Peter Cheng 問到:

當網頁要引用 jQuery、Vue 等開源程式庫的 .js/.css 檔案,是要給 CDN 網址直接下載,還是該抓下來放自家網站?

CDN 速度快省頻寬,但自然也存在缺點。這是個好問題,隨著時代演變技術更迭,優缺點的影響或重要性可能已大不相同。(就像昨天提到,在 HTTP/2 普及後 Bundle 必要性該被重新評估) 既然提起這個議題,這篇就試著用現今網站管理的角度重新審視。

thumbnail

前端發展多年,如今 JavaScript 大小開源程式庫幾乎都能從三大 CDN (CDNJS、jsDelivr、unpkg) 上找到(三者的比較可參考這篇),在網頁加一行 <script src="https://unpkg.com/vue"> 即插即用,簡單又方便。除此之外,從 CDN 下載還具備以下優點:

  1. 速度快:CDN 伺服器遍佈全球,客戶端會從離自己最近的伺服器下載。若訪客來自全球,外國訪客從當地 CDN 下載一定比越洋到你的網站抓快。
  2. 省頻寬:客戶端從 CDN 下載不會耗用到你的對外頻寬,頻寬有上限流量要花錢,若為熱門網站每天有千上萬人造訪,幾十數百 KB 的 JavaScript 積少成多也是很驚人的。
  3. 可共用快取:若使用者剛在其他網站下載同一 CDN 內容,連到你的網站時連下載動作都可以省,直接用快取內容,有效率又環保
    [2025-02-18 更新]基於資安考量,現代瀏覽器已加入快取分區觀念,不同網站間已不會共用同一 CDN 的快取內容。至於透過共用快取進行攻擊的手法可參考前端旁路攻擊:XSLeaks,感謝胡立補充。

不過,使用 CDN 會帶來一些問題,不應被忽視:

  1. CDN 的設備與管理一般會比我們專業,但並非永遠不會故障,例如 2024/4/12 unpkg 就曾當掉好幾小時。若網站本身健全卻因 CDN 壞掉被牽連,被罵時會特別堵爛吧?
  2. CDN 的程式庫版本會自動更新,是好事也是壞事。我就踩過https://unpkg.com/vue@next 失效的雷,放在自家可避免這類非預期的版本升級,可靠性高些。
  3. 從資安的角度:萬一 CDN 被入侵或惡意利用,程式庫遭置換掉或加料,惡意程式便會長驅直入在我們的網頁上執行,猶如木馬屠城。理論上主流 CDN 的資安防護不致太差(甚至比許多中小網站都強),但通常在檢討時,仍會將這類風險納入考量。
  4. 另外,CDN 有可能會蒐集使用者資訊,不利於隱私保護;若未設定 Referrer-Policy,CDN 亦可透過 Referrer Header 蒐集我們網站的使用狀況。不過,依我個人觀點,CDNJS、jsDelivr、unpkg 這類 CDN 作惡的機率不高,而我們的網站也很少值錢到變成重點觀察對象,哈!但若是一些較不常見的 CDN 來源,就值得提高警覺。

    【註1】針對 3, 4 點,目前已有因應做法,在引用時加註 Integrity 註明檔案雜湊值及指定 crossorigin="anonymous"、referrerpolicy="no-referrer" 原則,如此即可防止檔案內容被竄改,避免 CDN 蒐集使用者及網站活動資訊。CDNJS 的 Copy Script Tag 已內建,複製內容已自動加上,例如:<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.5.13/vue.global.prod.min.js" integrity="sha512-66fV4MXSQdGN0KQxZ0Bw627HalhTQYQbOoF24EtMXN2FaAoKMgAZ7nDi77d9xWwrRjEEUfE+7rxjTt+cA2IuJA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> (感謝 Peter Cheng 補充)
    【註2】提供 CDN 引發隱私爭議的極端案例供參考:使用 Google 字型 CDN 未揭露蒐集 IP 行為被 GDPR 裁罰。(感謝 Yi-Chun Lu 補充)
  5. 前面提過 HTTP/2 可以很有效率地處理同網站資源的同時下載(參考:實測 HTTP/2 網頁加速效果),若 JavaScript/CSS 分散到太多個 CDN,則會喪失部分優勢。不過,由於常用的 CDN 也就那幾個,這部分影響應該有限。
  6. 有些網路控管環境採白名單方式申請開通,增加 CDN 來源需額外申請;另外有些網路過濾政策會將 CDN 視為風險來源,預設封鎖。這些狀況也值得納入考量。

以上就是我所想到使用 CDN 的優勢與缺點。若問我的看法,我認為除非網站強調全球性,對速度敏感或熱門到頻寬流量成本需被觀注;考量從 CDN 下載 .js/.css 會增加故障變數、造成非預期的版本異動、可能因網路管制受阻,加上會增加額外資安風險,我自己偏向將 JavaScript / CSS 檔案抓回來簽入版控,有助於管控及降低不確定因素。若要用 CDN,建議 Script 標籤加上 Integrity 及 no-referrer Attribute 防止竄改及洩漏網站活動資訊。
註:ASP.NET 專案要從 CDN 下載 .js/.css,可善用 LibMan。參考:Visual Studio GUIlibman CLI

When deciding whether to use a CDN for JavaScript/CSS libraries or host them locally, consider the following: CDNs offer faster global access, save bandwidth, and leverage shared caching. However, they introduce potential issues like downtime, automatic updates, security risks, and privacy concerns. For better control and reliability, hosting files locally is often preferred.


Comments

# by yoyo

版本管理問題,跟container image一樣 在Production環境一定是指定版號,不用模糊的tag

# by Leon

我覺得瀏覽器應該要內建這些熱門套件,熱門字體也內建一下,頻寬加倍省,反應加倍快。

Post a comment