webpack—— 優(yōu)化輸出質(zhì)量

webpack 優(yōu)化從兩個方面入手。
一茵瘾、優(yōu)化開發(fā)體檢切威。包括優(yōu)化構(gòu)建速度和優(yōu)化使用體驗。參考鏈接優(yōu)化開發(fā)體驗
二芽死、優(yōu)化輸出質(zhì)量,包括減少用戶能感知到的加載時間(首屏加載時間)和提升流暢度(提升代碼性能)次洼。
參考webpack官網(wǎng)关贵、深入淺出webpack

減少用戶能感知到的加載時間

  1. 壓縮代碼
    壓縮后,代碼文件會變小卖毁,且混淆揖曾。文件變小會使在網(wǎng)絡(luò)中傳輸更優(yōu)化一點。使用UglifyJS進行壓縮亥啦。

  2. 代碼分離
    代碼分離是 webpack 中最引人注目的特性之一炭剪。此特性能夠把代碼分離到不同的 bundle 中,然后可以 按需加載或并行加載 這些文件翔脱。代碼分離可以用于獲取更小的 bundle奴拦,以及控制資源加載優(yōu)先級,如果使用合理届吁,會極大影響加載時間错妖。
    代碼分離是為了防止文件過大,多頁面的時候有重復(fù)代碼導(dǎo)入等原因瓷产。
    常用的代碼分離方法有三種:

    • 入口起點:使用 entry 配置手動地分離代碼站玄。(也就是多頁面配置,entry中有多個入口的情況下濒旦,打包出來的就是按照入口分離的。但是這種沒有去除重復(fù)的再登。)
     // 1.入口起點   缺點:重復(fù)模塊都會引入尔邓。比如lodash
      entry: {
          index: './src/index.js',
          another: './src/another-module.js',
      }, 
    
    • 防止重復(fù):使用 SplitChunksPlugin 去重和分離 chunk。(替代了webpack3.0版本中的CommonsChunkPlugin)
      分離的方式是:
      多入口的時候:將公共的代碼分離到一個默認(rèn)為vendors的chunk里面锉矢。然后每個入口是一個chunk.比如我有兩個入口 a.js 和 b.js 梯嗽。那么打包出來的就是a.bundle.js 、 b.bundle.js沽损、 vendors~a~b.bundle.js灯节。
      單入口的時候:會按照設(shè)置規(guī)則打包。比如默認(rèn)的設(shè)置這種。會將入口文件打包成一個文件比如index.bundle.js炎疆,將里面引用的比較大的文件卡骂,打包成單獨的文件為vendors~index.bundle.js。
    // 2.防止重復(fù)  如果是多頁面應(yīng)用可以去重并分離形入。如果是單頁面應(yīng)用可以做到分離全跨。 
    optimization: {
     splitChunks: {
         chunks: 'all'
     },
    },
    
    • 動態(tài)導(dǎo)入:通過模塊中的內(nèi)聯(lián)函數(shù)調(diào)用來分離代碼。動態(tài)引入的文件也會單獨打包出來亿遂。
      包括兩種方式浓若。 第一種,推薦的蛇数,使用符合 ECMAScript提案的 import() 語法 來實現(xiàn)動態(tài)導(dǎo)入挪钓。第二種,則是 webpack 的遺留功能耳舅,使用 webpack 特定的 require.ensure碌上。他們的原理就是利用JSONP。參考Webpack的異步加載原理及分包策略挽放。動態(tài)導(dǎo)入完整代碼參考官網(wǎng)介紹绍赛。
      動態(tài)導(dǎo)入的案例

異步加載原理
webpack ensure 有人稱它為異步加載,也有人稱為代碼切割辑畦,他其實就是將 js 模塊給獨立導(dǎo)出一個.js 文件吗蚌,然后使用這個模塊的時候,再創(chuàng)建一個 script 對象纯出,加入到 document.head 對象中蚯妇,瀏覽器會自動幫我們發(fā)起請求,去請求這個 js 文件暂筝,然后寫個回調(diào)函數(shù)箩言,讓請求到的 js 文件做一些業(yè)務(wù)操作。
異步加載 就是動態(tài)導(dǎo)入焕襟。通過異步加載實現(xiàn)了按需加載陨收。懶加載= 按需加載。依靠的方式是動態(tài)導(dǎo)入的方式

  1. 按需加載鸵赖。就說用的時候才加載务漩。框架里面的路由配置它褪。多數(shù)都配置成路由按需加載饵骨。會自動生成對應(yīng)的chunk。
  2. CDN 加速
    針對 HTML 文件:不開啟緩存茫打,把 HTML 放到自己的服務(wù)器上居触,而不是 CDN 服務(wù)上妖混,同時關(guān)閉自己服務(wù)器上的緩存。自己的服務(wù)器只提供 HTML 文件和數(shù)據(jù)接口轮洋。
    針對靜態(tài)的 JavaScript制市、CSS、圖片等文件:開啟 CDN 和緩存砖瞧,上傳到 CDN 服務(wù)上去息堂,同時給每個文件名帶上由文件內(nèi)容算出的 Hash 值, 例如app_a6976b6d.css 文件块促。 帶上 Hash 值的原因是文件名會隨著文件內(nèi)容而變化荣堰,只要文件發(fā)生變化其對應(yīng)的 URL 就會變化,它就會被重新下載竭翠,無論緩存時間有多長振坚。
    用 Webpack 實現(xiàn) CDN 的接入。配置如下:
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const {WebPlugin} = require('web-webpack-plugin');

