0

0

0

修罗

站点介绍

只有了解事实才能获得真正的自由

webpack 优化配置

修罗 2020-08-02 1817 0条评论 前端资源构建 webpack

首页 / 正文

webpack性能优化

  • 开发环境性能优化
  • 生产环境性能优化

开发环境性能优化

  • 优化打包构建速度

    • HMR
  • 优化代码调试

    • source-map

生产环境性能优化

  • 优化打包构建速度

    • oneOf
    • babel缓存
    • 多进程打包
    • externals
    • dll
  • 优化代码运行的性能

    • 缓存(hash-chunkhash-contenthash)
    • tree shaking
    • code split
    • 懒加载/预加载
    • pwa

第 5 章:webpack 优化配置

5.1 HMR

HMR: hot module replacement 热模块替换 / 模块热替换
作用:一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块) 极大提升构建速度

样式文件:可以使用HMR功能:因为style-loader内部实现了~

js文件:默认不能使用HMR功能 --> 需要修改js代码,添加支持HMR功能的代码
注意:HMR功能对js的处理,只能处理非入口js文件的其他文件。

html文件: 默认不能使用HMR功能.同时会导致问题:html文件不能热更新了~ (不用做HMR功能)解决:修改entry入口,将html文件引入

开启HMR功能

hot: true

webpack.config.js

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: ['./src/js/index.js', './src/index.html'],
  output: {
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      // loader的配置
      {
        // 处理less资源
        test: /\.less$/,
        use: ['style-loader', 'css-loader', 'less-loader']
      },
      {
        // 处理css资源
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        // 处理图片资源
        test: /\.(jpg|png|gif)$/,
        loader: 'url-loader',
        options: {
          limit: 8 * 1024,
          name: '[hash:10].[ext]',
          // 关闭es6模块化
          esModule: false,
          outputPath: 'imgs'
        }
      },
      {
        // 处理html中img资源
        test: /\.html$/,
        loader: 'html-loader'
      },
      {
        // 处理其他资源
        exclude: /\.(html|js|css|less|jpg|png|gif)/,
        loader: 'file-loader',
        options: {
          name: '[hash:10].[ext]',
          outputPath: 'media'
        }
      }
    ]
  },
  plugins: [
    // plugins的配置
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  mode: 'development',
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true,
    port: 3000,
    open: true,
    // 开启HMR功能
    // 当修改了webpack配置,新配置要想生效,必须重新webpack服务
    hot: true
  }
};

js支持hmr

if (module.hot) {
  // 一旦 module.hot 为true,说明开启了HMR功能。 --> 让HMR功能代码生效
  module.hot.accept('./print.js', function() {
    // 方法会监听 print.js 文件的变化,一旦发生变化,其他模块不会重新打包构建。
    // 会执行后面的回调函数
    print();
  });
}

1596708872256.png

1596709124890.png

5.2 source-map

source-map:

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

[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map

使用:在配置文件加入(配置的一次层对象属性)

devtool: 'eval-source-map'

内联 和 外部的区别:1. 外部生成了文件,内联没有 2. 内联构建速度更快

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加入

开发环境:速度快,调试更友好
速度快(eval>inline>cheap>...)

eval-cheap-souce-map
eval-source-map

调试更友好

souce-map
cheap-module-souce-map
cheap-souce-map

--> eval-source-map / eval-cheap-module-souce-map

生产环境:源代码要不要隐藏? 调试要不要更友好
内联会让代码体积变大,所以在生产环境不用内联
nosources-source-map 全部隐藏
hidden-source-map 只隐藏源代码,会提示构建后代码错误信息

--> source-map / cheap-module-souce-map

5.3 oneOf

oneOf:loader 只会匹配一个

1596712339968.png

5.4 缓存

babel缓存 --> 让第二次打包构建速度更快

cacheDirectory: true

1596714352131.png

文件资源缓存

hash: 每次wepack构建时会生成一个唯一的hash值。([hash:10]拿hash值前十位)
问题: 因为js和css同时使用一个hash值。
如果重新打包,会导致所有缓存失效。(可能我却只改动一个文件)

chunkhash(根据入口文件引入的资源(依赖)都会生成一个chunk):

根据chunk生成的hash值。如果打包来源于同一个chunk,那么hash值就一样
问题: js和css的hash值还是一样的
因为css是在js中被引入的,所以同属于一个chunk

contenthash: 根据文件的内容生成hash值。不同文件hash值一定不一样
--> 让代码上线运行缓存更好使用

出口文件

1596714527404.png

css文件

1596714566792.png

图片文件

1596714599824.png

5.5 tree shaking

摇掉树上死掉的叶子(没用到的代码)

tree shaking:去除无用代码

前提:1. 必须使用ES6模块化  2. 开启production环境
作用: 减少代码体积

1596721808586.png

在package.json中配置
"sideEffects": false: 所有代码都没有副作用(都可以进行tree shaking)
问题:可能会把css / @babel/polyfill (副作用)文件干掉,因为直接引入没有使用
"sideEffects": [".css", ".less"]

5.6 code split

可以将一个文件分隔为多个文件,按需加载(js)

1、

1596724739983.png

构建

1596724833021.png

2、splitChunks可以将node_modules中代码单独打包一个chunk最终输出

​ 多入口还会自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk

(js1中加载了jQuery,js2中也加载了jQuery,没有配置splitChunks会加载两次,打包出来的两个js文件都很大。把jQuery整成单独一个文件)

1596725016795.png

3、

通过js代码,让某个文件被单独打包成一个chunk

import动态导入语法:能将某个文件单独打包(这里打包当前目录下text.js)

1596725556875.png

加入保证node_modules单独打包一个chunk

1596725671665.png

5.7 lazy loading

懒加载:当文件需要使用时才加载

1596723993760.png

预加载 prefetch:会在使用之前,提前加载js文件

正常加载可以认为是并行加载(同一时间加载多个文件)

预加载 prefetch:等其他资源加载完毕,浏览器空闲了,再偷偷加载资源

1596724036394.png

5.8 pwa

PWA: 渐进式网络开发应用程序(离线可访问)

workbox --> workbox-webpack-plugin

npm install --save-dev workbox-webpack-plugin

插件中配置

new WorkboxWebpackPlugin.GenerateSW({
/*
  1. 帮助serviceworker快速启动
  2. 删除旧的 serviceworker

  生成一个 serviceworker 配置文件~
*/
    clientsClaim: true,
    skipWaiting: true
})

index.js写如下代码

/*
  1. eslint不认识 window、navigator全局变量
    解决:需要修改package.json中eslintConfig配置
      "env": {
        "browser": true // 支持浏览器端全局变量
      }
   2. sw代码必须运行在服务器上
      --> nodejs
      -->
        npm i serve -g
        serve -s build 启动服务器,将build目录下所有资源作为静态资源暴露出去
*/
// 注册serviceWorker
// 处理兼容性问题
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker
      .register('/service-worker.js')
      .then(() => {
        console.log('sw注册成功了~');
      })
      .catch(() => {
        console.log('sw注册失败了~');
      });
  });
}

