国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Webpack 3一些代碼體積優(yōu)化方案的小結(jié)

taowen / 997人閱讀

摘要:表示生成一個懶加載的,只有當需要時才會被加載。主要是作用域提升,將所有模塊放在同一個作用域當中,一方面能提高運行速度,另一方面也能降低文件體積。前提是你的代碼是用模塊寫的。參考文章學習小結(jié)

前言

之前接手公司一個前端項目,開發(fā)了幾個月后越來越難以忍受項目結(jié)構(gòu)的混亂和打包體積的臃腫(腳手架和基本功能代碼都是從公司的其他項目復制過來的),如果不立即進行重構(gòu),難以想象以后要怎么維護各個產(chǎn)品線。于是我自告奮勇承擔了項目框架的優(yōu)化任務,這里分享一下我在打包體積優(yōu)化中所研究的成果,經(jīng)過幾輪的努力,成功的將我們這個 react+antd+immutable+rxjs的較大項目從打包后的9MB降低到了2.5MB,首屏加載(gzip)從600KB+降低到了200KB,并且基本上將穩(wěn)定的第三方庫,webpack runtime代碼和業(yè)務代碼完全分離,最低限度減少網(wǎng)站更新時用戶需要加載的代碼量。
廢話不多說,下面詳細說明我所做的每一個步驟。

1. 優(yōu)化第三方庫

項目里對庫的使用較為混亂,有些庫安裝了但很少用或者根本沒用,但是又在webpack中的vendor入口指定打包了進來,造成體積上的浪費,所以需要仔細評估每個庫是否必要安裝。
react v16對比react v15,加上react-dom,體積上降低了30%,因此果斷升級。

2. moment.js

分析完stats.json后,發(fā)現(xiàn)的第一個問題就是moment很大,具體原因webpack是把所有的locale文件打包了進來。我們的項目不需要多語言,因此我們可以使用ContextReplacementPlugin插件來舍棄中文之外的其他語言文件:

new webpack.ContextReplacementPlugin(/moment[/]locale$/, /zh-cn/)

去除掉locale后,又發(fā)現(xiàn)了另一個問題:依賴分析顯示,我的項目里打包了兩份moment,一份es module版的,一份umd版的。經(jīng)過一番排查后發(fā)現(xiàn),使用import "moment"導入的會加載es module版的,這是webpack配置的mainFields決定的,但是在locale中的語言文件中,它會用相對路徑導入umd版的moment,這就導致我的項目里出現(xiàn)了兩份moment。為了統(tǒng)一版本,我們將moment設置為一個別名并指向umd版:

alias: {
  "moment$": path.resolve("node_modules/moment/moment"),
},
// $表示絕對匹配

另外還有一個庫dayjs值得一提,其API基本與moment一致,但是體積僅為幾KB,不知道antd會不會加入對dayjs的支持。

3. ECharts

項目之前是直接使用的完整版的echarts,并且沒有將echarts組件抽取為公共chunk,結(jié)果導致每個異步加載的頁面組件,只要用了echarts就會變得碩大無比。
解決方案:在echarts官網(wǎng)定制一份僅包含項目所需圖表類型的閹割版,并且將echarts組件抽取為異步加載的chunk,這樣就只需要加載一次。
關于如何將組件抽取為多帶帶的chunk,可以用import()語法,或者使用react-loadable這個庫,它可以直接將react組件包裝成異步組件,并在需要時才進行加載。

4. 抽取異步加載的chunk中的公共代碼

上面的步驟抽取echarts就是指的抽取異步chunk中的公共代碼,除了echarts之外還有很多大體積的公共代碼,例如各種antd的組件以及其依賴的底層組件rc-components,這部分也是我們要提取出來的。我們沒必要將每個antd組件包裝為異步組件,這里只需要配置一下CommonsChunkPlugin就可以了:

new webpack.optimize.CommonsChunkPlugin({
  async: "async-vendor",
  deepChildren: true,
  minChunks: (module) => {
    return /node_modules/.test(module.context);
  },
}),

在沒有將children設為true時,CommonsChunkPlugin會從入口文件(entry)提取公共代碼,這時就不會對異步加載的chunk起作用。因此為了提取異步chunk的公共代碼,我們設置deepChildrentruechildren指的是入口文件的直接子節(jié)點,deepChildren指的是全部子節(jié)點)。async表示生成一個懶加載的chunk,只有當需要時才會被加載。
上面只是將第三方庫的公共代碼提取了出來,如果希望把異步chunk當中自己的業(yè)務代碼提取出來,則可以修改minChunks規(guī)則,或者再增加一個配置:

    new webpack.optimize.CommonsChunkPlugin({
      async: "async-biz",
      deepChildren: true,
      minChunks: 2,
    }),