module.exports = {
  // 省略 entry 配置...
  output: {
    // 給輸出的 JavaScript 文件名稱加上 Hash 值
    filename: '[name]_[chunkhash:8].js',
    path: path.resolve(__dirname, './dist'),
    // 指定存放 JavaScript 文件的 CDN 目錄 URL
    publicPath: '//js.cdn.com/id/',
  },
  module: {
    rules: [
      {
        // 增加對 CSS 文件的支持
        test: /\.css$/,
        // 提取出 Chunk 中的 CSS 代碼到單獨的文件中
        use: ExtractTextPlugin.extract({
          // 壓縮 CSS 代碼
          use: ['css-loader?minimize'],
          // 指定存放 CSS 中導(dǎo)入的資源(例如圖片)的 CDN 目錄 URL
          publicPath: '//img.cdn.com/id/'
        }),
      },
      {
        // 增加對 PNG 文件的支持
        test: /\.png$/,
        // 給輸出的 PNG 文件名稱加上 Hash 值
        use: ['file-loader?name=[name]_[hash:8].[ext]'],
      },
      // 省略其它 Loader 配置...
    ]
  },
  plugins: [
    // 使用 WebPlugin 自動生成 HTML
    new WebPlugin({
      // HTML 模版文件所在的文件路徑
      template: './template.html',
      // 輸出的 HTML 的文件名稱
      filename: 'index.html',
      // 指定存放 CSS 文件的 CDN 目錄 URL
      stylePublicPath: '//css.cdn.com/id/',
    }),
    new ExtractTextPlugin({
      // 給輸出的 CSS 文件名稱加上 Hash 值
      filename: `[name]_[contenthash:8].css`,
    }),
    // 省略代碼壓縮插件配置...
  ],
};

以上代碼中最核心的部分是通過 publicPath 參數(shù)設(shè)置存放靜態(tài)資源的 CDN 目錄 URL斋扰, 為了讓不同類型的資源輸出到不同的 CDN渡八,需要分別在:

  • output.publicPath 中設(shè)置 JavaScript 的地址。
  • css-loader.publicPath 中設(shè)置被 CSS 導(dǎo)入的資源的的地址传货。
  • WebPlugin.stylePublicPath 中設(shè)置 CSS 文件的地址屎鳍。

提升流暢度

1.使用 Prepack
實際上 Prepack 就是一個部分求值器,編譯代碼時提前將計算結(jié)果放到編譯后的代碼中问裕,而不是在代碼運行時才去求值逮壁。
Prepack 的工作原理和流程大致如下:
通過 Babel 把 JavaScript 源碼解析成抽象語法樹(AST),以方便更細(xì)粒度地分析源碼粮宛;
Prepack 實現(xiàn)了一個 JavaScript 解釋器窥淆,用于執(zhí)行源碼。借助這個解釋器 Prepack 才能掌握源碼具體是如何執(zhí)行的巍杈,并把執(zhí)行過程中的結(jié)果返回到輸出中忧饭。
從表面上看去這似乎非常美好,但實際上 Prepack 還不夠成熟與完善筷畦。Prepack 目前還處于初期的開發(fā)階段词裤,局限性也很大”畋觯可以看官網(wǎng)或者看書亚斋。不再多做介紹。

總結(jié)

優(yōu)化輸出質(zhì)量攘滩。就是更快的讓用戶能看到頁面。一方面頁面足夠兄脚荨(加載會快點漂问,利用壓縮)赖瞒,一次不要加載太多(解決首屏慢)。一方面則是利用網(wǎng)絡(luò)可以一次請求4-7個請求蚤假。利用此特點栏饮,則不能全部放到一個文件中,合理的使用代碼分離磷仰。進而可以做到按需加載袍嬉。按需加載又解決了首屏慢的問題。另外通過cdn可以讓用戶訪問最近的代碼灶平。加快請求伺通。還可以做一些預(yù)加載之類的。
在頁面請求渲染的整個過程中逢享,每一項都可以有優(yōu)化的點罐监。但是物極必反。合理的利用才是最好的選擇瞒爬。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末弓柱,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子侧但,更是在濱河造成了極大的恐慌矢空,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件禀横,死亡現(xiàn)場離奇詭異屁药,居然都是意外死亡,警方通過查閱死者的電腦和手機燕侠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門者祖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人绢彤,你說我怎么就攤上這事七问。” “怎么了茫舶?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵械巡,是天一觀的道長。 經(jīng)常有香客問我饶氏,道長讥耗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任疹启,我火速辦了婚禮古程,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘喊崖。我一直安慰自己挣磨,他們只是感情好雇逞,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著茁裙,像睡著了一般塘砸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上晤锥,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天掉蔬,我揣著相機與錄音,去河邊找鬼矾瘾。 笑死女轿,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的霜威。 我是一名探鬼主播谈喳,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼戈泼!你這毒婦竟也來了婿禽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤大猛,失蹤者是張志新(化名)和其女友劉穎扭倾,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挽绩,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡膛壹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了唉堪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片模聋。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖唠亚,靈堂內(nèi)的尸體忽然破棺而出链方,到底是詐尸還是另有隱情,我是刑警寧澤灶搜,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布祟蚀,位于F島的核電站,受9級特大地震影響割卖,放射性物質(zhì)發(fā)生泄漏前酿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一鹏溯、第九天 我趴在偏房一處隱蔽的房頂上張望罢维。 院中可真熱鬧,春花似錦丙挽、人聲如沸言津。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽悬槽。三九已至,卻和暖如春瞬浓,著一層夾襖步出監(jiān)牢的瞬間初婆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工猿棉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留磅叛,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓萨赁,卻偏偏與公主長得像弊琴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子杖爽,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容