webapck

webpack性能优化总结:面试题

1、优化 Loader 配置

由于 Loader 对文件的转换操作很耗时,所以需要让尽可能少的文件被 Loader 处理。可以通过 test/include/exclude 三个配置项来命中 Loader 要应用规则的文件。

2、优化 resolve.modules 配置

resolve.modules 的默认值是['node_modules'],含义是先去当前目录的 node_modules 目录下去找我们想找的模块,如果没找到就去上一级目录 ../node_modules 中找,再没有就去 ../../node_modules 中找,以此类推。这和 Node.js 的模块寻找机制很相似。 当安装的第三方模块都放在项目根目录的 node_modules 目录下时,就没有必要按照默认的方式去一层层地寻找,可以指明存放第三方模块的绝对路径,以减少寻找.

3、优化 resolve.mainFields 配置

在安装的第三方模块中都会有一个 package.json 文件,用于描述这个模块的属性,其中可以存在多个字段描述入口文件,原因是某些模块可以同时用于多个环境中,针对不同的运行环境需要使用不同的代码。

4、优化 resolve.alias 配置

resolve.alias 配置项通过别名来将原导入路径映射成一个新的导入路径。

在实战项目中经常会依赖一些庞大的第三方模块,以 React 库为例,发布出去的 React 库中包含两套代码

一套是采用 CommonJS 规范的模块化代码,这些文件都放在 lib 录下,以 package.json 中指定的入口文件 react.js 为模块的入口

一套是将 React 的所有相关代码打包好的完整代码放到一个单独的文件中, 这些代码没有采用模块化,可以直接执行。其中 dist/react.js 用于开发环境,里面包含检查和警告的代码。dist/react.min.js 用于线上环境,被最小化了。

在默认情况下, Webpack 会从入口文件 ./node_modules/react/react.js 开始递归解析和处理依赖的几十个文件,这会是一个很耗时的操作 通过配置 resolve.alias, 可以让 Webpack 在处理 React 库时,直接使用单独、完整的 react.min.js 文件,从而跳过耗时的递归解析操作

5、优化 resolve.extensions 配置

在导入语句没带文件后缀时,Webpack 会自动带上后缀去尝试询问文件是否存在。如果这个列表越长,或者正确的后缀越往后,就会造成尝试的次数越多,所以resolve .extensions 的配置也会影响到构建的性能 在配置resolve.extensions 时需要遵守 以下几点,以做到尽可能地优化构建性能。

后缀尝试列表要尽可能小,不要将项目中不可能存在的情况写到后缀尝试列表中。

频率出现最高的文件后缀要优先放在最前面,以做到尽快退出寻找过程。

在源码中写导入语句时,要尽可能带上后缀 从而可以避免寻找过程。例如在确定的情况下将 require ( './data ') 写成 require ('./data.json')

6、优化文件监听的性能

在开启监听模式时,默认情况下会监听配置的 Entry 文件和所有 Entry 递归依赖的文件,在这些文件中会有很多存在于 node_modules 下,因为如今的 Web 项目会依赖大量的第三方模块, 所以在大多数情况下我们都不可能去编辑 node_modules 下的文件,而是编辑自己建立的源码文件,而一个很大的优化点就是忽略 node_modules 下的文件,不监听它们。

7、压缩 JavaScript

所谓压缩就是将代码变的更小,安全转换是指通过重写代码而不改变代码逻辑。这方面的好例子包括重命名变量,甚至是删除整个的访问不到的代码块(if (false))。

不安全的转换可能会破坏代码,因为它们可能会丢失底层代码所依赖的隐含内容。例如,Angular 1在使用模块时需要特定的函数参数命名。除非在这种情况下采取预防措施,否则重写参数会破坏代码。

8、修改 JavaScript 压缩处理器

在 Webpack 4 中,通过两个配置字段控制压缩过程:optimization.minimize 字段切换压缩处理器,而 optimization.minimizer 数组用来配置压缩处理器。

为了调整默认值,我们将 terser-webpack-plugin 附加到项目中,以便可以调整它。

minimizer

配置 Webpack 使用的压缩工具。常用的压缩工具有 UglifyJS、TerserJS 和 CSSMinimizerPlugin 等。

splitChunks

配置 Webpack 如何将打包后的代码拆分为多个文件,以便实现按需加载。splitChunks 的默认配置已经足够满足大多数情况,但也可以根据具体需求进行调整。

runtimeChunk

配置 Webpack 为每个入口添加一个额外的 chunk,用于存放公共代码和运行时代码。这个选项可以有效减少打包后的文件大小,提高网站性能。

usedExports

开启 Tree Shaking 功能,用于删除未被使用的代码。

moduleIds(模块 ID)

指定 Webpack 如何生成模块 ID,默认为自增的数字,可以使用 named 选项将 ID 转换为可读性更好的名称。

splitChunks.maxSize(chunk 最大大小)

指定一个 chunk 的最大大小,超过这个大小将自动进行分割。

splitChunks.minChunks(最小使用次数)

指定一个模块被使用的最小次数才会被抽取出来形成单独的 chunk。

splitChunks.cacheGroups(缓存组)

指定 Webpack 如何根据不同的模块抽取出不同的 chunk,例如将第三方库抽取成单独的 chunk