5. 并非每個路由頁面組件都需要異步加載

項目之前的做法是,每個路由對應的頁面根組件都需要異步加載,這樣做的結(jié)果是打包出了很多個chunk,而有一半的chunkgzip之前體積都不足5KB,浪費請求是一方面,更嚴重的是影響了首屏加載體積。
這是為什么?明明把每個頁面都異步加載了,怎么會影響首屏體積呢?其實原因就是第三步中的async-vendor被首屏加載了,該chunk主要包含了antd組件,gzip之后約為120KB
對于用戶來說,第一次打開我們的網(wǎng)站一定是到登錄界面,此時需要完全加載我們的首屏代碼,之后有了緩存,除了業(yè)務代碼更新需要加載很小的chunk之外,理論上是不需要再下載任何代碼的,因此我們需要針對登錄界面進行首屏優(yōu)化。
登錄界面包含了登錄、修改密碼、申請賬號等子路由,之前將這些都打包為異步chunk,由于這些界面需要async-vendor當中的某幾個antd組件,因此首屏加載一定會包含async-vendor。拆分async-vendor是一種辦法,但是還要分析到底用了哪些組件,改動業(yè)務代碼后又要重新分析,顯得很麻煩,最簡單的做法就是取消登錄相關路由的異步加載,將其打包到main當中,同時只需加載需要的antd組件,因此完全避免了加載async-vendor,首屏體積得到了大大降低。

6. 分離出webpack runtime代碼

webpack在客戶端運行時會首先加載webpack相關的代碼,例如require函數(shù)等,這部分代碼會隨著每次修改業(yè)務代碼后發(fā)生變化,原因是這里面會包含chunk id等容易變化的信息。如果不抽取出來將會被打包在vendor當中,導致vendor每次都要被用戶重新加載,vendor也失去了它的意義。分離的配置很簡單:

    new webpack.optimize.CommonsChunkPlugin({
      name: "manifest",
      minChunks: Infinity,
    }),

minChunks: Infinity表示創(chuàng)建一個什么都沒有的chunk,因為不會有任何模塊被無限次引用過,這樣webpack runtime代碼就會被CommonsChunkPlugin放入這個最后的chunk當中。

7. webpack內(nèi)部優(yōu)化

這部分內(nèi)容很簡單,就兩個插件的使用,HashedModuleIdsPluginModuleConcatenationPlugin
默認情況下,webpack會為每個模塊用數(shù)字做為ID,這樣會導致同一個模塊在添加刪除其他模塊后,ID會發(fā)生變化,不利于緩存。為了解決這個問題,有兩種選擇:NamedModulesPluginHashedModuleIdsPlugin,前者會用模塊的文件路徑作為模塊名,后者會對路徑進行md5處理,降低了文件體積,相比較而言,應該開發(fā)時選擇前者,生產(chǎn)環(huán)境選擇后者。
ModuleConcatenationPlugin主要是作用域提升,將所有模塊放在同一個作用域當中,一方面能提高運行速度,另一方面也能降低文件體積。前提是你的代碼是用es模塊寫的。

8. babel-polyfill

polyfill也是體積很大的一部分,但是又不得不加載,關于這部分的優(yōu)化可以參考這篇文章,ES6和Babel你不知道的事兒。還有一種方法是使用polyfill.io,這個解決思路個人覺得很不錯,但是還不敢在生產(chǎn)環(huán)境用,先觀望觀望。

總結(jié)

以上內(nèi)容是我這些天找資料研究的結(jié)果,總的來說打包體積算是得到了有效控制,關于chunk的打包配置如下:

entry: {
    main: path.join(process.cwd(), "src/index.js"),
    vendor: [
      "babel-polyfill", "immutable", "moment", "react", "react-dom" ...
    ],
},
output: {
    filename: "[name].[chunkhash].js",
    chunkFilename: "[name].[chunkhash].chunk.js",
},
plugins: [
    new webpack.HashedModuleIdsPlugin(),
    
    new webpack.optimize.ModuleConcatenationPlugin(),
    
    new webpack.optimize.CommonsChunkPlugin({
      async: "async-vendor",
      deepChildren: true,
      minChunks: (module) => {
        return /node_modules/.test(module.context);
      },
    }),
    
    new webpack.optimize.CommonsChunkPlugin({
      name: "vendor",
    }),
    
    new webpack.optimize.CommonsChunkPlugin({
      name: "manifest",
      minChunks: Infinity,
    }),
]

