43 webpack optimization - Code splitting

Code segmentation

So far, the output of build JS contains javaScript and Css code, and the dependent modules used in the project will also be packaged into build JS JS is huge. It's loading build JS will take a lot of time, resulting in slow page loading. Therefore, the output files need to be reasonably divided to generate multiple multi type files, and then make full use of the browser's parallel request mechanism to request these files at the same time to improve the loading speed of the page.

Segmentation of Css

Use mini Css extract plugin to split Css code. Its configuration is as follows:

use: [
    MiniCssExtractPlugin.loader,
    'css-loader',
    // Other loader s
]

You also need to configure plugins as follows:

plugins: [
    new MiniCssExtractPlugin({
        filename: 'css/[name].[hash:5].css',
        chunkFilename: '[id].css',
    }),
]

So far, the separation of CSS code is realized, and a CSS folder is specially generated to store the extracted CSS files, making the directory structure more standardized.

Segmentation of javaScript

The segmentation of javaScript code can be divided into two parts: synchronous code segmentation and asynchronous code segmentation.

Synchronous code splitting is realized through SplitChunksPlugin. Its default configuration is as follows:

module.exports = {
    optimization: {
        splitChunks: {
            /**
            * async Asynchronous code segmentation only
            * initial Split only for synchronous code
            * all Split all codes (recommended)
            */
            chunks: 'async',
            // Modules larger than 30000 bit are divided
            minSize: 30000,
            // When the module is larger than maxSize, the secondary segmentation is performed. If it is set to 0, the secondary segmentation is not performed
            maxSize: 0,
            // Code segmentation is performed only when the number of modules introduced is greater than or equal to minChunks
            minChunks: 1,
            // The maximum number of js files loaded asynchronously is the boundary condition for code segmentation
            maxAsyncRequests: 5,
            //Take the maximum number of initially loaded js files as the boundary condition for code segmentation
            maxInitialRequests: 3,
            // Code division generated file name link symbol
            automaticNameDelimiter: '~',
            // Code division generation file automatically generates file name
            name: true,
            // Code split cache group: the split code file is output as a file through the cache group.
            cacheGroups: {
                // Third party module segmentation
                vendors: {
                    // Regular matching module path (specified scope)
                    test: /[\\/]node_modules[\\/]/,
                    // Priority. The higher the priority, the first to perform its corresponding segmentation operation (- 10-20)
                    priority: -10
                },
                default: {
                    // Default cache group. Generally, priority is set to the lowest value
                    minChunks: 2,
                    priority: -20,
                    // Indicates whether to reuse existing chunk s
                    reuseExistingChunk: true
                }
            }
        }
    }
}

In the project, in order to realize a single page, we created and used history JS, now we use SplitChunks to remove it from build JS. The configuration is as follows:

module.exports = {
    optimization: {
        splitChunks: {
            // The configuration in cacheGroups can override the configuration in splitChunks
            cacheGroups: {
                common: {
                    test: /utils\/history\.js/,
                    chunks: "all",
                    minChunks: 1,
                    minSize: 500,
                    filename: 'common/common.js'
                }
            }
        }
    }
}

Now there is more common in the output resource common directory JS, whose content is history JS package, with a size of 3.18Kib, and build JS volume becomes smaller, indicating that the code segmentation is successful.

It is worth noting that the current construction efficiency will be slower than before, because the divided code also needs systematic I/O operation, and the redundant time is almost spent on it. In order to optimize the loading of the page, reasonable code segmentation is inevitable. In different project scenarios, developers need to seriously consider how to configure in order to achieve a win-win situation for developers and users.

Asynchronous code segmentation is similar to synchronous code segmentation. It is worth noting that if you use babel related modules to process project files, you need to use @ babel / plugin syntax dynamic import plug-in to realize asynchronous code segmentation. Its configuration is as follows:

{
    loader: 'babel-loader',
        options: {
        // Preset collection
        presets: ['@babel/preset-env'],
            // Plug in collection
            plugins: [
                // Use other plug-ins
                "@babel/plugin-syntax-dynamic-import"
            ]
    }
}

The plug-in enables Babel to parse and recognize the import() dynamic import syntax. After configuration, it can split the code loaded on demand.

The demo code is as follows:

const btns = document.getElementById("home-dialog-btn");
btns.onclick = () => {
    import('../../utils/dialog').then(res => {
        console.log(res.default);
    })
}

Keywords: Javascript Front-end Webpack

Added by tadapapaya on Wed, 15 Dec 2021 23:02:32 +0200