webpack学习笔记--优化

简介: webpack学习笔记--优化

前言

了解了webpack的基本配置之后,接下来应该关注其优化策略。webpack的优化策略对我们的程序有着极大的性能提升。这是我记录学习webpack优化的文章,纪录的同时也希望分享给大家。

DLL动态链接库

在开发的过程中,我们会引入像reactreact-dom这样的库,这样的库基本上每一次打包时它们的内容都不会改变,所以我们引入动态链接库。将它们打包一次,在之后的构建过程中它们就不会被打包,打包的模块也会使用动态链接库里面的代码而不是去node_modules中取,这样我们的构建速度就会大大提升。下面让我们来看看webpack中怎么构建动态链接库。

打包

我们新建一个webpack.dll.config.js的文件,配置如下

const path = require('path')
const DllPlugin = require('webpack/lib/DllPlugin')
module.exports = {
    entry:{
        //将react、react-dom放到动态链接库中
        react:['react','react-dom']
    },
    output:{
        //输出的文件名称,[name]指的是当前动态链接库的名称,即react
        filename:'[name].dll.js',
        //输出到dist目录下
        path:path.resolve(__dirname,'dist'),
        //存动态链接库的全局变量名称,即_dll_react,加上_dll_防止全局变量冲突
        library:'_dll_[name]',
    },
    plugins:[
        new DllPlugin({
            //动态链接库的全局变量名称,需要和library一致
            name:'_dll_[name]',
            path:path.join(__dirname,'dist','[name].manifest.json')
        })
    ]
}

下面执行命令npx webpack --config webpack.dll.config.js,dist目录下多了两个文件,分别是react.dll.jsreact.manifest.jsonreact.dll.js里面包含React的基础运行环境,即reactreact-dom模块。react.manifest. json用于描述在动态链接库文件中包含哪些模块。

然后再新建一个webpack.config.js文件,在打包出来的chunk块中声明需要引入的动态链接库,具体配置如下

const path = require('path')
const DllReferencePlugin = require('webpack/lib/DllReferencePlugin')
module.exports = {
    entry: {
        main: './main.js'
    },
    output:{
        filename:'bundle.js',
        path:path.resolve(__dirname,'dist')
    },
    module:{
        rules:[

        ]
    },
    plugins:[
        new DllReferencePlugin({
            manifest:require('./dist/react.manifest.json')
        })
    ]
}

执行命令npx webpack,在dist目录下生成bundle.js

引入

然后我们在dist目录下新建一个index.html文件,引入打包构建出来的文件和动态链接库。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
    <script src="./react.dll.js"></script>
    <script src="./buncld.js"></script>
</body>
</html>

HappyPack

当文件数量变多时,webpack构建速度慢的问题会变得特别明显。但是运行在node之上的webpack是单线程的,不能同时处理多个任务。而HappyPack可以让webpack做到这一点,它将任务分解成多个子进程去并发执行。由于JavaScript是单线程模型,所以想要发挥多核CPU的作用只能通过多进程而不能通过多线程来实现。 接入HappyPack的代码如下

const path = require('path')
const HappyPack = require('happypack');
module.exports = {
    entry: {
        main: './main.js'
    },
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [{
                test: /\.js$/,
                //以babel为id,转交给happypack处理
                use: ['happypack/loader?id=babel'],
            },
            {
                test: /\.css$/,
                //以css为id,转交给happypack处理
                use: ['happypack/loader?id=css']
            }

        ]
    },
    plugins: [
        new HappyPack({
            id: 'babel',
            loaders: ['babel-loader']
        }),
        new HappyPack({
            id: 'css',
            loaders: ['style-loader','css-loader']
        })
    ]
}

执行构建命令 npx webpack 从命令行的输出可以看出HappyPack已经生效

Happy[babel]: Version: 5.0.1. Threads: 3
Happy[babel]: All set; signaling webpack to proceed.
Happy[css]: Version: 5.0.1. Threads: 3
Happy[css]: All set; signaling webpack to proceed.

压缩代码

为了提升网页的加载速度,可以对资源进行压缩。

压缩JavaScript

这里我们会用到UglifyJS,它通过去掉无效代码、去掉日志输出、缩短变量名,从而来优化我们的代码。 简单的配置如下