webpack中loader和plugin的原理

1、plugin的原理

Webpackplugin插件是用来扩展Webpack功能的JavaScript对象,它们可以在Webpack编译过程中执行自定义的任务,例如:优化资源、压缩代码、代码分割等。Webpack插件机制的核心是一个钩子系统(Hook System),Webpack在不同的编译阶段提供不同的钩子,插件可以监听这些钩子,根据自己的需求来执行相应的操作。

plugin的工作流程:

  1. 创建一个JavaScript对象,它应该包含一个apply方法。

  1. 在apply方法中,使用Webpack提供的钩子来监听Webpack编译过程中的特定事件,例如:compilation、emit、done等。

  1. 在钩子函数中,可以执行任意JavaScript代码,例如:读写文件、修改文件内容、输出信息等。

  1. 最后,将插件对象传递给Webpack配置文件的plugins选项中。

2、Loader的原理

Webpack Loader是用来处理非JavaScript文件的Webpack插件,它们可以将非JavaScript文件转换为JavaScript模块,以便在Webpack中引用和使用。Webpack Loader机制的核心是一个转换函数,这个函数接收一个源文件作为输入,然后输出一个JavaScript模块代码字符串。

Loader的工作流程:

  1. 读取源文件的内容。

  1. 对源文件进行转换,例如:将Less或Sass文件转换为CSS文件、将TypeScript文件转换为JavaScript文件等。

  1. 生成JavaScript模块代码字符串,并返回它。

  1. 将生成的JavaScript模块代码字符串注入到Webpack打包后的代码中,以便在浏览器中运行。

webpack中常用的loader 和plugin

在使用插件前要将其先进行下载安装 npm i xxx

1、loader中常用的插件

  1. less-loader 用于将less编译成css

  1. css-loader 用于将css以CommonJS语法打包到JS中;必须配合style-loader共同使用,只安装css-loader样式不会生效。

  1. style-loader 用于动态创建style标签,将css引入其中

  1. sass-loader css预处理器

  1. postcss-loader 用于补充css样式各种浏览器内核前缀,用于处理css兼容问题,需要和postcss、postcss-preset-env配合使用。

  • 使用的时机为:["css-loader","postcss-loader","less-loader"]。

  • 需要在package.json中配置browserslist属性指定具体的兼容规则

  • browserslist是一个单独的库,被广泛用在各种涉及浏览器/移动端的兼容性支持工具中

  1. babel-loader 将Es6+ 语法转换为Es5语法;

  • babel-loader 这是使babel和webpack协同工作的模块

  • @bable/core 这是babel编译器核心模块

  • @babel/preset-env 这是babel官方推荐的预置器,可根据用户的环境自动添加所需的插件和补丁来编译Es6代码;

  • 直接使用只能处理简单的语法,Promise等无法处理。

  • 借助polyfill完成高级es6语法的转换,缺点:所有都转换,无法按需转换,生成的js体积大。

  • 使用core-js配合polyfill完成按需转换。

  1. ts-loader 用于配置项目typescript

  1. html-loader 想引入一个html页面代码片段赋值给DOM元素内容使用,这时就用到html-loader

  1. file-loader 用于处理文件类型资源,如jpg,png等图片。返回值为publicPath为准。

  1. eslint-loader 用于检查代码是否符合规范,是否存在语法错误

2、Plugin中常用的插件

  1. html-webpack-plugin 根据指定模板自动创建html文件,并且引入外部资源

  1. mini-css-extract-plugin 将 CSS 提取为独立的文件的插件,对每个包含 css 的 js 文件都会创建一个 CSS 文件,支持按需加载 css 和 sourceMap。只能用在 webpack4 中。

  1. optimize-css-assets-webpack-plugin 用于压缩css,减小 css 打包后的体积。

  1. friendly-errors-webpack-plugin webpack 构建日志美化插件

  1. SplitChunksPlugin 公共脚本分离成公共包,并进行优化。webpack 自带

webpack和vite的区别

1、底层的语言

webpack是基于node.js构建,js是以毫秒计数。

vite是基于esbulid预构建依赖,esbulid是采用go语言编写的,go语言是纳秒级别的。

总结:因为js是毫秒级别,go语言是纳秒级别。所以vite比webpack打包器快10-100倍。

2、打包过程

webpack:分析各个模块之间的依赖=>然后进行编译打=>打包后的代码在本地服务器渲染。随着模块增多,打包的体积变大,造成热更新速度变慢。

vite:启动服务器=>请求模块时按需动态编译显示。(vite遵循的是ES Modlues模块规范来执行代码,不需要打包编译成es5模块即可在浏览器运行。)

总结:vite启动的时候不需要分析各个模块之间的依赖关系、不需要打包编译。vite可按需动态编译缩减时间。当项目越复杂、模块越多的情况下,vite明显优于webpack

3、热更新

webpack:模块以及模块依赖的模块需重新编译

vite:浏览器重新请求该模块即可

4、使用方面

vite开箱即用,更加简单,基于浏览器esm,使得hmr更加优秀,达到极速的效果;webpack更加灵活,api以及插件生态更加丰富。

5、原理不同

webpack是bundle,自己实现了一套模块导入导出机制。vite是利用浏览器的esm能力,是bundless。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值