前端靜態資源部署

前幾天廠里的網突然渣掉了,某些網頁變得極度卡頓,但是劃水網站依舊流暢;我覺得很有趣就打開 DevTools 對比了一下,結果看到某卡頓網頁的 Network 狀況如下,我大概猜到了一些緣由。這期就借機講講前端部署里的一些小技巧吧。

Network

原始前端

OK,這期討論的原始前端當然也沒那么“原始”,我無意追述到 JSP,thymeleaf 這類傳統后端渲染的技術。只是說“原始前端”開發比較簡單,只需要一頁文本編輯器,一份 html 模版和一款打包工具(webpack);部署更簡單,webpack 構建并打包出 html、css、js,然后一股腦丟到服務器上就行。當請求到來時,服務器返回 index.html, 然后再把它的相關引用(js、css)返回給客戶端即可。

Server

但是這里有個問題是,引用文件名——onion.js——是固定的:一旦部署更新后,就得防止客戶端緩存舊文件,所以一般會設置Cache-Control: no-cache。這就是文章開頭提到的一個問題,每次打開頁面都得重新加載一遍引用文件,一旦網絡渣渣了,首頁渲染就會十分緩慢。

版本管理

看樣子緩存策略還是需要保留的,可如何兼顧更新呢?有人就想到了給引用路勁加個版本號:

Version

p.s. index.html 始終是 no-cache

新版本上線后,瀏覽器請求 html,發現資源路勁更改了,便主動放棄相關緩存,重新加載引用文件。這個小小的改變很實用,兼顧了緩存策略和新舊版本文件沖突。至于這個版本號怎么添加,各色打包工具都能實現,最簡單的策略就是在 index.html 模版里加個時間戳。

摘要算法

當然,隨著業務增長,js 和 css 文件會變得愈發巨大,僅僅加載單個文件就可能需要數秒。遇到問題就解決問題,把大文件拆成小份就行了!利用瀏覽器異步加載多個文件的機制,拆分 JS 能迅速提速。(當然,瀏覽器并發加載數有限,拆太細會適得其反)。

multi-link

這時候有聰明人就發現了:每次更新時,某些 js 文件并沒有被修改,為什么也要增加版本號呢?讓客戶無端加載一個一模一樣的 js 文件,不是很浪費嗎?

反正版本號就是一個 unique 值——防沖突用的,不如換成別的數值吧?比如,經典的MD5(消息摘要)算法生成的content hash值,該哈希值與文件內容一一對應的,這就有了精確到單個文件的版本控制信息了。

Content Hash

我自己開發時,會利用 webpack 的 splitChunks 功能,把 Vue 全家桶打包成單個 js 文件、UI 框架也打包成單個 js;這種文件體積不小,但基本不會變動,cache-control/max-age可以寫大一些,客戶端除了首次訪問會慢一點,其他時候基本就disk cache了。

CDN

上面提到服務器存放靜態資源文件,但這種形式在性能上也有缺陷:

  • 受地理環境影響,離服務器越遠資源加載越慢
  • 頻繁請求資源對服務器壓力較大

為了進一步提升性能,大家開始把動態網頁(index.html)和靜態資源(js、css、image...)分開部署。靜態資源被放置于 CDN 上。

CDN

但是 CDN 也有緩存策略:新的靜態資源發布后,需要一定的時間去覆蓋各個邊緣站點的舊資源。若某客戶端獲得了新的動態網頁,但是附近的 CDN 節點尚未更新最近發布的靜態資源,客戶端即便放棄本地緩存,它加載的依舊是位于 CDN 上的“臟數據”。怎么辦呢?干脆把文件名也給改了——讓摘要信息成為文件名的一部分!具體實現還是可以仰仗 webpack,將 output.filename 設為 [name].[contenthash].js,輸出文件和 html 模版都會幫你更改好。

Hash Name

用摘要信息重命名后的資源文件,與舊資源就不同名了,不再需要以覆蓋舊文件的形式主動更新各個地區的邊緣站點。新版本發布后,瀏覽器首次請求資源,若 CDN 不存在該資源,便會向就近的邊緣站點加載該文件,同時更新 CDN 緩存;這就徹底避免了 CDN 臟數據的問題。

Build

關于構建,我自己所在項目組的做法是前端單獨部署:git 接收 MR 后觸發 AWS 的 code pipeline 和 code build;Webpack 自動打包生成dist文件夾(里面包含 html、js、css 等資源),html 部署到服務器上,其他靜態資源發布到 CDN 上。這一套下來也不貴:一個月十幾刀,每次部署也就幾分鐘。但是,但是!我后來看到有些廠的做法,覺得實在是太“摳”了——成本控制得真好!

他們的做法是這樣的:build 在開發環境就完成了,然后把打包生成的dist文件夾也 push 到 git 上。好處很明顯:

  • 節省了一套 code pipeline + code build 的花費:大公司就不是一個月十幾刀的事了
  • 大大縮短 build 時間:構建環境是不包含node_modules的,大型項目光npm install就要很久,build 時間更是感人

而開發人員本地 build,可以很完美地繞開上面兩個缺點。配置上寫個 hook,在git commit時多加如下三個 changes 即可:

modified: dist/index.html
delete:   dist/garlic.6b58.js
new file: dist/garlic.e5i1.js

最后的犧牲只是 git repo 上包含了一個 dist 文件夾而已,真的是很“摳門”啊。

小結

這期內容很簡單,講了講靜態資源文件名的那些事,算是螺螄殼里做道場吧。一直在想一件事,我們追求新技術的本質是什么?我覺得是降低成本!軟件本質上還是屬于“工業產品”。新聞上能看到一些重工業單位通過調整工藝大大降低成本的案例;我們做軟件的也應該不斷調整工藝,降低成本、減少設備消耗,從而幫助公司賺取更多的利潤。我曾看過有人形容軟件開發就是一種緩慢地破壞+重建的過程,這種觀點還是挺有道理的,分享給大家。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,637評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,555評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,629評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,976評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,139評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,686評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,411評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,641評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,820評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,362評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,604評論 2 380

推薦閱讀更多精彩內容