搞笑网站模板,网页游戏排行榜前十2023,哪个公司做网站专业,wordpress免费模版安装教程本文主要总结经常用到的一些代码性能优化、减小代码体积、提升webpack打包构建速度等内容的方法。具体的实现可参考webpack官网查看相关示例。 注#xff1a;如果读者还未接触过webpack#xff0c;请先了解webpack的基本使用。
正文#xff1a;
SourceMap ---- 提升开发体…本文主要总结经常用到的一些代码性能优化、减小代码体积、提升webpack打包构建速度等内容的方法。具体的实现可参考webpack官网查看相关示例。 注如果读者还未接触过webpack请先了解webpack的基本使用。
正文
SourceMap ---- 提升开发体验
SourceMap源代码映射是一个用来生成源代码与构建后代码一一映射的文件的方案。 使用webpack打包之后会生成一个与打包文件对应的.map文件里面包含源代码和构建后代码每一行、每一列的映射关系。当构建后的代码报错时其会通过.map文件将构建后代码中出错的位置映射到源代码出错的位置从而让浏览器的报错提示的是源代码文件报错的位置信息帮助开发人员快速定位。 解决方案 可以通过设置devtool来控制如何生成source map。开发模式下我们一般使用cheap-module-source-map优点打包编译速度快只包含行映射缺点没有列映射。生产模式下使用source-map优点包含行和列的映射缺点打包编译速度慢。
// webpack.dev.js
module.exports {mode: development,devtool: cheap-module-source-map
}
// webpack.prod.js
module.exports {mode: production,devtool: source-map
}提升构建打包速度
1. HotModuleReplacementHMR模块热替换
在webpack5中热更新是webpack默认开启的。开发时只重新编译打包更新变化了的代码不变的代码使用缓存从而实现局部更新而不是刷新整个页面。
// webpack.config.js
module.exports {devServer: {hot: true}
}2. OneOf 规则数组 只使用第一个匹配规则
当在webpack配置文件中写了很多处理不同资源文件的loader时资源文件会遍历所有loader进行解析处理当使用了oneOf规则之后资源文件一旦被某个loader处理了就不会继续往下遍历从而使打包速度更快。
// webpack.config.js
module.exports {module: {rules: [{oneOf: [{test: /\.css$/,use: [style-loader, css-loader]},{test: /\.less$/,use: [style-loader, css-loader, less-loader]},{test: /\.s[sc]ss$/,use: [style-loader, css-loader, sass-loader]},{test: /\.styl$/,use: [style-loader, css-loader, stylus-loader]},{test: /\.(png|jpe?g|gif|webp|svg)$/,type: asset,parser: {dataUrlCondition: {// 小于10KB的图片转base64maxSize: 10 * 1024}},generator: {filename: static/img/[hash:10][ext][query]}},{test: /\.(ttf|woff2?|mp3|mp4|avi)$/,type: asset/resource,generator: {filename: static/media/[hash:10][ext][query]}},{test: /.\.js$/,exclude: /node_modules/,loader: babel-loader}]}]}
}3. Include/Exclude
引入或排除某些文件处理的文件更少速度更快。例如开发时我们用到了第三方的库或者插件那么这些文件是不需要编译就可以使用的所以可以排除exclude对这些文件的处理。或者只处理include某个文件夹下面的源代码。二者选其一使用。
// webpack.config.js
const path require(path)
const ESlintPlugin require(eslint-webpack-plugin)module.exports {module: {rules: [{test: /.\.js$/,// 排除node_modules下的文件 不作处理exclude: /node_modules/,loader: babel-loader},// 或者{test: /.\.js$/,// 只处理src下的内容 其他文件不处理include: path.resolve(__dirname, ./src),loader: babel-loader},]},plugins: [new ESlintPlugin([context: path.resolve(__dirname, ./src),exclude: /node_modules/, // 默认值//或者include: path.resolve(__dirname, ./src),])]
}4. Cache 缓存
可以对eslint和babel处理的结果进行缓存让后续打包速度更快。
// webpack.config.js
const path require(path)
const ESlintPlugin require(eslint-webpack-plugin)module.exports {module: {rules: [{test: /.\.js$/,// 排除node_modules下的文件 不作处理exclude: /node_modules/,loader: babel-loader,options: {cacheDirectory: true, // 开启babel缓存cacheCompression: false // 关闭缓存文件压缩 }},]},plugins: [new ESlintPlugin([context: path.resolve(__dirname, ./src),exclude: /node_modules/, // 默认值cache: true, // 开启缓存cacheLocation: path.resolve(__dirname, ./node_modules/.cache/eslintcache) // 定义缓存位置])]
}5. Thead 多进程打包
当项目非常庞大的时候打包速度越来越慢主要是对js文件进行检查eslint、编译babel、压缩terser要提升运行速度可以开启多进程同时处理js文件。由于进程启动通信都是有开销的所以只有在代码比较多的时候处理才有效果。
npm i thread-loader --save-dev使用时需将此 loader 放置在其他 loader 之前。放置在此 loader 之后的 loader 会在一个独立的 worker 池中运行。 在 worker 池中运行的 loader 是受到限制的。例如
这些 loader 不能生成新的文件。这些 loader 不能使用自定义的 loader API也就是说不能通过插件来自定义。这些 loader 无法获取 webpack 的配置。 每个 worker 都是一个独立的 node.js 进程其开销大约为 600ms 左右。同时会限制跨进程的数据交换。
请仅在耗时的操作中使用此 loader
// webpack.config.js
const os require(os)
const ESlintPlugin require(eslint-webpack-plugin)
const TerserPlugin require(terser-webpack-plugin) // 内置插件const threads os.cups().length // 获取CPU核数module.exports {module: {rules: [{test: /\.js$/,include: path.resolve(src),use: [{loader: thread-loader,options: {works: threads }},{loader: babel-loader }],},],},plugins: [new ESlintPlugin([context: path.resolve(__dirname, ./src),exclude: /node_modules/, // 默认值cache: true, // 开启缓存cacheLocation: path.resolve(__dirname, ./node_modules/.cache/eslintcache), // 定义缓存位置threads, // 开启多进程和设置数量]),new TerserPlugin({ // 代码压缩parallel: threads //开启多进程和设置数量})],// 压缩插件 第二种写法optimization: {minimizer: [new CssMinimizerPlugin(), // css文件压缩new TerserPlugin({ // js代码压缩parallel: threads //开启多进程和设置数量})]}
};减小代码体积
1. Tree Shaking
当我们编写了很多工具函数或者引入了第三方库可能在实际开发中只应用了其中一部分那么在打包时这些未用到的代码就无须进行打包。Tree Shaking就帮我们做了这件事情。它可以移除JS上下文中的死代码且其语法依赖于ESM不支持CommonJS。 在Webpack中已经默认开启了此配置所以开发者无需再进行配置。
2. babel/plugin-transform-runtime
此插件可以对babel进行处理让辅助代码单独生成到一个文件中引入到编译后的文件中而不是每个文件都生成辅助代码从而减小打包后的体积。
npm i babel/plugin-transform-runtime -D// webpack.config.jsmodule.exports {module: {rules: [{test: /.\.js$/,// 排除node_modules下的文件 不作处理exclude: /node_modules/,loader: babel-loader,options: {cacheDirectory: true, // 开启babel缓存cacheCompression: false, // 关闭缓存文件压缩plugins: [babel/plugin-transform-runtime] // 减小代码体积}},]}
}3. Image Minimizer 图片压缩
当项目中使用了很多本地图片那么可以对图片进行压缩减小图片体积从而加快请求速度。如果项目中使用的是在线链接的图片那么就不需要进行配置了。
npm i image-minimizer-webpack-plugin imagemin -D安装完上面两个依赖包之后还需要下载另外两种压缩方式的包读者选择性下载。 一是无损压缩
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo --save-dev二是有损压缩
npm install imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant imagemin-svgo --save-dev// webpack.config.js
const ImageMinimizerPlugin require(image-minimizer-webpack-plugin);
const { extendDefaultPlugins } require(svgo);module.exports {module: {rules: [{test: /\.(jpe?g|png|gif|svg)$/i,type: asset,},],},plugins: [new ImageMinimizerPlugin({minimizerOptions: {plugins: [[gifsicle, { interlaced: true }],[jpegtran, { progressive: true }],[optipng, { optimizationLevel: 5 }],[svgo,{plugins: extendDefaultPlugins([{name: removeViewBox,active: false,},{name: addAttributesToSVGElement,params: {attributes: [{ xmlns: http://www.w3.org/2000/svg }],},},]),},],],},}),]
}优化代码性能
1. Code Split 代码分割
在进行打包时会将所有的js文件打包到一个文件中导致体积太大加载速度慢。当使用了代码分割之后生成多个js文件渲染哪个页面就加载哪个js文件这样就会减少资源的加载速度就更快从而提升性能。
使用 一、多入口、多输出
module.exports {entry: { // 多个入口文件打包时就会产生多个输出文件main: ./main.js,app: ./src/app.js},optimization: {splitChunks: { // 代码分割配置chunks: all, // 对所有模块都进行分割minSize: 20000, // 生成chunk的最小体积以bytes为单位minRemainingSize: 0, // 类似minSize最后确保提取的文件大小不能为0minChunks: 1, // 至少被引用的次数满足条件才会代码分割maxAsyncRequests: 30, // 按需加载时并行加载文件的最大数量maxInitialRequests: 30, // 入口js文件最大并行请求数量enforceSizeThreshold: 50000, // 超过50KB一定会单独打包此时会忽略minRemainingSize、maxAsyncRequests、maxInitialRequestscacheGroups: { // 组指哪些模块要打包到一个组defaultVendors: { // 组名test: /[\\/]node_modules[\\/]/, // 需要打包到一起的模块priority: -10, // 权重数值越大权重越高reuseExistingChunk: true, // 如果当前chunk包含已从主bundle中拆分出的模块则它将被重用而不是生成新的模块},default: { // 默认属性没有就会使用上面的配置此配置会覆盖上面的配置minChunks: 2,priority: -20,reuseExistingChunk: true,},},}}
}二、单入口多输出
module.exports {entry: ./main.js,optimization: {splitChunks: {chunks: all}}
}2. Preload / Prefetch 预加载 预获取
preload使浏览器立即加载资源prefetch等待浏览器空闲时开始加载资源。它们只会加载资源并不执行且都有缓存。Preload加载优先级要高于Prefetch。
npm install --save-dev vue/preload-webpack-pluginconst PreloadWebpackPlugin require(vue/preload-webpack-plugin);module.exports {plugins: [new PreloadWebpackPlugin({rel: preload, // 预加载的relas: script, // 预加载的资源类型include: allChunks // 预加载的文件范围 // 或者使用 prefetchrel: prefetch})]
}3. Network Cache
对输出资源的文件更好的命名可以做好缓存提升性能。只对修改的文件打包之后改动文件名其它文件不因引入改动的文件而改动文件名可以更好的做到缓存。
module.exports {optimization: {runtimeChunk: {name: entrypoint runtime~${entrypoint.name}.js}}
}4. Core-js 解决兼容性
例如一些ES6的新语法babel无法处理例如async函数、promise对象、数组的一些方法等等。所以可以使用core-js专门处理ES6及以上的语法。更好的适配老款浏览器的兼容性。
npm i core-js安装好之后在主入口引入即可
import core-js5. PWA 渐进式网络应用程序(progressive web application - PWA)
当网络断开时就无法访问Web应用了。为了提供离线访问效果我们可以引入PWA内部是通过Service Works技术实现的。可以将所有资源缓存到ServiceWork中当离线时依旧可以访问。
npm install workbox-webpack-plugin --save-devconst WorkboxPlugin require(workbox-webpack-plugin);module.exports {entry: {app: ./src/index.js,print: ./src/print.js,},plugins: [new HtmlWebpackPlugin({title: Output Management,title: Progressive Web Application,}),new WorkboxPlugin.GenerateSW({// 这些选项帮助快速启用 ServiceWorkers// 不允许遗留任何“旧的” ServiceWorkersclientsClaim: true,skipWaiting: true,}),],output: {filename: [name].bundle.js,path: path.resolve(__dirname, dist),clean: true,},};最后需要在主入口文件中注册Service Worker才能生效
main.js if (serviceWorker in navigator) {window.addEventListener(load, () {navigator.serviceWorker.register(/service-worker.js).then(registration {console.log(SW registered: , registration);}).catch(registrationError {console.log(SW registration failed: , registrationError);});});}