关于javascript:面试三板斧-代码分割下

42次阅读

共计 3643 个字符,预计需要花费 10 分钟才能阅读完成。

背景

本文接上篇:

上文中,咱们理解了 chunks 三个字段的含意,以及每个字段对应的行为。

明天是实际篇。

批改短短几行配置,就达到了数百毫秒的优化成果。

注释

我的这个我的项目,迭代一年多了,两头打包配置也没没怎么改过,毕竟也没什么问题,速度也还能够。

刚好最近老板要搞指标,让每个项目组剖析性能数据,给优化计划,做性能优化。

不剖析不晓得,一剖析,很快啊,马上就看出了问题, 看包剖析后果:

脑海里霎时闪过一张图:

简直所有的三方依赖都打在了一起,写好的页面按路由加载也都打到了一起, 几乎辣眼睛 …

于是就去看了一下代码配置:

修改前

原始配置:

const OnBoard = React.lazy(() => import('@/pages/onboard'));

const menuData = MenuItemTypes[] = [
  {
    title: 'onboard',
    path: '/onboard',
    meta: {showInMenu: false},
    children: [
      {
        component: OnBoard,
        // ...
      },
      // ...
    ]
  },
  // ...
];
const AppRouter = () => {
  // ...
  const {el, routes} = getRoutes(menuData);
  // ...
   
  return (<BasicLayout {...matchedRoute.meta}>
      <Suspense fallback={<Spin />}>
        <Route path="/" exact component={MyDashboard} />
        {el}
      </Suspense>
      // ...
    </BasicLayout>
  );
};
const App: React.FC<> = () => {
  // ...
  
  return <AppRouter />;
};

const AppContainer = () => (<Router history={history}>
    <Provider store={store}>
      <Locale>
        <App />
      </Locale>
    </Provider>
  </Router>
);

看起来没什么问题。

看了一下 webpack 配置:

  optimization: {
    splitChunks: {
      chunks: 'all',
      minSize: 30000,
      minChunks: 1,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      cacheGroups: {
        vendor: {test: /[\\/]node_modules/,
          enforce: true,
          priority: 5,
        },
        antd: {test: /[\\/]node_modules[\\/]antd[\\/]/,
          priority: 10,
        },
        antdIcons: {test: /[\\/]node_modules[\\/]@ant-design[\\/]/,
          priority: 15,
        },
        styles: {test: /\.(scss|css)$/,
          minChunks: 1,
          reuseExistingChunk: true,
          enforce: true,
          priority: 20,
        },
      },
    },
  },

看起来貌似也没什么问题。。。

build 之后 html 中的脚本,乍一看如同也没故障 …

<script type="text/javascript" src="/main.75a8d9f8.js"></script>
<script type="text/javascript" src="/chunk.styles~main.eaa8f358.js"></script>
<script type="text/javascript" src="/chunk.antdIcons~main.6ee35491.js"></script>
<script type="text/javascript" src="/chunk.vendor~main.aa82abbc.js"></script>
<script type="text/javascript" src="/chunk.main.db1b67a1.js"></script>

这种状况下,批改 chunks 配置的比照:

chunks: all

包剖析:

加载工夫以及入口文件初始加载的脚本文件:

chunks: async:

  <script type="text/javascript" src="/main.64245819.js"></script>
  <script type="text/javascript" src="/chunk.main.d6a

简直没有什么变动,一时间,开始狐疑是不是受了其余配置的影响,就去认真去找了一下,果然:

速度批改了配置。

修改后:

chunks:all

  optimization: {
    runtimeChunk: {name: 'manifest',},
    splitChunks: {
      chunks: 'all',
      minSize: 30000,
      minChunks: 1,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      cacheGroups: {
        vendor: {test: /[\\/]node_modules/,
          enforce: true,
          priority: 5,
        },
        antd: {test: /[\\/]node_modules[\\/]antd[\\/]/,
          priority: 15,
          enforce: true,
        },
        antdIcons: {test: /[\\/]node_modules[\\/]@ant-design[\\/]/,
          priority: 15,
          enforce: true,
        },
        antdV: {test: /[\\/]node_modules[\\/]@antv[\\/]/,
          priority: 30,
          enforce: true,
        },
        bizcharts: {test: /[\\/]node_modules[\\/]bizcharts[\\/]/,
          priority: 20,
          enforce: true,
        },
        dplayer: {test: /[\\/]node_modules[\\/]dplayer[\\/]/,
          priority: 25,
          enforce: true,
        },
        styles: {test: /\.(scss|css|less})$/,
          minChunks: 1,
          reuseExistingChunk: true,
          enforce: true,
          priority: 20,
        },
        'react-dom': {test: /[\\/]node_modules[\\/]react-dom[\\/]/,
          priority: 25,
          enforce: true,
        },
        'rc-components': {test: /([\\/]node_modules[\\/]rc-[a-zA-Z-]+[\\/])/,
          priority: 25,
          enforce: true,
        },
      },
    },
  },

很快啊,马上就有了变动:

chunks: async

入口文件初始加载的脚本:

  <script type="text/javascript" src="/main.572fc9fe.js"></script>
  <script type="text/javascript" src="/chunk.main.8c0dcc22.js"></script>

除了入口脚本数量的变动,总体积,加载时长,简直没有变动。

脚本数量的不同:

  • all: 8
  • async: 4

区别就是,大文件的体积不同,对这个大文件的加载工夫有影响。

回头看,这是一个 maxChunks 配置谬误引发的血案。

修改配置之后,空谷传声。


依据不同场景正当的拆分

依据你的状况,能够抉择更适宜的打包策略。

all 的劣势在于,能共享代码。

Providing all can be particularly powerful, because it means that chunks can be shared even between async and non-async chunks.

抉择这个模式,如果你用的协定是 h2, 并行下载,可能有比拟好的成果。

async 会帮你合并一些包,但产生的申请也会缩小。

须要依据理论状况做测试,抉择最适宜的打包策略。

还有一种宰割策略:

基于路由的宰割 vs 基于组件的宰割

打包的状况也会不同,比照如下两幅图:

和:

理论的场景中,不会严格的辨别这两种,能够一起用。

比方,个别状况下,一个页面就是一个模块,它的子页面,也是一个模块,而这两者是离开的。

也就是更贴近这个模型:

当然一些非凡的场景下,也能够对某些性能组件去宰割,比方播放器组件,代码块组件等。
这个时候的组件,会独自成包,应用的时候才去加载。

这是另一个话题了,也有很多细节在外面,本篇就不过多介绍。

总结

具体,还是要依据不同的场景,抉择不同的打包策略,来达到最有成果。

webpack 也提供了具体的文档:

https://webpack.docschina.org…

理论用到的时候能够去看看。

内容就这么多,心愿对大家有所启发。

谢谢。

正文完
 0