|
| 1 | +# Info |
| 2 | + |
| 3 | +This example illustrates webpack's algorthim for automatic deduplication using `optimization.splitChunks`. |
| 4 | + |
| 5 | +This example application contains 7 pages, each of them importing 1-3 modules from the `node_modules` folder (vendor libs) and 0-3 modules from the `stuff` folder (application modules). In reallity an application is probably more complex, but the same mechanisms apply. |
| 6 | + |
| 7 | +The following configuration is used: |
| 8 | + |
| 9 | +* `optimization.splitChunks.chunks: "all"` - This opt-in into automatic splitting of initial chunks which is off by default |
| 10 | +* `optimization.splitChunks.maxInitial/AsyncRequests: 20` - This opt-in into a HTTP2 optimized splitting mode by increasing the allowed amount of requests. Browser only supports 6 requests in parallel for HTTP1.1. |
| 11 | + |
| 12 | +# Interpreting the result |
| 13 | + |
| 14 | +* `pageA.js` the normal output files for the entrypoint `pageA` |
| 15 | +* `vendors~pageD~pageE~pageF~pageG.js` vendor libs shared by these pages extracted into a separate output file when larger then the threshold in size |
| 16 | +* `vendors~pageA.js` vendors only used by a single page but larger than the threshold in size |
| 17 | +* `pageA~pageD~pageF.js` application modules shared by these pages and larger than the threshold in size |
| 18 | + |
| 19 | +The threshold is here 40 bytes, but by default (in a real application) 30kb. |
| 20 | + |
| 21 | +Some modules are intentially duplicated, i. e. `./stuff/s4.js` is shared by `pageA` and `pageC`, but it's the only shared module so no separate output file is created because it would be smaller than the threshold. A separate request (which comes with an overhead and worsen gzipping) is not worth the extra bytes. |
| 22 | + |
| 23 | +Note: decreasing `maxInitial/AsyncRequest` will increase duplication further to reduce the number of requests. Duplication doesn't affect initial page load, it only affects download size of navigations to other pages of the application. |
| 24 | + |
| 25 | +## webpack.config.js |
| 26 | + |
| 27 | +``` |
| 28 | +module.exports = { |
| 29 | + // mode: "development || "production", |
| 30 | + entry: { |
| 31 | + pageA: "./pages/a", |
| 32 | + pageB: "./pages/b", |
| 33 | + pageC: "./pages/c", |
| 34 | + pageD: "./pages/d", |
| 35 | + pageE: "./pages/e", |
| 36 | + pageF: "./pages/f", |
| 37 | + pageG: "./pages/g" |
| 38 | + }, |
| 39 | + optimization: { |
| 40 | + splitChunks: { |
| 41 | + chunks: "all", |
| 42 | + maxInitialRequests: 20, // for HTTP2 |
| 43 | + maxAsyncRequests: 20, // for HTTP2 |
| 44 | + minSize: 40 // for example only: choosen to match 2 modules |
| 45 | + // omit minSize in real use case to use the default of 30kb |
| 46 | + } |
| 47 | + } |
| 48 | +}; |
| 49 | +``` |
| 50 | + |
| 51 | +## Production mode |
| 52 | + |
| 53 | +``` |
| 54 | +Hash: 0a1b2c3d4e5f6a7b8c9d |
| 55 | +Version: webpack 4.8.3 |
| 56 | + Asset Size Chunks Chunk Names |
| 57 | + pageG.js 1.15 KiB 7 [emitted] pageG |
| 58 | +vendors~pageD~pageE~pageF~pageG.js 119 bytes 0 [emitted] vendors~pageD~pageE~pageF~pageG |
| 59 | + vendors~pageD~pageE~pageF.js 178 bytes 2 [emitted] vendors~pageD~pageE~pageF |
| 60 | + vendors~pageA~pageB~pageC.js 180 bytes 3 [emitted] vendors~pageA~pageB~pageC |
| 61 | + vendors~pageC.js 121 bytes 4 [emitted] vendors~pageC |
| 62 | + vendors~pageB.js 121 bytes 5 [emitted] vendors~pageB |
| 63 | + vendors~pageA.js 121 bytes 6 [emitted] vendors~pageA |
| 64 | + pageA~pageD~pageF.js 156 bytes 1 [emitted] pageA~pageD~pageF |
| 65 | + pageF.js 1.18 KiB 8 [emitted] pageF |
| 66 | + pageE.js 1.17 KiB 9 [emitted] pageE |
| 67 | + pageD.js 1.18 KiB 10 [emitted] pageD |
| 68 | + pageC.js 1.27 KiB 11 [emitted] pageC |
| 69 | + pageB.js 1.27 KiB 12 [emitted] pageB |
| 70 | + pageA.js 1.18 KiB 13 [emitted] pageA |
| 71 | +Entrypoint pageA = vendors~pageA~pageB~pageC.js vendors~pageA.js pageA~pageD~pageF.js pageA.js |
| 72 | +Entrypoint pageB = vendors~pageA~pageB~pageC.js vendors~pageB.js pageB.js |
| 73 | +Entrypoint pageC = vendors~pageA~pageB~pageC.js vendors~pageC.js pageC.js |
| 74 | +Entrypoint pageD = vendors~pageD~pageE~pageF~pageG.js vendors~pageD~pageE~pageF.js pageA~pageD~pageF.js pageD.js |
| 75 | +Entrypoint pageE = vendors~pageD~pageE~pageF~pageG.js vendors~pageD~pageE~pageF.js pageE.js |
| 76 | +Entrypoint pageF = vendors~pageD~pageE~pageF~pageG.js vendors~pageD~pageE~pageF.js pageA~pageD~pageF.js pageF.js |
| 77 | +Entrypoint pageG = vendors~pageD~pageE~pageF~pageG.js pageG.js |
| 78 | +chunk {0} vendors~pageD~pageE~pageF~pageG.js (vendors~pageD~pageE~pageF~pageG) 43 bytes ={1}= ={10}= ={2}= ={7}= ={8}= ={9}= [initial] [rendered] split chunk (cache group: vendors) (name: vendors~pageD~pageE~pageF~pageG) |
| 79 | + > ./pages/d pageD |
| 80 | + > ./pages/e pageE |
| 81 | + > ./pages/f pageF |
| 82 | + > ./pages/g pageG |
| 83 | + 1 module |
| 84 | +chunk {1} pageA~pageD~pageF.js (pageA~pageD~pageF) 62 bytes ={0}= ={10}= ={13}= ={2}= ={3}= ={6}= ={8}= [initial] [rendered] split chunk (cache group: default) (name: pageA~pageD~pageF) |
| 85 | + > ./pages/a pageA |
| 86 | + > ./pages/d pageD |
| 87 | + > ./pages/f pageF |
| 88 | + [6] ./stuff/s3.js 31 bytes {1} [built] |
| 89 | + [7] ./stuff/s2.js 31 bytes {1} [built] |
| 90 | +chunk {2} vendors~pageD~pageE~pageF.js (vendors~pageD~pageE~pageF) 86 bytes ={0}= ={1}= ={10}= ={8}= ={9}= [initial] [rendered] split chunk (cache group: vendors) (name: vendors~pageD~pageE~pageF) |
| 91 | + > ./pages/d pageD |
| 92 | + > ./pages/e pageE |
| 93 | + > ./pages/f pageF |
| 94 | + 2 modules |
| 95 | +chunk {3} vendors~pageA~pageB~pageC.js (vendors~pageA~pageB~pageC) 86 bytes ={1}= ={11}= ={12}= ={13}= ={4}= ={5}= ={6}= [initial] [rendered] split chunk (cache group: vendors) (name: vendors~pageA~pageB~pageC) |
| 96 | + > ./pages/a pageA |
| 97 | + > ./pages/b pageB |
| 98 | + > ./pages/c pageC |
| 99 | + 2 modules |
| 100 | +chunk {4} vendors~pageC.js (vendors~pageC) 43 bytes ={11}= ={3}= [initial] [rendered] split chunk (cache group: vendors) (name: vendors~pageC) |
| 101 | + > ./pages/c pageC |
| 102 | + 1 module |
| 103 | +chunk {5} vendors~pageB.js (vendors~pageB) 43 bytes ={12}= ={3}= [initial] [rendered] split chunk (cache group: vendors) (name: vendors~pageB) |
| 104 | + > ./pages/b pageB |
| 105 | + 1 module |
| 106 | +chunk {6} vendors~pageA.js (vendors~pageA) 43 bytes ={1}= ={13}= ={3}= [initial] [rendered] split chunk (cache group: vendors) (name: vendors~pageA) |
| 107 | + > ./pages/a pageA |
| 108 | + 1 module |
| 109 | +chunk {7} pageG.js (pageG) 70 bytes ={0}= [entry] [rendered] |
| 110 | + > ./pages/g pageG |
| 111 | + [0] ./stuff/s1.js 31 bytes {7} {8} {10} {12} [built] |
| 112 | + [10] ./pages/g.js 39 bytes {7} [built] |
| 113 | +chunk {8} pageF.js (pageF) 144 bytes ={0}= ={1}= ={2}= [entry] [rendered] |
| 114 | + > ./pages/f pageF |
| 115 | + [0] ./stuff/s1.js 31 bytes {7} {8} {10} {12} [built] |
| 116 | + [11] ./pages/f.js 113 bytes {8} [built] |
| 117 | +chunk {9} pageE.js (pageE) 98 bytes ={0}= ={2}= [entry] [rendered] |
| 118 | + > ./pages/e pageE |
| 119 | + [4] ./stuff/s7.js 31 bytes {9} {12} [built] |
| 120 | + [12] ./pages/e.js 67 bytes {9} [built] |
| 121 | +chunk {10} pageD.js (pageD) 144 bytes ={0}= ={1}= ={2}= [entry] [rendered] |
| 122 | + > ./pages/d pageD |
| 123 | + [0] ./stuff/s1.js 31 bytes {7} {8} {10} {12} [built] |
| 124 | + [13] ./pages/d.js 113 bytes {10} [built] |
| 125 | +chunk {11} pageC.js (pageC) 206 bytes ={3}= ={4}= [entry] [rendered] |
| 126 | + > ./pages/c pageC |
| 127 | + [5] ./stuff/s4.js 31 bytes {11} {13} [built] |
| 128 | + [14] ./stuff/s6.js 31 bytes {11} [built] |
| 129 | + [15] ./stuff/s5.js 31 bytes {11} [built] |
| 130 | + [17] ./pages/c.js 113 bytes {11} [built] |
| 131 | +chunk {12} pageB.js (pageB) 206 bytes ={3}= ={5}= [entry] [rendered] |
| 132 | + > ./pages/b pageB |
| 133 | + [0] ./stuff/s1.js 31 bytes {7} {8} {10} {12} [built] |
| 134 | + [4] ./stuff/s7.js 31 bytes {9} {12} [built] |
| 135 | + [18] ./stuff/s8.js 31 bytes {12} [built] |
| 136 | + [20] ./pages/b.js 113 bytes {12} [built] |
| 137 | +chunk {13} pageA.js (pageA) 144 bytes ={1}= ={3}= ={6}= [entry] [rendered] |
| 138 | + > ./pages/a pageA |
| 139 | + [5] ./stuff/s4.js 31 bytes {11} {13} [built] |
| 140 | + [22] ./pages/a.js 113 bytes {13} [built] |
| 141 | +``` |
0 commit comments