關於 webpack 打包後文件過大的那些事……

react 配合 webpack 打包當然好用,但比較尷尬的是打包事後的 react 文件的體積……javascript

首屏加載過慢,怎麼辦?慢慢優化唄……
通常正常的網站首屏應該在1s左右加載出來,這個體驗性簡直極好的。
既然優化那就先從資源文件大小開始。
可能有的人會說既然優化,那就作個按需。這確實是個好主意,可是若是你打包後的文件不是很大的話,其實不必作按需。css

首先配置全局變量

告訴 webpack 我要發佈 production 了,按照 production 方式去打包。html

new webpack.DefinePlugin({
        'process.env': {
            //注意一個單引號一個雙引號…… 這裏是要將 "production" 替換到文件裏面
            NODE_ENV: '"production"'
        }
    })

1. 注意 devtool 中的 source-map。

若是你打包後的文件莫名其妙的好幾 MB的大小…… 看到這個文件內心真是一萬隻奔騰的……java

若是好幾 MB, 那不用想了確定是 source-map 的問題, 注意 source-map 的那種幾種類型使用.react

webpack sourcemap 選項多種模式的一些解釋
https://webpack.github.io/docs/configuration.html#devtoolwebpack

source map 在開發調試的時候確實是好用,但也只是開發的時候……
生產環境沒多大必要去用這個了,固然也有人選擇在生產環境開啓 source-map ,方便調試, 但我以爲真心不必, 在生產環境調試的方法多的是,不必用這個方式.git

能夠試一下,當開啓 devtool打包後的文件github

devtool: "inline-source-map"web

打包後3.9MB...

瞬間高潮了,這個js掛在服務器上沒有10s出不來的,記得當我第一次在服務器上打包後,滿懷期待的打開頁面後的場景……npm

其實瞭解下 source-map 的不一樣方式就知道了, inline-source-map 爲每個文件添加 sourcemap 的 DataUrl,注意這裏的文件是打包前的每個文件而不是最後打包出來的,同時這個 DataUrl 是包含一個文件完整 souremap 信息的 Base64 格式化後的字符串,而不是一個 url。

建議在production環境打包的時候關閉 devtool.

若是非得在線上使用 source-map, 能夠配置爲

devtool: "#source-map",

這樣只會在文件後面跟一個 url,這樣對源文件影響就很小了

這樣還有1.52MB

能夠看到使用#source-map後 vendor.js 已經從3.9M 減到 1.52MB。
若是非要在生成環境使用 source-map, 請嚴謹選擇。

2. 使 css 剝離 js 文件, 將 css 單獨打包。

依賴插件 npm install --save-dev extract-text-webpack-plugin 先安裝再使用

var ExtractTextPlugin = require('extract-text-webpack-plugin');
    
    //在 plugins 中配置
    plugins: [ new ExtractTextPlugin('[name].[contenthash].css') ]

把 css 單獨打包出來,省得之後只修改 css 致使 瀏覽器端 js 的緩存也失效了。
這裏使用了 contenthash, webpack 會按照內容去生成 hash 值。

3. 壓縮, 去除註釋

注意若是開啓了source-map選擇inline-source-map壓縮後依然好幾MB的

//在 plugins 中添加
    new webpack.optimize.UglifyJsPlugin({
        comments: false,        //去掉註釋
        compress: {
            warnings: false    //忽略警告,要否則會有一大堆的黃色字體出現……
        }
    })

最好開啓去掉代碼註釋。
代碼壓縮後提高簡直不是一點兩點的……

壓縮後只有410kb

哇塞很贊哎. 其實仍是不行的,這樣首屏加載還會慢點, 怎麼辦 gzip 咯。

4. 開啓 gzip 壓縮

依賴插件 npm install --save-dev compression-webpack-plugin

git 地址:compression-webpack-plugin

var CompressionWebpackPlugin = require('compression-webpack-plugin');

    //在 plugin 中添加
    new CompressionWebpackPlugin({ //gzip 壓縮
        asset: '[path].gz[query]',
        algorithm: 'gzip',
        test: new RegExp(
            '\\.(js|css)$'    //壓縮 js 與 css
        ),
        threshold: 10240,
        minRatio: 0.8
    })

這個就很滿意……

只有115KB了

gzip

這個截圖是請求服務器上的 js。以前這個 js 要10多秒的……(雲服務器最低配置的那種)
請求截圖

從3.9MB 到 115KB!!! 真是極好的。

5. 壓縮 html, 自動添加上面生成的靜態資源。

依賴插件 npm install --save-dev html-webpack-plugin

git 地址:html-webpack-plugin

var HtmlWebpackPlugin = require('html-webpack-plugin');
    
    new HtmlWebpackPlugin({
        filename: 'react.html',    //生成的文件,從 output.path 開始 output.path + "/react.html"
        template: '../client/react.html',  //讀取的模板文件,這個路徑是相對於當前這個配置文件的
        inject: true, // 自動注入
        minify: {
            removeComments: true,        //去註釋
            collapseWhitespace: true,    //壓縮空格
            removeAttributeQuotes: true  //去除屬性引用
            // more options:
            // https://github.com/kangax/html-minifier#options-quick-reference
        },
        //必須經過上面的 CommonsChunkPlugin 的依賴關係自動添加 js,css 等
        chunksSortMode: 'dependency'
    })

這樣就大功告成了, css,js 開啓 gzip 壓縮後, 會將生成的文件名自動注入到 html 中。 若是有多個 html 配置再添加一個 new HtmlWebpackPlugin() 便可。

小結

  1. 肯定不會在生產環境打包多餘的代碼, 好比 熱加載 只是舉個例子

  2. 檢查只在 dev 使用的配置,在生產環境將其去掉. 可以使用配置文件,靈活配置,靈活切換

  3. 去除全部註釋, 壓縮全部可壓縮的資源文件.

  4. 開啓 gzip壓縮.

總而言之爲了讓文件變小,爲了讓瀏覽器加載的更快,咱們真的要無所不用其極……

以上, 致那顆騷動的心……
相關文章
相關標籤/搜索