随着项目功能的扩充, 版本迭代, 我们与 webpack 捆绑起来的的项目越来越大, 大到开始影响加载速度了. 这时我们就该考虑如何对代码进行拆分了.
这次我们一起学习一下如何对 React 项目中的代码进行 Code-Splitting(代码分割, 代码拆分等各种叫法.....).
Code-Splitting 的思路有很多, 很多人选择的拆分方案是根据不同的路由进行拆分开来实现组件按需加载. 存在的弊端就是这样只是根据顶级路由的区别实现了代码的拆分.
而在 react 官方文档中的 "高级指引" 部分有提到一个库 - React Loadable. 对于 React Loadable 的介绍用一句话就可以说明, route-centric code splitting is shit, component-centric splitting is cool as shit.(自行体会吧 233333).
那么让我们进入正题, 说到基于路由拆分和基于组件拆分, Git 库的 readme 中给出了图解:
可以很直观的看出来, 根据路由拆分代码的时候还有很多可以细分的地方, 比如某一条路由下包含的某些需要特定操作才展现的 ui 组件, 这种组件没有必要在父路由加载的时候就跟着加载.
Loadable 的本质是一个高阶组件, 他可以很容易的以 react 的组件为中心对代码进行分割. 那么如何使用 React Loadable 呢?
借用官方的例子, 我们分为 3 步进行了解, 假设我们有两个组件, 组件 MyComponent 引入并渲染组件 Bar, 常规操作如下:
下面做一下升华, 当 MyComponent 需要渲染 Bar 的时候再渲染它:
这其实就已经开始复杂了, 而且仔细一推敲, 好多场景都没有考虑到, 比如 import 失败的时候, 需要做服务端渲染的时候.
这时, 就可以拿出我们的 Loadable 来帮助我们解决这一难题了:
这样代码清晰明了, 需要考虑的场景 loadable 已经帮我们完成了.
Tip: 当我们使用 import()配合 webpack2 + 的时候, 将会自动进行代码分割, 无需额外的配置. 这就意味着当 import(),webpack2 + 和 React Loadable 在一起玩的时候, 我们只需要尽可能的考虑到代码的拆分点即可.
和常规的拆分操作对比之后, 我们来看一下 Loadable 为我们提供了哪些 API:
Loadable:
在渲染模块之前首先渲染它, 他将返回一 LoadableComponent(后面讲到):
Loadable.Map:
允许您并行加载多个资源的高阶组件, 其中 loader 选项接收一个函数对象, 并且需要一个 render 方法:
Loadable 和 Loadable.Map 的接收的参数:
.loader 传入需要加载的组件
.loading 加载中或加载失败时展示的内容, 这个选项为必填项, 如果什么都不想展示则传入 null
.delay 组件展示的延迟时间, 此选项将传递给组件参数 props.pastDelay, 默认为 200(单位毫秒)
.timeout 组件加载的等待时间, 此选项将传递给组件参数 props.timeOut, 默认关闭.
.render 自定义已加载模块的呈现的函数, 它接受两个参数: 选项 loader 接收的对象和 props.
.webpack 选填, 可以将组件变成 "弱" 依赖 (不会将 module 引入到 bundle) 中, 当使用 babel 的时候自动执行.
.modules 选填, 由要导入模块的可选路径组成的数组.
LoadableComponent:
这是通过 Loadable 或 Loadable.map 返回的组件.
LoadableComponent.preload():
用于提前加载(预加载)LoadableComponent, 下面假设有一个组件, 点击按钮后展示, 当鼠标划入按钮上的时候就开始预加载:
LoadableComponent 可以接收的 props:
.error 加载失败, 值为 null 时代表加载成功, 使用案例:
.retry 重新加载(重试), 使用案例:
.timeOut 布尔值, 请求超时时传递给组件, 使用案例:
.postDelay 布尔值, 到达时间延迟后返回给组件, 使用案例:
以上参数汇总使用案例:
以上就是我为大家总结出的 React Loadable 的功能和用法.
总结一下 React Loadable 的原理是通过 import()返回的 promise 对象实现了异步的操作.
即便如此, 其实代码的拆分工作也不是那么简单, 我们要确保选择拆分的位置能够均匀地分割代码包而不会影响用户体验, 这也是一大难点. 反观本文开头给出的对比图片可以得到些许启发, 在基于路由拆分代码的基础上进行基于组件拆分是一个不错的起点.
最后大家可以在评论区探讨一些自己拆分代码的好的方案, 心得或者疑惑, 让我们一起探讨一下吧~
欢迎大家关注我们的公众号
Web 前端 Talk
来源: https://www.cnblogs.com/migufe/p/11091273.html