前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >入门webpack的最佳实践(基于webpack4.X 5.X)-- 运行体验优化

入门webpack的最佳实践(基于webpack4.X 5.X)-- 运行体验优化

作者头像
Jou
发布2022-09-28 14:11:41
1.2K0
发布2022-09-28 14:11:41
举报
文章被收录于专栏:前端技术归纳前端技术归纳

theme: channing-cyan

导语

来到这家公司之后,一直在使用webpack,也写了不少笔记,但是都比较零散,现在决定整理一下webpack相关的知识点,由浅入深,方便自己后续查漏补缺,后续会一直更新。

前言

本文将从几个方面,介绍webpack如何优化打包后的运行体验,所谓运行体验,就是用户在使用我们打包后的应用时,能够快速加载页面,渲染关键信息。

目录
  • splitChunks
  • 懒加载
  • prefetch 与 preload
  • css内联

splitChunks

当我们打包的模块比较大的时候,我们可以通过splitChunks来进行分包配置,从 webpack v4 开始,移除了 CommonsChunkPlugin,取而代之的是 optimization.splitChunks,先来看一下它的默认配置

module.exports = {
  //...
  optimization: {
    splitChunks: {
      chunks: 'async',
      minSize: 20000,//当导入的模块最小是多少字节才会进行代码分割
      minRemainingSize: 0,//解析见代码下面的文字说明,不用设置
      minChunks: 1,//当一个模块被导入(引用)至少多少次才对该模块进行代码分割
      maxAsyncRequests: 30,//按需加载时的最大并行请求数
      maxInitialRequests: 30,//入口点的最大并行请求数
      enforceSizeThreshold: 50000,//解析见代码下面的文字说明,不用设置
      cacheGroups: {//缓存组
        defaultVendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10,//优先级
          reuseExistingChunk: true,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },
  },
};

更多配置请参阅: https://webpack.docschina.org/plugins/split-chunks-plugin/

chunks
  • all模式下,入口文件和动态引入文件都会进行打包,作用最强大
  • initial 模式下,会将入口文件中的依赖包重新切割为一个新的文件,其它文件中动态引入的不会进行拆分
  • async(默认值)模式下,入口文件中的模块输出一个依赖包,对于动态加载的模块,默认配置会将该模块单独打包。
cacheGroups

cacheGroups是让我们自定义打包策略的地方,我们想抽取的各类公共模块,都再这个地方配置,存组可以继承和/或覆盖来自 splitChunks.* 的任何选项,比较常用的几个参数有

  • priority:优先级,只配置在缓存组的每一项,决定执行的顺序。
  • minChunks:最小块,即当块的数量大于等于minChunks时,才起作用
  • minSize:最小大小,即当抽取的公共模块的大小,大于minSize所设置的值,才起作用
  • maxSize:如果引入的包大小已经超过了设置的最大值,那么webpack会尝试对该包再进行分割
  • test:匹配规则,说明要匹配的项,这里是匹配匹配绝对模块资源路径或 chunk 名称
  • name: 打包之后的文件名,从 webpack 5 开始,不再允许将 entry 名称传递给 {cacheGroup}.test 或者为 {cacheGroup}.name 使用现有的 chunk 的名称。

比如,我们想在默认缓存组的基础上,抽离react的相关依赖,我们可以这样配置

cacheGroups: {
  // 配置提取模块的方案
  defaultVendors: {
    test: /[\/]node_modules[\/]/,
    priority: -10,
    reuseExistingChunk: true,
    name: 'vendors',
  },
  default: {
    minChunks: 2,
    priority: -20,
    reuseExistingChunk: true,
    name: 'default',
  },
  react: {
    test: /(react|react-dom)/, // 匹配chunk的名称
    name: 'react', //打包后的文件名
    chunks: 'all',
    priority: 13, // 优先级 越高则先处理
  },
},

在打包后,就会看到react的依赖包

图片.png
图片.png

懒加载

懒加载其实也叫动态加载,顾名思义,就是在项目中,不一开始就加载所有资源,而是在使用到的时候再进行加载,依赖于ES Module,比如说,

有一个asyncImportModule.js的文件,里面的方法返回一个新的组件

// 用于动态引入的module
console.log('console一下证明引入了文件');

const AsyncImportModule = () => {
  return <div class='module'>这是一个新的module</div>;
};
export default AsyncImportModule;

然后我们在页面中的方法动态引用它

onclick=() => {
  import('./base/asyncImportModule').then((res) => console.log(res));
}

通过splitchunks的配置,我们动态引用到的文件会打包成一个额外的包

图片.png
图片.png

在页面中运行时,一开始并不会加载这个js文件,只有当我们执行方法时才会加载这个js文件。

内联注释

通过在 import 中添加注释,我们可以进行诸如给 chunk 命名或选择不同模式的操作。比如,我们可以通过传入webpackChunkName来指定打包后的文件名

import(/* webpackChunkName: "changeModuleName" */'./base/asyncImportModule').then((res) => console.log(res));

更多配置请参阅: https://webpack.docschina.org/api/module-methods/#magic-comments

react中使用懒加载

react提供了React.lazySuspense 方法来实现懒加载以及代码分割

const Home = lazy(() => import(/* webpackChunkName: "home" */ './home/index'));

const SuspenseComponent = (Component: any) => (props: any) => (
    <Suspense fallback={Loading}>
      <Component {...props}></Component>
    </Suspense>
);

const App = () => {
return <div>
    {SuspenseComponent(Home)}
</div>
}

prefetch 与 preload

前面说到了我们可以动态的引入资源,但是如果需要异步加载的文件比较大时,在点击的时候去加载也会影响到我们的体验,这个时候我们就可以考虑使用 prefetch 来进行预拉取,使用preload进行预加载。

prefetch和preload也是通过内联注释进行配置

prefetch (预获取):浏览器空闲的时候进行资源的拉取

// 按需加载
img.addEventListener('click', () => {
  import( /* webpackPrefetch: true */ './desc').then(({ default: element }) => {
    console.log(element)
    document.body.appendChild(element)
  })
})

preload (预加载):提前加载后面会用到的关键资源,因为会提前拉取资源,如果不是特殊需要,谨慎使用

官网示例:

import(/* webpackPreload: true */ 'ChartingLibrary');

css内联

在打包时,我们可以将css通过style标签内联到页面中,这样做的好处是可以让页面样式更快的渲染出来,也能避免页面闪动,不过在webpack5已经放弃了这种方法。

使用postcss-loader实现

{
  loader: 'postcss-loader',
  options: {
    //将样式标签插入到header
    insertAt: 'top',
    //将所有style标签合成为一个
    singleton: true,
    plugins: () => [
      require('autoprefixer')({
        //配置浏览器版本
        browsers: ['Android 4.1', 'iOS 7.1', 'Chrome > 31', 'ff > 31', 'ie >= 8'],
      }),
    ],
  },
},

项目链接

https://github.com/AdolescentJou/webpack-base-demo

最后

感谢你能看到这里,本文总结了优化运行体验的几种配置,希望对你有所帮助,之后会陆续更新其他webpack相关的文章。

参考链接

https://webpack.docschina.org

https://juejin.cn/post/7023242274876162084#heading-52

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-08-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导语
    • 前言
      • 目录
    • splitChunks
      • chunks
      • cacheGroups
    • 懒加载
      • 内联注释
      • react中使用懒加载
    • prefetch 与 preload
      • css内联
        • 项目链接
        • 最后
          • 参考链接
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档