Webpack性能最適化(一)(別名でリダイレクト)

19982 ワード

前言
WebpackはOneAPMフロントエンドテクノロジースタックの重要な一部であり、非常に使いやすく、まだそれを理解していない場合は、このWebpackを読むことをお勧めします.OneAPMでは静的リソースパッケージ、ES 6コードの変換、Reactコンポーネントの組織などを完了し、次の日には、Webpackの使用中のパフォーマンスに関する経験を、一連の記事と業界を通じて共有します.
シリーズ第1編として、Webpackのresolve.alias、つまりリダイレクトをお願いすることに重点を置いて紹介します.ただし、Webpackのリクエストは、HTTPリクエストではなく、モジュールへの依存であるrequire文であることに注意してください.
必要な準備
  • 一定のNode.jsベースが必要
  • パソコンに最新版のWebpack(npm install webpack-g)がインストールされている
  • Webpackプロファイルのフォーマットを知る
  • 例:ローカルクロック
    実現する機能は簡単ですが、ページに現在の時間を中国語で表示するには、momentというライブラリを使用する必要があります.このライブラリには日付に関連する関数が多くパッケージされており、国際化のサポートが付いています.
    Node.jsプロジェクトを新規作成
    使用npm initあなたのプロジェクトを初期化し、npm install moment -Dプラスmomentの開発者依存.
    新規作成entry.js入口ファイルとしてはもちろんapp.jsという名前も使えますが、ほとんどのWebpack例ではentry.jsを使用しています.
    var moment = require('moment');
    document.write(moment().locale('zh-cn').format('LLLL'));

    新規ページ作成index.html、引用bundle.js:
    <body>
    <h5>    :h5>
    <script src="dist/bundle.js">script>
    body>

    ファイルディレクトリは次のように表示されます.
    index.html
    package.json
    entry.js
    node_modules/moment

    これまでbundle.jsこの書類は存在しませんでしたが、焦らないで次の作業はWebpackに任せて完了します.
    index.html  ------------------------+               
    package.json                        |               
                                        +--> <Clock App>
    entry.js    --------+               |               
                        +-->bundle.js+--+               
    node_modules/moment-+ 

    図のようにWebpackはentry.jsmomentモジュールとともにbundle.jsファイルにパッケージ化され、index.htmlとともにClock Appを構成しています.どうですか.もうClock Appの音が聞こえましたか.
    Webpackパッケージコードの使用
    コマンドラインで実行:
    webpack --entry ./entry.js --output-path dist --output-file bundle.js
    

    次のような出力結果が表示されます.
    Hash: bf9007fb1e0cb30e3ef7
    Version: webpack 1.10.0
    Time: 650ms
        Asset    Size  Chunks             Chunk Names
    bundle.js  378 kB       0  [emitted]  null
       [0] ./entry.js 125 bytes {0} [built]
        + 86 hidden modules

    650 msもかかり、こんなに遅いのは意外で、「次世代の神器」の速度を高める方法を考えなければならない.一方、最後の行の+86 hidden modulesは、簡単なClockアプリなのに、どうしてこんなに依存しているのか疑問に思っています.
    Webpackの速度が遅い理由
    もう一度、コマンドラインに入力します.
    webpack --entry ./entry.js --output-path dist --output-file bundle.js \
    --colors \
    --profile \
    --display-modules

    しかし、今回は3つのパラメータが追加されました.この3つのパラメータの意味はそれぞれ次のとおりです.
  • --colors出力結果はカラー付きで、例えば、赤色で表示するのに時間がかかるステップ
  • --profile性能データを出力し、ステップごとの消費時間を見ることができる
  • --display-modulesデフォルトではnode_modules下のモジュールは非表示になりますが、このパラメータを加えるとこれらの非表示になっているモジュールの今回のコマンドラインの結果が参考になりますので、時間のかかるステップの特定に役立ちます
  • Hash: bf9007fb1e0cb30e3ef7
    Version: webpack 1.10.0
    Time: 650ms
        Asset    Size  Chunks             Chunk Names
    bundle.js  378 kB       0  [emitted]  null
       [0] ./entry.js 125 bytes {0} [built]
           factory:11ms building:8ms = 19ms
       [1] ../~/moment/moment.js 102 kB {0} [built]
           [0] 19ms -> factory:7ms building:141ms = 167ms
       [2] (webpack)/buildin/module.js 251 bytes {0} [built]
           [0] 19ms -> [1] 148ms -> factory:132ms building:159ms = 458ms
       [3] ../~/moment/locale ^\.\/.*$ 2.01 kB {0} [optional] [built]
           [0] 19ms -> [1] 148ms -> factory:6ms building:10ms dependencies:113ms = 296ms
       [4] ../~/moment/locale/af.js 2.57 kB {0} [optional] [built]
           [0] 19ms -> [1] 148ms -> [3] 16ms -> factory:52ms building:65ms dependencies:138ms = 438ms
                      .....      ,Node.js         nodejs@oneapm.com ......
       [85] ../~/moment/locale/zh-cn.js 4.31 kB {0} [optional] [built]
            [0] 22ms -> [1] 162ms -> [3] 18ms -> factory:125ms building:145ms dependencies:22ms = 494ms
       [86] ../~/moment/locale/zh-tw.js 3.07 kB {0} [optional] [built]
            [0] 22ms -> [1] 162ms -> [3] 18ms -> factory:126ms building:146ms dependencies:21ms = 495ms

    コマンドラインの結果からRequest[4]からRequest[86]まで解析moment.js付随する大量のローカライズファイルが見られる.だから私たちが遭遇した速度の遅い問題は実はmomentによるものです.
    なぜWebpackがこんなに多くのモジュールをロードしているのか知りたいなら、この記事を参考にしてください.Why Enormous Locales During Webpack MomentJS
    もう一度見てみましょうentry.jsコードの最初の行、標準的なCommonJS書き方:
    var moment = require('moment');
    

    つまり、リクエストしたのはmomentのソースコードです.実際、NPM実装momentの場合は、momentのソースコードと圧縮後のコードを同時に実装し、以下のような書き方も可能であることを実証した.
    var moment = require('moment/min/moment-with-locales.min.js');
    

    ただし、このように変更すると可読性が低下し、使用する場所ごとにmomentと書かなければなりません.また,同様の問題がサードパーティモジュールに現れると,他の人のコードを修正するのはそれほど便利ではない.Webpackでこの問題をどう解決するか見てみましょう.
    Webpackでの別名の使用
    別名(resolve.alias)はWebpackの1つのコンフィギュレーション項目であり、ユーザの1つのリクエストを別のパスにリダイレクトする役割を果たし、例えばwebpack.config.jsコンフィギュレーションファイルを修正することによって、以下のように参加する.
      resolve: {
        alias: {
            moment: "moment/min/moment-with-locales.min.js"
        }
      }

    このようにパッケージ化されるスクリプトの中のrequire('moment');実はrequire('moment/min/moment-with-locales.min.js');に等しい.エイリアスの使用により、この例ではほぼ半分の時間を短縮できます.
    Hash: cdea65709b783ee0741a
    Version: webpack 1.10.0
    Time: 320ms
        Asset    Size  Chunks             Chunk Names
    bundle.js  148 kB       0  [emitted]  main
       [0] ./entry.js 125 bytes {0} [built]
           factory:11ms building:9ms = 20ms
       [1] ../~/moment/min/moment-with-locales.min.js 146 kB {0} [built] [1 warning]
           [0] 20ms -> factory:8ms building:263ms = 291ms
       [2] (webpack)/buildin/module.js 251 bytes {0} [built]
           [0] 20ms -> [1] 271ms -> factory:3ms building:1ms = 295ms
    
    WARNING in ../~/moment/min/moment-with-locales.min.js
    Module not found: Error: Cannot resolve 'file' or 'directory' ./locale in */webpack_performance/node_modules/moment/min
     @ ../~/moment/min/moment-with-locales.min.js 1:2731-2753
    Webpackで既知ファイルの解析を無視module.noParseはいwebpackもう1つの有用な構成項目は、1つのモジュールに他の新しい依存がないと判断した場合に構成できます.webpackこのファイルの依存はスキャンされません.
      module: {
        noParse: [/moment-with-locales/]
      }

    このように修正して、前の名前の変更例と結びつけて、更新後の流れは:
  • webpackチェックentry.jsファイル対momentの依頼
  • リクエストがaliasリダイレクトされ、リクエストがmoment/min/moment-with-locales.min.js;
  • noParseルールの中の/moment-with-locales/一条が発効したのでwebpackそのまま依存をパッケージ化bundle.js.
  • Hash: 907880ed7638b4ed70b9
    Version: webpack 1.10.0
    Time: 76ms
        Asset    Size  Chunks             Chunk Names
    bundle.js  147 kB       0  [emitted]  main
       [0] ./entry.js 125 bytes {0} [built]
           factory:13ms building:13ms = 26ms
       [1] ../~/moment/min/moment-with-locales.min.js 146 kB {0} [built]
           [0] 26ms -> factory:13ms building:5ms = 44ms

    時間はさらに圧縮され,76 msで前のステップより75%減少した.
    Webpackでの共通CDNの使用
    Webpackはこのように強力で、パッケージ化されたスクリプトで複数の環境で実行できます.Web環境はデフォルトの1つであり、最も一般的な1つです.Web上に多くのパブリックCDNサービスがあることを考えると、WebpackとパブリックCDNをどう組み合わせて使うのでしょうか.方法はexternals外部依存を宣言することです.
      externals: {
        moment: true
      }

    もちろんHTMLコードには1行追加する必要があります
    
    

    のパッケージは、 49 msしか わず、ほぼ に しました.
    まとめ
    では,ローカルクロックの と びつけて,Webpack の を する と, な2つのパラメータ:--display-modulesおよび--profileを した. に、resolve.alias によるリダイレクトの とシーンを に した で、module.noParse のモジュールの を することでさらに を げることができます. に,externals メソッドを して CDNを いた.
    について
    に するソースコードは、 のとおりです.https://github.com/wyvernnot/webpack_performance/tree/master/moment-example;
    はOneAPMエンジニアのオリジナル です.OneAPMは の ソフトウェア の リーダー であり、 のユーザーと が に できる: いプログラムコードとSQL のリアルタイムキャプチャ. については、OneAPM テクニカルブログを してください.