eslint配置

1596727715786.png
安装服务器

npm i serve -g

运行服务器

1596728159578.png
没有网也能加载,搜狗浏览器不支持

1596728053478.png

5.9 多进程打包

进程启动大概为600ms,进程通信也有开销。

只有工作消耗时间比较长,才需要多进程打包

1596728676016.png

5.10 externals

场景:有些包通过CDN引入

1596728895265.png

5.11 dll

动态连接库。

使用dll技术,对某些库(第三方库:jquery、react、vue...)进行单独打包

当你运行 webpack 时,默认查找 webpack.config.js 配置文件

需求:需要运行 webpack.dll.js 文件

webpack --config webpack.dll.js

webpack.dll.js

const { resolve } = require('path');
const webpack = require('webpack');

module.exports = {
  entry: {
    // 最终打包生成的[name] --> jquery
    // ['jquery'] --> 要打包的库是jquery
    jquery: ['jquery'],
  },
  output: {
    filename: '[name].js',
    path: resolve(__dirname, 'dll'),
    library: '[name]_[hash]' // 打包的库里面向外暴露出去的内容叫什么名字
  },
  plugins: [
    // 打包生成一个 manifest.json --> 提供和jquery映射
    new webpack.DllPlugin({
      name: '[name]_[hash]', // 映射库的暴露的内容名称
      path: resolve(__dirname, 'dll/manifest.json') // 输出文件路径
    })
  ],
  mode: 'production'
};

1596753628877.png

安装库

yarn add add-asset-html-webpack-plugin -D

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: 'built.js',
    path: resolve(__dirname, 'build')
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    // 告诉webpack哪些库不参与打包,同时使用时的名称也得变~
    new webpack.DllReferencePlugin({
      manifest: resolve(__dirname, 'dll/manifest.json')
    }),
    // 将某个文件打包输出去,并在html中自动引入该资源
    new AddAssetHtmlWebpackPlugin({
      filepath: resolve(__dirname, 'dll/jquery.js')
    })
  ],
  mode: 'production'
};

这样打包自动引入

1596754171280.png

这样不会打包出来

1596754345165.png

评论(0)


最新评论

  • https://www.studyglobus.com/author/carroll34a5552/

    Ценники на вывоз мусора сейчас космос, любые лайфхаки по экономии в тему.

  • Richardgrold

    1xbet onlayn kazino platforması ilə vaxtınızı daha səmərəli və maraqlı keçirin. Saytın canlı kazino bölməsi istifadəçilərə fərqli bir dünya təklif edir. Burada canlı dilerli kazino oyunlarının hər bir növünü sınaqdan keçirə bilərsiniz. Krupyelərin peşəkarlığı oyunun dinamikasını və marağını artırır. Müntəzəm olaraq yenilənən oyun siyahısı cansıxıcılığa yol vermir. Hesabınızı artırmaq üçün onlarla fərqli və etibarlı üsul mövcuddur. Qazanılan pullar cəmi bir neçə dəqiqə ərzində şəxsi hesabınıza köçürülür. Aktiv fəaliyyətinizə görə fərdi bonuslar və hədiyyələr qazana bilərsiniz. Dəstək xidməti həm çat, həm də e-poçt vasitəsilə kömək göstərir. 1xbet ailəsinə qoşulun və böyük uduşlar üçün ilk addımı atın. onlayn kazino

  • 砂岩白丘

    我一直梦想, 看到你们相册那样的地方。真棒。

  • 城市地標

    我喜欢, 这里分享真实经验。你的项目 就是 属于这里的。请继续。

  • 宗教地標

    我热爱这样的想法, 去那么多国家。真的很鼓舞。

  • 觀景高地

    能感受到热爱。继续保持 感受。

  • 最佳季節

    我关注这样的资源, 写得很实在。你的网站 就是 属于这里的。加油。

  • 1

    1

  • 1

    1

  • -1' OR 2+158-158-1=0+0+0+1 or 'TKCTZnRa'='

    1

日历

2026年07月

   1234
567891011
12131415161718
19202122232425
262728293031 

文章目录

推荐关键字: Linux webpack js 算法 MongoDB laravel JAVA jquery javase redis