const UglifyJSPlugin = require('webpack/lib/optimize/UglifyJsPlugin')
module.exports = {
    //以上省略。。。
    plugins: [
        //压缩输出的 JavaScript 代码
        new UglifyJSPlugin({
            compress: {
                //在 UglifyJS 删除没有用到的代码时不输出警告
                warnings: false,
                //删除所有 console 语句, 可以兼容IE浏览器
                drop_console: true,
                //内嵌己定义但是只用到一次 的变量
                collapse_vars: true,
                //提取出现了多次但是没有定义成变量去 用的静态值
                reduce_vars: true,
                output: {
                    //最紧凑的输出
                    beautify: false,
                    //删除所有注释
                    comments: false,
                }
            }
        })
    ]

压缩CSS

CSS也可以向JavaScript一样被压缩,这里用到的工具是cssnanocssnano的意义不仅仅是删除空格,它可以理解CSS代码。例如 margin:10px 20px 10px 20px 会被压缩为 margin:10px 20px基本配置如下

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-plugin')
module.exports = {
    //以上省略。。。。
    module: {
        rules: [{
            test: /\.css$/,
            use: [ExtractTextPlugin.extract({
                use: ['style-loader', 'css-loader?minimize']
            })]
        }]
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'./index.html',
            filename:'index.html'
        }),
        new ExtractTextPlugin({
            filename: '[name]_[contenthash:8].css'
        })
    ]
}

提取公共代码

如果将多个页面的公共代码抽离成单独的文件,就能优化一些问题。例如相同的资源被重复加载,浪费用户的流量和服务器的成本。每个页面要加载的资源太大,导致网页首屏加载缓慢,影响用户体验。 基本配置如下,此配置主要针对多页面。单页就不存在于公共代码这一说法了。

import 'react'
import 'react-dom'
import './index.css' //每个页面都用到的样式
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin')
module.exports = {
    module: {
        entry: './main.js',
        rules: [{
            test: /\.css$/,
            use: [ExtractTextPlugin.extract({
                use: ['style-loader', 'css-loader?minimize']
            })]
        }]
    },
    plugins: [
        new CommonsChunkPlugin({
            //从已有的common和base两个现成的chunks中提取公共部分 
            chunks: ['common', 'base'],
            //将公共部分放到base中 这样配置之后 common会变小,因为公共部分都跑到了base里,而base不变
            name: 'base'
        })
    ]
}

为了能使网页运行,以网页A为例,除了打包出来的A页面的JavaScript代码还需引入公共部分代码

<script src= 'base.js'></script>
<script src='common.js'></script>
<script src='a.js'></script> 

按需加载

单页应用首次渲染缓慢,一个很重要的原因是一次性加载了所有功能对应的代码。这个时候如果采用按需加载,我们网站的性能将会大大提升。 在webpack里,按需加载可以这样来写。例如我们只打包出了一个bundle.js。在bundle.js中,有这么一段代码

window.document.getElementById('button').addEventListener('click',()=>{
    import('./show').then(show=>{
        show('webpack')
    })
})

show.js

module.exports= function (content) {
    window.aleat(`hello ${content}`)
}

webpack中内置了import语句的支持,当遇到这样的语句时,首先会生成一个新的chunk,然后触发import的时候再去加载这个chunk,返回的是一个Promise对象,在加载成功时使用then方法进行下面的操作,为了让webpack正确打包chunk,配置文件中需加入

output:{
    //从entry打包生成的chunk
    filename:'[name].js',
    //动态加载生成的chunk
    chunkFileName:'[name].js'
}

最后

webpack的优化配置还有很多,这里只记录了我平时常用的,具体详情还请查阅官方文档。

