webpack 优化

resolve配置
resolve: {
  alias: {
    // 减少依赖包所在文件的查询时间
    react: path.resolve(__dirname, "../../node_modules/react/dist/react.min.js"),
     ...
  },
  // 与alias类似,减少文件查找时间
  modules:['./src/components'],
  // 减少文件查找类别
   extensions: ['.js', '.json']
}
DLL,预打包
// webpack.dll.js 单独预打包,并且生成json文件
// json文件中包含“./node_modules/react/cjs/react.production.min.js”:{ id: 3, ...... }
// 模块id等信息
  entry: {
    library: ["react",  "react-dom"]
  },
  output: {
    filename: "[name]_[hash].dll.js",  // library.dll.js
    path: path.join(process.cwd(), "dll/library"),
    library: '[name]', // window.react == react.js
  },
  plugins: [
    new webpack.DllPlugin({ // 生成对应的json文件
      name: "[name]",
      path: path.join(process.cwd(), "dll/library/[name].json"),
    })
  ]
// webpack.base.js 
// webpack.DllReferencePlugin根据之前打包的json文件进行引用
plugins: [
    new webpack.DllReferencePlugin({
       manifest: path.join(process.cwd(), "/dll/library/library.json")
    }),
]
缓存的使用
  • css cache缓存
      {
        test: /\.js$/,
        use: [
          'babel-loader?cacheDirectory=true', // 二次构建缓存开启提升40%
          'eslint-loader'
        ],
      },
  • plugins 模块缓存
const HardSourceWebpackPlugin = require("hard-source-webpack-plugin");
 [
new HardSourceWebpackPlugin({}) 
]
并发处理
  • js的并发处理loader,webpack之前happy-pack,webpack4自带thread-loader
      {
        test: /.js$/,
        use: [
          'thread-loader'
        ],
      },
  • css的并发处理plugin
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
    new MiniCssExtractPlugin({
      filename: "[name]_[contenthash:8].css",////都提到build目录下的css目录中
      chunkFilename: "[id][contenthash:8].css"
    }),
    new OptimizeCssAssetsPlugin({
      assetNameRegExp: /\.css$/g,
      cssProcessor: require("cssnano"), // css 并发处理器
    }),
splitChunks分包
  optimization: {
    splitChunks: {
      // async:require.ensure()/import.then()引入的库进行分离(默认),
      // initial: 同步引入的库进行分离,
      //  all:所有引入的库进行分离(推荐)
      chunks: 'all',
      minSize: 0, // 抽离的公共包最小的大小,单位字节
    maxSize: 0, // 最大的大小
    minChunks: 1, // 资源使用的次数(在多个页面使用到), 大于1, 最小使用次数
    maxAsyncRequests: 5, // 并发请求的数量
    maxInitialRequests: 3, // 入口文件做代码分割最多能分成3个js文件
    automaticNameDelimiter: '~', // 文件生成时的连接符
    automaticNameMaxLength: 30, // 自动自动命名最大长度
      name: true, //让cacheGroups里设置的名字有效
      cacheGroups: { //当打包同步代码时,上面的参数生效
        verder: {
          name: "verder",
          test: /[\\/]node_modules[\\/]/, //检测引入的库是否在node_modlues目录下的
          priority: -10, //值越大,优先级越高.模块先打包到优先级高的组里
          // filename: 'vendors.js'//把所有的库都打包到一个叫vendors.js的文件里
        },
        commonUtils: {
          name: "commonUtils",
          test: /[\\/]src[\\/]utils[\\/]/,
          priority: -9,
        },
      }
    },
    minimizer: [
      new TerserPlugin({
        parallel: true,
        cache: true,
      })
    ]
  },
缩减包的体积/其它
  • 动态兼容, polyfill-service,针对浏览器ua下发不同的polyfill文件
  • 图片的压缩算法的原理:tinyPng: 将24位png转化为更小索引的8位图片,去除非必要的matadata信息
  • devtool的选择:
    --------------使用————————————————
  • eval 定位webpack后的代码
  • cheap-eval-source-map 进过loader转化后的代码
  • cheap-module-eval-source-map 源代码只能看行
  • eval-source-map 源代码
  • cheap-source-map loader后无列信息源代码
  • cheap-module-source-map 后无列信息源代码
  • source-map 源代码
  • inline-source-map 源代码
  • hidden-source-map 源代码,注释的形式和原文件打包
    sourcemap的主要原理:
{
  version : 3,                          // 版本
  file: "out.js",                       // 转换后文件目录
  sourceRoot : "",                      // 转换前的文件所在的目录。如果与转换前的文件在同一目录,该项为空。
  sources: ["foo.js", "bar.js"],        // 转换前的文件。该项是一个数组,表示可能存在多个文件合并
  names: ["src", "maps", "are", "fun"], // 转换前的变量名称
  mappings: "AAgBC,SAAQ,CAAEA"          // 记录位置信息的字符窜
}
- 主要原理在于mapping是如何实现的
- 位置对应原理: 
  五位的字符长度(如上述mapping中: “AAgBC”)
  [“转换后的代码的第几列”,“哪个source文件”,“转换之前第几行”,“转换之后第几列”,“属于names中的哪个变量”]
- 每一位上采用的是VLQ编码
- VLQ编码流程: 
  “16”(变量) --> 
  "10000"(二进制) --> 
  "100000"(>0补0) --> 
  "00001"+"00000"(按5位分割) --> 
  "100000"+"00000"(反转)  --> 
  “gB”(进行base64编码)【得到“16”的最后编码结果】
按需加载

使用import().then()或者require().ensure()
react下的异步组件

import React, { lazy, Suspense } from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <OtherComponent />
    </Suspense>
  );
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260