前端性能優化 - CDN引入分析及實踐

在前端項目里引入CDN技術以達到加速網頁加載的目的

create-react-app為例,

// config-overrides.js
const addCustomize = () => (config) => {
 config.plugins.push(
        new HtmlWebpackExternalsPlugin({
          externals: [
            {
              // 引入的模塊
              module: "react",
              // cdn的地址
              entry: "https://cdn.bootcdn.net/ajax/libs/react/16.13.1/umd/react.production.min.js"
              // 掛載到了window上的名稱
              // window.jQuery就可以全局使用
              global: "React",
            }
          ],
        })
      );
  return config;
};

module.exports = override(
    ...
    addCustomize(),
)

當然,需要引入BundleAnalyzerPlugin進行編譯打包后體積查看

// config-overrides.js
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;

const addCustomize = () => (config) => {
    ...
    config.plugins.push(
      new BundleAnalyzerPlugin({
        analyzerMode: "static", //輸出靜態報告文件report.html,而不是啟動一個web服務
      })
    );
   ....
}

筆者莫得私有CDN,于是乎想著試試用ng實現類似的引入方式。

即: ng暴露linux某個文件夾,可以遠程讀取里面的文件,那么CDN的文件放在上面,且設置對應長時間的緩存策略,達到只讀一次之后就不必再次請求獲取資源的目的,原理上除了加速,使用、讀取是跟CDN類似的,在此嘗試讀取本機的資源

搞起

配置ng

location /private_static {
         alias /home/private_static/;
         expires 180d; ## 長時間的緩存策略
         add_header Cache-Control "public";
         add_header Access-Control-Allow-Origin *;  ## 跨域設置
         add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
         add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
         autoindex on; ## 開啟遠程讀取模式
       }

然后一個個把umd類型的包放進去即可

drwxr-xr-x 3 root root 4096 Apr 29 10:05 antd
drwxr-xr-x 3 root root 4096 Apr 29 10:04 antd-design-icons
drwxr-xr-x 3 root root 4096 Apr 29 10:04 antd-mobile
drwxr-xr-x 2 root root 4096 Apr 29 09:51 geolocation
drwxr-xr-x 3 root root 4096 Apr 29 10:09 react
drwxr-xr-x 3 root root 4096 Apr 29 11:57 react-activation
drwxr-xr-x 3 root root 4096 Apr 29 10:07 react-dom
drwxr-xr-x 3 root root 4096 Apr 29 10:06 react-is
drwxr-xr-x 3 root root 4096 Apr 29 10:06 react-router-dom
drwxr-xr-x 3 root root 4096 Apr 29 10:06 styled-components
drwxr-xr-x 3 root root 4096 Apr 29 10:03 vconsole

其一例子如下:

// config-overrides.js
 config.plugins.push(
        new HtmlWebpackExternalsPlugin({
          externals: [
            {
              // 引入的模塊
              module: "react",
              // cdn的地址
             entry: "https://www.yingtai.tech/private_static/react/16.13.1/react.production.min.js",
              // 掛載到了window上的名稱
              // window.jQuery就可以全局使用
              global: "React",
            }
          ],
        })
      );

筆者嘗試將N多個使用到的依賴包都改為CDN讀取,前后打包對比:

未使用CDN模式:

parsed size

大部分包使用CDN模式(嚴格來說,ng如此配置,除了加速,其他跟CDN一樣):


CDN parsed size

打包后體積小了近170+kb,較原先的包小了近23%。頓時有點開心,優化了一大截

但是真的優化了嗎?

于是放上服務器對比前后首次加載速度:

未使用CDN模式:


image.png

約在1.9s~2.1s之間

(自己的服務器,帶寬較低,同樣的包在公司測試服務器能有900ms~1.01s的速度,具體優化之前有文章提及如何優化的,在此不做贅述)

大部分包使用CDN模式后:


image.png

包是小了,但是首次渲染時間竟然到8s了,excuse me ? 沒優化都比優化快多了好嘛!

即使是ng,沒有CDN加速,也不至于吧

分析原因,發現如果每個依賴包都用CDN模式,會加大網絡request請求數量,時間就損耗在這里了,有些甚至才幾十kb的,加載速度也跟幾百kb相差無幾,這就虧大了

So接下來的策略應該是:

通過BundleAnalyzerPlugin分析,哪些包特大,才采用CDN模式

image.png

那么就單對這個包進行CDN:

image.png

也小了100+kb,包體積10%左右的優化

image.png

速度也趨近于2s左右

只優化了一個大包,原先的加載速度應該是在2.2s-2.3s之間,快了0.2s,加載速度提升9-10%左右,且如果使用加速后的CDN而非這種ng模擬的形式,應該會更快

但最重要的在這里:

如果是單域名,多個子域名伺服多個應用,那么采用了這種CDN形式,能讓各個應用體積都減少10%,且節省已加載的共用包的加載時間!

這就很可觀了!

比如,https://yingtai.tech/有多個子域名,伺服多個應用:

https://yingtai.tech/first_app/
https://yingtai.tech/second_app/
https://yingtai.tech/third_app/
...
N個應用都用到了對應的react,react-dom包,那么這N個應用各自可以減少10%的打包體積。
同時:如果用戶訪問了first_app,然后訪問second_app,由于設置了對應react,react-dom包的訪問策略,在訪問frist_app時,已經將公用包儲存在本地,當訪問second_app甚至其他類似的app情況下,會讀取共用包本地緩存,那么當首次訪問second_app,只需要加載second_app非共用的資源包即可

只要訪問過該域名下的某個應用一次,那么其訪問該域名下的應用的首次加載時間將會對應減少

按上面例子來說,假設訪問a、b、c三個應用,三個應用共用一個包E,
a應用首次訪問耗時2.2s,此時去訪問b或者c應用,同等網絡情況下,必然比2.2s耗時小

以另一個項目為例子:

未CDN前:


image.png

加載速度:(帶寬大點的服務器,確實快很多!)


image.png

CDN后:
image.png

加載速度:


image.png

之前是900ms ~ 1.1s左右,現在基本可以800ms~900ms,包體積小100kb+

當然最看重的還是,統一域名下的其他應用,單煩用到相關的包,都能用本地緩存,節省首次加載時間

附用到的附帶命令:

linux下載

curl -O <對應的url>

linux移動文件

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

推薦閱讀更多精彩內容