相关文章
|
6月前
|
JSON JavaScript 前端开发
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)(下)
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)
89 2
|
3月前
|
缓存 前端开发 数据可视化
Webpack Bundle Analyzer:深入分析与优化你的包
Webpack Bundle Analyzer是一款可视化工具,帮助分析Webpack构建结果,找出占用空间较大的模块以便优化。首先需安装Webpack和Webpack Bundle Analyzer,接着在`webpack.config.js`中配置插件。运行Webpack后,会在`dist`目录生成`report.html`,展示交互式图表分析包大小分布。为优化可采用代码分割、Tree Shaking、压缩插件、加载器优化、模块懒加载、代码预热、提取公共库、使用CDN、图片优化、利用缓存、避免重复模块、使用Source Maps、优化字体和图标、避免全局样式污染以及优化HTML输出等策略。
132 3
|
16天前
|
缓存 前端开发 JavaScript
前端性能优化:Webpack与Babel的进阶配置与优化策略
【10月更文挑战第28天】在现代Web开发中,Webpack和Babel是不可或缺的工具,分别负责模块打包和ES6+代码转换。本文探讨了它们的进阶配置与优化策略,包括Webpack的代码压缩、缓存优化和代码分割,以及Babel的按需引入polyfill和目标浏览器设置。通过这些优化,可以显著提升应用的加载速度和运行效率,从而改善用户体验。
35 6
|
18天前
|
缓存 监控 前端开发
前端工程化:Webpack与Gulp的构建工具选择与配置优化
【10月更文挑战第26天】前端工程化是现代Web开发的重要趋势,通过将前端代码视为工程来管理,提高了开发效率和质量。本文详细对比了Webpack和Gulp两大主流构建工具的选择与配置优化,并提供了具体示例代码。Webpack擅长模块化打包和资源管理,而Gulp则在任务编写和自动化构建方面更具灵活性。两者各有优势,需根据项目需求进行选择和优化。
47 7
|
17天前
|
缓存 前端开发 JavaScript
前端工程化:Webpack与Gulp的构建工具选择与配置优化
【10月更文挑战第27天】在现代前端开发中,构建工具的选择对项目的效率和可维护性至关重要。本文比较了Webpack和Gulp两个流行的构建工具,介绍了它们的特点和适用场景,并提供了配置优化的最佳实践。Webpack适合大型模块化项目,Gulp则适用于快速自动化构建流程。通过合理的配置优化,可以显著提升构建效率和性能。
31 2
|
5月前
|
缓存 JavaScript 前端开发
探讨如何通过一系列优化策略来提升TypeScript与Webpack的构建性能。
【6月更文挑战第11天】本文探讨了优化TypeScript与Webpack构建性能的策略。理解Webpack的解析、构建和生成阶段是关键。优化包括:调整tsconfig.json(如关闭不必要的类型检查)和webpack.config.js选项,启用Webpack缓存,实现增量构建,代码拆分和懒加载。通过这些方法,可以提升构建速度,提高开发效率。
79 0
|
3月前
|
前端开发 JavaScript 开发者
Angular与Webpack协同优化:打造生产级别的打包配置——详解从基础设置到高级代码拆分和插件使用
【8月更文挑战第31天】在现代前端开发中,优化应用性能和加载时间至关重要,尤其是对于使用Angular框架的项目。本文通过代码示例详细展示了如何配置Webpack,以实现生产级别的打包优化。从基础配置到生产环境设置、代码拆分,再到使用加载器与插件,每个步骤都旨在提升应用效率,确保快速加载和稳定运行。通过这些配置,开发者能更好地控制资源打包,充分发挥Webpack的强大功能。
86 0
|
4月前
|
缓存 JSON 前端开发
Webpack打包优化实践
【7月更文挑战第17天】Webpack的打包优化是一个持续的过程,需要开发者根据项目的实际情况选择合适的优化策略。通过拆分代码、压缩代码、使用Tree Shaking、优化加载器配置、利用缓存以及进行性能分析,我们可以有效提升Webpack的打包效率和应用的加载
|
6月前
|
缓存 JavaScript 前端开发
【TypeScript技术专栏】TypeScript与Webpack构建优化
【4月更文挑战第30天】本文探讨了优化TypeScript与Webpack构建性能的策略。理解Webpack的解析、构建和生成阶段是关键。优化包括:调整tsconfig.json(关闭不必要的类型检查,适配目标环境)和webpack.config.js(配置entry、output、resolve,使用压缩插件)。启用Webpack缓存和增量构建,利用代码拆分与懒加载,能有效提升构建速度和开发效率。
87 0
|
6月前
|
缓存 前端开发 算法
Webpack 进阶:深入理解其工作原理与优化策略
Webpack 进阶:深入理解其工作原理与优化策略
171 2