@ozo/lazy-loader
lazy loader for React
npm install @ozo/lazy-loader
该库可用于动态加载 React 组件或其他工具库。
lazy (function, spinner)
React.lazy 的具体用法:https://reactjs.org/docs/code-splitting.html#reactlazy
可以延迟加载指定库,当库加载完后需要通过 render props called 或 ref 来取值。
const Moment = lazyLib(() => import("moment"));
function FromNow({ date }) {
return (
<Suspense fallback={<div>loading</div>}>
<Moment fallback={date.toLocaleDateString()}>
{({ default: moment }) => moment(date).fromNow()}
</Moment>
</Suspense>
);
}
<FromNow date={new Date()} />;
@loadable/component 支持服务端渲染,具体用法请参考:https://www.smooth-code.com/open-source/loadable-components/
https://www.smooth-code.com/open-source/loadable-components/docs/loadable-vs-react-lazy/
Magic Comments:https://webpack.js.org/api/module-methods/#magic-comments
利用 loadable 进一步封装生成 AsyncLoad 组件,通过组件方式加载,可以避免繁琐的变量定义。适合在项目本地封装使用,例如路由统一配置表中(统一引入路径),注意使用场景及组件的路径匹配。
// ./src/App.js
import { loadable } from "@ozo/lazy-loader";
// 动态加载组件的组件,支持自定义加载动画
const AsyncLoad = loadable(({ path }) => import(path));
function MyComponent() {
return (
<div>
<AsyncLoad path="./Home" />
<AsyncLoad path="./Contact" />
</div>
);
}
import()中的相对路径相对于 import 语句所在的文件,无法通过工具包进一步封装。
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import styled from 'styled-components';
import { lazy, lazyX, loadable, loadableDelay, loadableTimeout } from '@ozo/lazy-loader';
import Loader from 'react-loader-spinner';
import 'react-loader-spinner/dist/loader/css/react-spinner-loader.css';
import NormalLoad from './Demo.jsx';
const LazyLoad = lazy(() => import('./Demo'), { pastDelay: 0 });
const LazyXLoad = lazyX(() => import('./Demo'));
/**
* 动态加载组件的组件,支持自定义加载动画
*/
const AsyncLoad = loadable(() => import('./Demo'));
const PreLoad = loadable(() => import('./Demo'));
const DelayLoad = loadableDelay(import('./Demo'), {
delay: 3000,
spinner: <Loader type="Triangle" color="#666" height={50} width={50} />,
});
const TimeoutLoad = loadableTimeout(import('./Demo'), { timeout: 5 });
async function randomString(len) {
len = len || 16;
// 默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1
var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
var maxPos = $chars.length;
var pwd = '';
for (let i = 0; i < len; i++) {
pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
}
const Section = styled.div`
overflow: hidden;
`;
class App extends Component {
state = {
list: [],
}
componentDidMount(){
const list = await randomString(480000).split('');
setTimeout(()=>{
this.setState({list: list});
}, 0);
}
render() {
const { list } = this.state;
PreLoad.preload();
return (
<>
<Section>
<h3>使用loadable预加载</h3>
<AsyncLoad list={list} />
</Section>
</>
);
}
}
ReactDOM.render(<App />, mountNode);