为什么我重新写了一个 "react-lodable" ?
简单来说是为了通过配置 webpack 插件及少量业务代码即可实现Code Splitting
+ 组件懒加载
+ 预加载
。
虽然react
官方提供了一个 lazy
API用于 react 组件的Code Splitting(代码拆分)
及组件懒加载
const LazyComponent = React.lazy(() => import('./OtherComponent'))
但lazy
有一个局限就是必须放在<Suspense>
组件内。
import React, { Suspense } from 'react';
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
</div>
);
}
同时,由于懒加载的关系,组件资源加载存在异步耗时,会导致<LazyComponent />
在实际业务渲染中,存在较长的耗时,以至于组件渲染过程中出现闪烁
、体验卡顿
等情况,影响用户体验,虽然<Suspense>
有提供一个 fallback
属于用于组件等待过程中进行渲染,但是交互体验相对于不使用lazy
的情况下,体验是有变差的。
而react
社区提供的react-lodable 解决了以上两个问题:
- 不强依赖
react-lodable
,可独立渲染<LazyComponent />
- 提供了
preload
预加载方案,减少异步加载耗时,保证用户体验。
let LoadableMyComponent = Loadable(
() => import('./another-component'),
MyLoadingComponent,
);
class MyComponent extends React.Component {
state = { showComponent: false };
onClick = () => {
this.setState({ showComponent: true });
};
onMouseOver = () => {
LoadableMyComponent.preload();
};
render() {
return (
<div>
<button onClick={this.onClick} onMouseOver={this.onMouseOver}>
Show loadable component
</button>
{this.state.showComponent && <LoadableMyComponent/>}
</div>
)
}
}
但是有个问题是模块过多时,侵入式的代码也变多了
,同时被预加载的模块并没有进行统一管理
,后续维护也不会很方便,不直观
。
那么是不是可以在webpack plugin
层面对预加载的模块进行统一维护,同时减少了项目中的侵入式代码。
于是便有了 route-resource-preload, 其具备的特性:
拆分模块按需加载
,提升应用首屏加载体验.基于预加载缩短动态导入组件的加载时间
(可以看作是 suspense loading 组件持续时间)以提供最佳交互体验.- 支持[
自动预加载资源
],如hover、某组件渲染时、出现在视图内时。(JS / Component / Module-Federation / UMD / Svg / Png 等). - 支持
手动调用预加载
. - 支持
React <Suspense>
,但不依赖。 - 完备的
typescript
支持.
基于插件按模块对动态资源进行归类:
打包成JSON
自动预加载:
效果
资源 | 正常懒加载 - react.lazy (ms) | 预加载 (ms) |
---|---|---|
普通组件 (单个资源文件) | 184 | 1 |
Module-Federation 组件 (6个资源文件) | 405 | 8 |
体验地址:route-resource-preload.netlify.app/
希望本插件能为各位看客的业务赋能吧,鼓励使用,期待反馈~~~
转载自:https://juejin.cn/post/7260732188953952314