最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • webpakc性能优化

    正文概述 掘金(热心市民萝卜先生)   2021-02-18   408

    webpakc性能优化

    • 开发环境性能优化

      1、优化打包构建速度

      2、优化代码调试

    • 生产环境性能优化

      1、优化打包构建速度

      2、优化代码运行的性能

    一、HMR:hot modules replacement 热模块替换/模块热替换
    • ​ 作用:一个模块发生变化,只会重新打包这一个模块(而不是打包所有),提升构建速度
      • 样式文件:可以使用HMR功能,因为style-loader内部实现了

      • js文件:默认不能使用HMR功能,

      • html文件:默认不能使用HMR功能

        ​ 改变entry,[ './src/index.js','./src/index.html'],就可以开启HMR功能,html只有一个文件,每次重新打包会刷新

    devServer:{
    	contentBase:resolve(__dirname,'build'),
    	compress:true,
    	port:3000,
    	open:true
    	//开启HMR功能
    	hot:true
    }
    
    //新建print.js
    //修改index.js
    if(module.hot){
    	//必须开启HMR功能,才会执行到这个函数
       module.hot.accept('./print.js',function(){
           //监听print.js文件是否发生变化
           print();
       })
    }
    
    二、source-map:一种提供源代码到构建后代码映射技术
    devtool:'eval-source-map'
    

    source-map:一种提供源代码到构建后代码映射技术(如果构建后代码出错,通过映射可以追踪到源代码错误)

    值:[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
       source-map          		:外联
         //错误代码准确信息  和  源代码的错误位置(精确到列)
       inline-source-map   		:内联,只生成一个内联的source-map
         //错误代码准确信息  和  源代码的错误位置(精确到列)
       hidden-source-map   		:外联
         //错误代码准确信息  和  构建代码的错误位置(只有构建后的代码)
       eval-source-map 	   		:内联,每个文件都生成对应的source-map文件,都在eval
         //错误代码准确信息  和  源代码的错误位置(精确到列)
       nosources-source-map		:外联
         //错误代码准确信息  和  没有源代码信息
       cheap-source-map    		:外联
         //错误代码准确信息  和  源代码的错误位置(精确到行)
       cheap-module-source-map  :外联
         //错误代码准确信息  和  没有源代码信息,module会将loader的source-map加入
                                          
       内联和外联的区别:1.外部生成了文件,内联没有;2.内联构建速度更快
       
       开发环境:速度快,调试更友好 ----->eval-source-map/ eval-cheap-module-source-map
         速度快
           eval-cheap-source-map
           eval-source-map
         调试友好
           source-map
           cheap-module-source-map
           cheap-source-map
       生产环境:源代码要不要隐藏,调试要不要更友好----->source-map/cheap-module-source-map
         //内联会让代码体积变大,所以再生产环境下不用内联
         源代码要不要隐藏
           nosources-source-map  全部隐藏
           hidden-source-map  只隐藏源代码,会提示构建后代码错误信息
         调试要不要更友好
           source-map
    
    三、oneof,以下loader只会匹配一个
    //不能有2个配置处理同一类型的文件
    //这里匹配2个js,将一个js提出与oneof平级,enforce优先处理
    module: {
      rules: [
        {
            test: /\.js$/,
            exclude: /node-modules/,
            enforce: 'pre', //优先语法检查
            loader: 'eslint-loader',
            options: {
                fix: true
            }
        },
        {
          oneof: [
            {
              test: /\.css$/,
              use: [...commonCssLoader]
            },
            {
              test: /\.less$/,
              use: [...commonCssLoader, 'less-loader']
            },
            {
              test: /\.js$/,
              exclude: /node-modules/,
              loader: 'babel-loader'
            }
          ]
        }
      ]
    }
    
    四、cache缓存
    1. babel缓存

      优点:第二次打包的速度更快

      cacheDirectory:true

    2. 文件资源缓存

      优点:代码上线运行缓存更好使用

      1. hash:webpack每次构建会生成一个唯一的hash值

        问题:js和css的hash值还是一样,如果重新打包会导致所有的缓存失效(可能改变一个文件)

      2. chunkhash:根据chunk生成的hash值。如果打包来源同一个chunk,那么hash值就一样

        问题:js和css的hash值还是一样

      3. contenthash:根据文件的内容生成hash值。不同的文件hash值一定不一样

    //babel缓存
    {
        test:/\.js$/
        exclude:/node-modules/
        loader:'babel-loader'
        options:{
            parsets:[
                [
                    '@babel/parset-env'
                    {
                    	useBuiltIns:'usage'
                    	corejs:{version:3},
                		targets:{
                			chrome:'60',
                			firefox:'50'
                		}
                    }
                ]
            ],
            //开启babel缓存
            //第二次构建会读取之前的缓存
            cacheDirectory:true
        }
    }
    
    五、tree shaking:去除无用代码

    前提:1、使用ES6模块化。2、必须在production模式下。满足这2个条件自动开启

    作用:减少代码体积,构建速度更快。

    在package.json中配置

    "sideEffects":false 所有的代码都没有副作用(都能进行tree shaking)
    问题:可能会把   css  /  @babel/polyfill 文件干掉
    "sideEffects":["*.css","*.less"]
    
    六、code split:代码分割
    //生产环境配置
    const { resolve } = require("path");
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    
    module.exports = {
      //单入口
      //entry: './src/js/index.js',
      //多入口
      entry:{
        //有一个入口,最终输出就有一个bundle
        index:'./src/js/index.js',
        test:'./src/js/test.js'
      },
      output: {
        //[name]:取当前文件名
        filename: 'js/[name].[contenthash:10].js',
        path: resolve(__dirname, 'build')
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: './src/index.html',
          minify: {
            collapseInlineTagWhitespace: true,
            removeComments:true
          }
        })
      ],
      mode: 'production'
    }
    
    //生产环境配置
    const { resolve } = require("path");
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    
    module.exports = {
      //多入口
      entry:{
        index:'./src/js/index.js',
        test:'./src/js/test.js'
      },
      //如果2个js同时引入JQ,打包生成3个chunk
      output: {
        filename: 'js/[name].[contenthash:10].js',
        path: resolve(__dirname, 'build')
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: './src/index.html',
          minify: {
            collapseInlineTagWhitespace: true,
            removeComments:true
          }
        })
      ],
      //1.可以将node-modules中的代码单独打包成一个chunk最终输出
      //2.自动分析多入口chunk中,有没有公共的文件,如果有会单独打包成一个chunk
      optimization:{
          splitChunks:{
              chunks:'all'
          }
      },
      mode: 'production'
    }
    
    //生产环境配置
    const { resolve } = require("path");
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    
    module.exports = {
      entry:'./src/js/index.js'
      output: {
        filename: 'js/[name].[contenthash:10].js',
        path: resolve(__dirname, 'build')
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: './src/index.html',
          minify: {
            collapseInlineTagWhitespace: true,
            removeComments:true
          }
        })
      ],
      //可以将node-modules中的代码单独打包成一个chunk最终输出
      optimization:{
          splitChunks:{
              chunks:'all'
          }
      },
      mode: 'production'
    }
    
    //index.js
    /*
    	通过js代码,让某个文件被单独打包成一个chunk
    */
    /*webpackChunkName:'test'*/    设置文件名
    imoprt (/*webpackChunkName:'test'*/'./test').then(({mul,count})=>{
        //文件加载成功
        console.log(mul(2,3))
    }).catch(()=>{
        //文件加载失败
    })
    
    七、lazy loading:懒加载
    //懒加载:当文件需要使用时才加载
    //预加载 prefetch:会使用之前,提前加载js文件   webpackPrefetch:true
    //正常加载:并行加载(同一时间加载多个文件)
    imoprt(/* webpackChunkName:'test',webpackPrefetch:true*/ './test').then(({mul})=>{
        console.log(mul(2,3))
    })
    
    八、PWA:渐进式网络应用开发程序(离线可访问)
    //生产环境配置
    const { resolve } = require("path");
    const MiniCssExtractPlugin = require("mini-css-extract-plugin")
    const optimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    
    const workboxWebpackPlugin = require('workbox-webpack-plugin')
    
    //指定node环境变量
    //process.env.NODE_ENV = 'development'
    
    const commonCssLoader = [
      MiniCssExtractPlugin.loader,
      'css-loader',
      {
        //还需要在package.json中配置browserslist
        /*
          "browserslist": {
            "development": [
              "last 1 chrome version",
              "last 1 firefox version",
              "last 1 safari version"
            ], 
            "production": [
              ">0.2%",
              "no dead",
              "no op_mini all"
            ]
          },
        */
        loader: 'postcss-loader',
        options: {
          ident: 'postcss',
          plugins: () => [
            require('postcss-preset-env')()
          ]
        }
      }
    ]
    
    module.exports = {
      entry: './src/index.js',
      output: {
         filename: 'js/[name].[contenthash:10].js',
        path: resolve(__dirname, 'build')
      },
      module: {
        rules: [{
            test: /\.css$/,
            use: [...commonCssLoader]
          },
          {
            test: /\.less$/,
            use: [...commonCssLoader, 'less-loader']
          },
          {
            //需要在package.json中配置eslintConfig--->airbnb
            /*
              "eslintConfig": {
                "extends": "airbnb-base",
                "env":{
                	"browser":true
                }
              }
            */
            test: /\.js$/,
            exclude: /node-modules/,
            enforce: 'pre', //优先语法检查
            loader: 'eslint-loader',
            options: {
              fix: true
            }
          },
          {
            test: /\.js$/,
            exclude: /node-modules/,
            loader: 'babel-loader', //将高版本的js转为ES5
            options: {
              presets: [
                [
                  '@babel-loader',
                  {
                    useBuiltIns: 'usage',
                    corejs: {
                      version: 3
                    },
                    targets: {
                      chrome: '60',
                      firefox: '50'
                    }
                  }
                ]
              ]
            }
          },
          {
            test: /\.(jpg|png|gif)$/,
            loader: 'url-loader',
            options: {
              limit: 8 * 1024,
              esModule: false,
              name: '[hash:10],[ext]',
              outputPath: 'images'
            }
          },
          {
            test: /\.html$/,
            loader: 'html-loader'
          },
          {
            exclude: /\.(css|less|html|js|jpg|png|gif)$/,
            loader: 'file-loader',
            options: {
              name: '[hash:10],[ext]',
              outputPath: 'media'
            }
          }
        ]
      },
      plugins: [
        new MiniCssExtractPlugin({
          filename: 'css/bulit.css'
        }),
        new optimizeCssAssetsWebpackPlugin(),
        new HtmlWebpackPlugin({
          template: './src/index.html',
          minify: {
            collapseInlineTagWhitespace: true,
            removeComments:true
          }
        }),
        new workboxWebpackPlugin.GenerateSW({
        	/**
        	* 1.帮助serviceWorker快速启动
        	* 2.删除旧的serviceWorker
        	*
        	* 生成一个serviceworker文件
        	*/
            clientClaim:true,
            skipWaiting:true
        })
      ],
      mode: 'production',
      devtool:'source-map' 
    }
    
    //index.js
    
    /**
    * 1.eslint不认识window,navigtor等全局变量
    * 解决:需要在package.json中修改eslintConfig配置
    * "evn":{
    *   "browser":true
    * }
    * 2.必须在服务器上运行
    */
    
    //在入口文件中注册serviceWorker
    //处理兼容性问题
    if('serviceWorker' in navigator){
    	window.addEventListente('load',()=>{
    		navigator.serviceWorker.register('/service-worker.js').then(()=>{
    			console.log('serviceWorker注册成功')
    		}).catch(()=>{
    			console.log('serviceWorker注册失败')
    		})
    	})
    }
    
    九、多进程打包
    //thread-loader,开启多进程打包,启动大概600ms,只有工作消耗时间较长才会开启多进程打包
    //npm install thread-loader -D
    {
    	test:/\.js$/
    	exclude:/node-modules/,
    	use:[
    		{
    			//开启多进程打包
    			loader:'thread-loader',
    			options:{
    				workers:2,//开启两个进程
    			}
    		},
    		{
    			loader:'babel-loader',
    			options:{
    				presets: [
                    [
                      '@babel-loader',
                      {
                        useBuiltIns: 'usage',
                        corejs: {
                          version: 3
                        },
                        targets: {
                          chrome: '60',
                          firefox: '50'
                        }
                      }
                    ]
                  ]
    			}
    		}
    	]
    }
    
    十、externals防止将某些包打包输出到bundle里面,不需要打包,直接通过CDN引入
    const { resolve } = require('path')
    const htmlWebpackPlugin = require('html-webpack-plugin')
    
    module.exports={
    	entry:'./js/index.js',
    	output:{
    		filename:'./js/[name].[contenthash:10].js',
    		path:resolve(__dirname,'build')
    	},
    	plugins:[
    		new htmlWebpackPlugin({
    			template:'./src/index.html',
    			minfy:{
    				collapseInlineTagWhitespace: true,
            		removeComments:true
    			}
    		})
    	],
    	mode:'production',
    	externals:{
    		//拒绝jquery被打包进来
    		jquery:'jQuery'
    	}
    }
    
    十一、dll,将第三方库单独打包,直接引入
    //webpack.dll.js
    /* 使用dll技术,对第三方库(jQuery,vue,react...)单独打包 */
    
    const {resolve} = require('path')
    const webpack = require('webpack')
    
    module.export = {
    	entry:{
    		//打包生成得name,要打包得库
    		jquery:['jquery']
    	},
    	output:{
    		filename:'[name].js',
    		path:resolve(__dirname,'dll'),
    		library:'[name]_[hash:10]'//打包得库,向外暴露得内容名字
    	},
    	plugins:[
    		//打包生成一个manifest.json文件 ---》 提供jQuery得映射
    		new webpack.DllPlugin({
    			name:'[name]_[hash:10]',//映射库得暴露名称
    			path:resolve(__dirname,'dll/manifest.json')//输出文件得目录
    		})
    	],
    	mode:'production'
    }
    
    //webpack.config.js
    const { resolve } = require('path')
    const htmlWebpackPlugin = require('html-webpack-plugin')
    const webpack = require('webpack')
    const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin')
    
    module.exports={
    	entry:'./src/index.js',
    	output:{
    		filename:'js/[name].[contenthash:10].js',
    		path:resolve(__dirname,'build')
    	},
    	plugins:[
    		new htmlWebpackPlugin({
    			template:'./src/index.html',
    			minfy:{
    				collapseInlineTagWhitespace: true,
            		removeComments:true
    			}
    		}),
    		//告诉webpack那些库不打包,同时使用时得名称也在变
    		new webpack.DllReferencePlugin({
    			manifest:resolve(__dirname,'dll/manifest.json')
    		}),
            //将第三方库单独打包,并在html自动引入
            new AddAssetHtmlWebpackPlugin({
                filepath:resolve(__dirname,'dll/jquery.js')
            })
    	],
    	mode:'production'
    }
    

    性能优化总结

    一、webpack性能优化
    • 开发环境性能优化
    • 生产环境性能优化
    二、开发环境性能优化
    • 优化打包构建速度
      • HRM
    • 优化代码调试
      • source-map
        • 开发环境:eval-source-map || eval-cheap-module-source-map
        • 生产环境:source-map || cheap-module-source-map
    三、生产环境性能优化
    • 优化打包构建速度
      • oneOf
      • babel缓存
      • 多进程打包
      • externals,
      • dll
    • 优化代码运行得性能
      • 缓存(hash || chunkhash || contenthash)
      • thee shaking(1、使用ES6模块化。2、必须在production模式下。满足这2个条件自动开启。)
      • code split
      • lazy loading
      • pwa

    起源地下载网 » webpakc性能优化

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元