code splittingのchunkのしくみ
疑問
異なるchunkA
B
それぞれで、同じモジュール(例えばlodash
)をimportしている場合、ビルド後のA
B
のサイズはどうなるのか
Answer
require.ensure
System.import
bundle-loader
どれを用いても結果は変わらず。A
B
双方「200kb」ほどサイズ増加しており、両方でlodash
を別々にloadしていることが伺える。
Code Splitting (公式)
Chunk optimization
If two chunks contain the same modules, they are merged into one. This can cause chunks to have multiple parents.
If a module is available in all parents of a chunk, it’s removed from that chunk.
If a chunk contains all modules of another chunk, this is stored. It fulfills multiple chunks.
とあるが、lodash
の場合はうまくいかないということ?
追記(19:09)
→どうやらそういうわけではなく、共通部分があってもentry chunkには決してmergeされない仕様らしい。つまり、複数の孫モジュール間での共通部分は抽出されて別のchunkとしてmergeされるはず…(親=entry chunk)
Webpack will take care of it by merging chunks (it will prefer merging chunk that have duplicate modules). Nothing will be merged into the entry chunk, so as not to impact initial page loading time.
optimization · webpack/docs Wiki · GitHub
試した
下記のように
entry chunk
-->Home
-->lodash
entry chunk
-->About
-->lodash
というchunkわけをしてビルドした結果。(lodash
は単一ファイルのchunk)
entry chunk ------ function resolveIndex(nextState, cb) { System.import('../components/Home') .then(module => cb(null, module.default)) .catch(handleError); } function resolveAbout(nextState, cb) { System.import('../components/About') .then(module => cb(null, module.default)) .catch(handleError); }
components/Home ------ import Home from './Home'; // sync loading is not merged... // import _ from 'lodash'; // async loading is merged into a new chunk !! System.import('lodash') export default Home;
components/About ------ import About from './About'; // sync loading is not merged... // import _ from 'lodash'; // async loading is merged into a new chunk !! System.import('lodash') export default About;
みごと2-c87d85131caeed2b63ea.js
にlodashのコードがmergeされている。
Version: webpack 2.1.0-beta.20 Time: 5341ms Asset Size Chunks Chunk Names 0-ad0eb1228846aae746d1.js 549 bytes 0 [emitted] 1-2fcd73cc179c047a58c9.js 449 bytes 1 [emitted] 2-c87d85131caeed2b63ea.js 69.5 kB 2 [emitted] main-d489ed5a12ea8ccac8d5.js 220 kB 3 [emitted] main main-d489ed5a12ea8ccac8d5.css 2.37 kB 3 [emitted] main main-d489ed5a12ea8ccac8d5.css.map 106 bytes 3 [emitted] main
さらに追記:アグレッシブにOptimizeする
DedupePlugin
https://webpack.github.io/docs/list-of-plugins.html#dedupeplugin
AggressiveMergingPlugin
https://webpack.github.io/docs/list-of-plugins.html#aggressivemergingplugin