webpack 4已經(jīng)出了,再也沒有CommonsChunkPlugin了,取而代之的是SplitChunksPlugin,看來又要研究新的東西了。。。

參考文章:
CommonsChunkPlugin學習小結(jié)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/95754.html

相關文章

  • webpack 構(gòu)建性能優(yōu)化策略小結(jié)

    摘要:但是,隨者工程開發(fā)的復雜程度和代碼規(guī)模不斷地增加,暴露出來的各種性能問題也愈發(fā)明顯,極大的影響著開發(fā)過程中的體驗。對應的資源也可以直接由頁面外鏈載入,有效地減小了資源包的體積。 背景 如今前端工程化的概念早已經(jīng)深入人心,選擇一款合適的編譯和資源管理工具已經(jīng)成為了所有前端工程中的標配,而在諸多的構(gòu)建工具中,webpack以其豐富的功能和靈活的配置而深受業(yè)內(nèi)吹捧,逐步取代了grunt和gu...

    hiYoHoo 評論0 收藏0
  • 深入理解 Webpack 打包分塊(上)

    摘要:而一個哈希字符串就是根據(jù)文件內(nèi)容產(chǎn)生的簽名,每當文件內(nèi)容發(fā)生更改時,哈希串也就發(fā)生了更改,文件名也就隨之更改。很顯然這不是我們需要的,如果文件內(nèi)容發(fā)生了更改,的打包文件的哈希應該發(fā)生變化,但是不應該。前言 隨著前端代碼需要處理的業(yè)務越來越繁重,我們不得不面臨的一個問題是前端的代碼體積也變得越來越龐大。這造成無論是在調(diào)式還是在上線時都需要花長時間等待編譯完成,并且用戶也不得不花額外的時間和帶寬...

    Rocko 評論0 收藏0
  • 用純 DOM 方式結(jié)合 Puppeteer 自動生成網(wǎng)頁骨架屏

    摘要:可以通過的提供的直接控制模擬大部分用戶操作來進行或者作為爬蟲訪問頁面來收集數(shù)據(jù)。 ??骨架屏是在頁面數(shù)據(jù)尚未加載完成前先給用戶展示出頁面的大致結(jié)構(gòu),直到請求數(shù)據(jù)返回后再顯示真正的頁面內(nèi)容;隨著單頁應用( SPA )的越來越流行,單頁應用的用戶體驗也越來越得到前端開發(fā)者的關注;為了優(yōu)化用戶體驗,在數(shù)據(jù)到達用戶之前,往往會在頁面上加上 loading 的效果,而現(xiàn)在,越來越多的場景傾向于使...

    BlackHole1 評論0 收藏0
  • 淺談webpack4.0 性能優(yōu)化

    摘要:中在性能優(yōu)化所做的努力,也大抵圍繞著這兩個大方向展開。因此,將依賴模塊從業(yè)務代碼中分離是性能優(yōu)化重要的一環(huán)。大型庫是否可以通過定制功能的方式減少體積。這又違背了性能優(yōu)化的基礎。接下來可以抓住一些細節(jié)做更細的優(yōu)化。中,為默認啟動這一優(yōu)化。 前言:在現(xiàn)實項目中,我們可能很少需要從頭開始去配置一個webpack 項目,特別是webpack4.0發(fā)布以后,零配置啟動一個項目成為一種標配。正因為...

    leanxi 評論0 收藏0
  • 淺探前端圖片優(yōu)化

    摘要:性能優(yōu)化是前端開發(fā)必不可少的一環(huán),而圖片優(yōu)化又是性能優(yōu)化中必不可少的一環(huán),但不知道有多少開發(fā)者在網(wǎng)頁的開發(fā)過程中會注意圖片的使用,圖片使用不當可能會導致網(wǎng)頁加載卡頓網(wǎng)頁加載速度慢等問題,這篇文章將會將我以往對圖片的處理做個總結(jié)。 性能優(yōu)化是前端開發(fā)必不可少的一環(huán),而圖片優(yōu)化又是性能優(yōu)化中必不可少的一環(huán),但不知道有多少開發(fā)者在網(wǎng)頁的開發(fā)過程中會注意圖片的使用,圖片使用不當可能會導致網(wǎng)頁加...

    CocoaChina 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<