vue、webpack打包优化

webpack默认打包把所有的资源都放在chunk-vendors.js,导致文件很大,从而让页面的响应很慢

1 使用compression-webpack-plugin,打包生成gzip静态资源压缩文件,结合服务端Nginx的配置,服务器启用gzip;

1.1 安装compression-webpack-plugin插件

bash 复制代码
npm install compression-webpack-plugin --save-dev

1.2 修改vue.config.js

复制代码
const CompressionWebpackPlugin = require('compression-webpack-plugin')
module.exports = {

 configureWebpack: {
    plugins: [
      // gzip
      new CompressionWebpackPlugin({
        filename: '[path].gz[query]',
        algorithm: 'gzip',
        test: new RegExp('\\.(' + ['js', 'css'].join('|') + ')$'),
        threshold: 10240,
        minRatio: 0.8,
        deleteOriginalAssets: false
      })
    ],
    resolve: {
      alias: {
        '@': resolve('src')
      }
    }
  },

}

1.3 修改nginx的配置

复制代码
http {

sendfile        on;
    keepalive_timeout  65;
    
    #上传文件的大小
    client_max_body_size 200m;
    
    ##缓存cache参数配置##  
    proxy_connect_timeout 60;  
    proxy_read_timeout 60;  
    proxy_send_timeout 60;  
    proxy_buffer_size 16k;  
    proxy_buffers 4 64k;  
    proxy_busy_buffers_size 128k;  
    proxy_temp_file_write_size 128k;  
    
    #缓存到nginx的本地目录  
    proxy_temp_path  /usr/local/nginx/temp/;  
    proxy_cache_path /usr/local/nginx/temp/cache_temp levels=1:2 keys_zone=my_cache:200m inactive=1d max_size=30g;
    # 开启缓存
    proxy_cache my_cache;
    ##压缩配置##
    gzip on; #开启或关闭gzip on off 
    gzip_static on;    
    gzip_disable "MSIE [1-6]\."; #IE1-6版本不支持gzip压缩
    gzip_min_length 10k; #gzip压缩最小文件大小,超出进行压缩(自行调节) 
    gzip_buffers 4 16k; #buffer 不用修改 
    gzip_comp_level 5; #压缩级别:1-10,数字越大压缩的越好,时间也越长 
    gzip_types text/plain text/css application/xml application/javascript text/javascript application/x-httpd-php application/json application/css image/jpeg image/gif image/png; # 压缩文件类型 
    gzip_vary on; #跟Squid等缓存服务有关,on的话会在Header里增加 "Vary: Accept-Encoding"
    gzip_http_version 1.0; #不设置的话,gzip不生效
    # 限流策略,可在一定程度上防止ddos攻击
    # ip限流策略
    limit_req_zone $binary_remote_addr zone=iplimit:10m rate=50r/s;
    # cookies中access_token值限流策略
    limit_req_zone $COOKIE_access_token zone=cookielimit:10m rate=50r/s;
    # header中Authorization值限流策略
    limit_req_zone $http_Authorization zone=headerlimit:10m rate=50r/s;
    # url中access_token参数值限流策略
    limit_req_zone $arg_access_token zone=paramlimit:10m rate=50r/s;
}

2 拆分chunk-vendors.js文件

2.1 拆解方式一

指定模块进行单独打包,不进行大小拆分

复制代码
module.exports = {
 css: { extract: false, sourceMap: false },  //  开发环境跟生成环境样式不一致时配置
  chainWebpack: config => {
    if (process.env.NODE_ENV !== 'development') {
      // 移除 prefetch 插件
      config.plugins.delete('prefetch')
      // 移除 preload 插件
      config.plugins.delete('preload')
      config.optimization.splitChunks({
        maxInitialRequests: 8, // 每个入口和它的同步依赖最多能被拆分的数量
        cacheGroups: {
          elementUI: {
            name: 'chunk-elementUI', // split elementUI into a single package
            priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
            test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
            chunks: 'all',
            reuseExistingChunk: true,
            enforce: true
          },
          Components: {
            name: 'chunk-components', // 这里name与pages中chunks里的名字对应
            test: /[\\/]node_modules[\\/](components)[\\/]/,
            chunks: 'all',
            priority: 14,
            reuseExistingChunk: true
          },
          base: {
            name: 'chunk-base', // 这里name与pages中chunks里的名字对应
            test: /[\\/]node_modules[\\/](base)[\\/]/,
            chunks: 'all',
            priority: 15,
            reuseExistingChunk: true,
            enforce: true
          }
        }
      })
    }
}

2.2 拆解方式二

直接根据模块名称正则配置拆分,并指定文件大小

复制代码
// 开启分离js
config.optimization = {
    runtimeChunk: 'single',
    splitChunks: {
        chunks: 'all',
        maxInitialRequests: Infinity,
        minSize: 20000, // 依赖包超过20000bit将被单独打包
        cacheGroups: {
            vendor: {
                test: /[\\/]node_modules[\\/]/,
                name(module) {
                    // get the name. E.g. node_modules/packageName/not/this/part.js
                    // or node_modules/packageName
                    const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
                    // npm package names are URL-safe, but some servers don't like @ symbols
                    return `npm.${packageName.replace('@', '')}`
                }
            }
        }
    }
};

2.3 上述拆分后,需要在chunks配置上对应的模块名,不然会导致页面空白

以方式一为例

复制代码
const glob = require('glob')
glob.sync('./src/modules/**/main.js').forEach(path => {
  const pageName = path.split('./src/modules/')[1].split('/main.js')[0]
  pages[pageName] = {
    entry: path, // page 的入口
    filename: pageName + '.html', // 在 dist/xxxx.html 的输出
    // If doesn't exist, fallback to 'public/index.html'
    template: pageName + '.html', // 模板来源
    // 提取出来的通用 chunk 和 vendor chunk。
    chunks: ['chunk-vendors', 'chunk-common', 'chunk-elementUI', 'chunk-base', 'chunk-components', pageName]
  }
})
相关推荐
wordbaby2 分钟前
TanStack Router 基于文件的路由
前端
wordbaby7 分钟前
TanStack Router 路由概念
前端
wordbaby9 分钟前
TanStack Router 路由匹配
前端
cc蒲公英10 分钟前
vue nextTick和setTimeout区别
前端·javascript·vue.js
程序员刘禹锡15 分钟前
Html中常用的块标签!!!12.16日
前端·html
我血条子呢25 分钟前
【CSS】类似渐变色弯曲border
前端·css
DanyHope26 分钟前
LeetCode 两数之和:从 O (n²) 到 O (n),空间换时间的经典实践
前端·javascript·算法·leetcode·职场和发展
hgz071027 分钟前
企业级多项目部署与Tomcat运维实战
前端·firefox
用户18878710698427 分钟前
基于vant3的搜索选择组件
前端
zhoumeina9927 分钟前
懒加载图片
前端·javascript·vue.js