@route-resource-preload/react v1.0.0-beta.27
@route-resource-preload/react - Any react can be split
π Focus on improving the first screen loading speed of applications and providing the best user experience, inspiration comes from the preloading of NextJS.
δΈζζζ‘£
Comparison
As we can see from the gif, the display time of the loading component is greatly reduced by route-resource-preload relative to react.lazy.
Why do you need route-resource-preload ?
Split modules loads as needed, improving the first screen loading experience of your App.Minimize dynamic component loading timeand providing the best user experience.- Support
automatic the preloading of resources( JS / Component / Module-Federation / UMD / Svg / Png , Etc) and providing the best user experience. - Support
manually to preload. - Support
typescript. - Support
React <Suspense>.
Why route-resoure-preload over react.lazy?
route-resource-preload support code splitting of components, and support automatic preloading and manual preloading of components to avoid poor component interaction experience due to component rendering delays.
Why route-resource-preload over webpack-prefetch/preload and loadable-components-prefetch/preload?
- Control
when to preload in more detail - Support preload
Module-Federation - Support
More typesof resource (image/font/svg/css/js/...)
Online Demo Test
| Component | Normal Lazy Load(ms) | Preload (ms) |
|---|---|---|
| Simple Component (one-resource) | 150 | 1 |
| Complex Component (six-resource) | 350 | 10 |
It can be seen from the table that preloading significantly improves the loading speed of components, especially for complex components, the improvement of loading speed is more obvious. This shows that in complex business scenarios,
preloading can significantly improve component loading speed and user experience.
React Demo Source
Install
npm install @route-resource-preload/webpack-plugin @route-resource-preload/reactUsing in react
Method 1 - Manually To Preload Single Component Based on Dynamic
import { dynamic } from '@route-resource-preload/react'
const Image = dynamic({
loader: () => import('Components'),
loading: (props) => <>loading...</>,
})
const handleClick = () => {
// execute preloading
Image.preload()
}
export default function Main(props){
return <div onClick={handleClick}>
<Image {...props} />
</div>
}Method 2 - Manually To Preload Multiple Components
Step 1: First, you need add
pluginin your build config.const RouteResourcePreloadPlugin = require('@route-resource-preload/webpack-plugin') webpack: { plugins: { add: [ new RouteResourcePreloadPlugin({ // [the-preloading-flag]: ['path'] // project's components(modules) modulePreloadMap: { "flagA": ["../components/A"] }, // module-federation's components(modules) mfPreloadMap: { "flagMF": ["ling_core/Components"] }, // static assets (just like js/css/png/jpg/font, etc.) assetPreloadMap: { "flagA": ['https://domain.com/xxx.png'] } }) ] }, }Step 2: Create a
Preloaderandrunimport { Preloader } from '@route-resource-preload/react' const preloader = new Preloader() // execute preloading preloader.run('flagA')
Method 3 - Automatic Preloading.
Step 1: First, you need add
pluginin your build config.const RouteResourcePreloadPlugin = require('@route-resource-preload/webpack-plugin') webpack: { plugins: { add: [ new RouteResourcePreloadPlugin({ // [the-preloading-flag]: ['path'] // project's components(modules) modulePreloadMap: { "flagA": ["../components/A"] }, // module-federation's components(modules) mfPreloadMap: { "flagMF": ["ling_core/Components"] }, // static assets (just like js/css/png/jpg/font, etc.) assetPreloadMap: { "flagA": ['https://domain.com/xxx.png'] } }) ] }, }Step 2:
Dynamicimport component and renderPreloadLinkimport { dynamic, PreloadLink } from '@route-resource-preload/react' // project's component const ComponentA = dynamic({ loader: ()=>import('../components/A'), loading: () => <>loading...</> }) // module-federation's component const Image = dynamic({ loader: ()=>import('your_lib/Components'), loading: () => <>loading...</>, submodule: 'Image' // may be you didn't export default, just like " export { Image, ...Others } " in js. }) export default function Main(props){ return <> <PreloadLink flag="flagA" onClick={()=>{ navigate('/A') // navigate comes from react-router-dom, you can custom your code. }} > Preload Component A </PreloadLink> <PreloadLink flag="flagMF"> {/* Link comes from react-router-dom, you can custom your code. */} <Link to="flagMF" >Preload MF</Link> </PreloadLink> </> }
API
dynamic - Split your component code and load it dynamically
const Modal = dynamic({
loader: () => import('xxx/Modal'),
// loading: () => <>loading...</>,
// suspense: true,
// submodule: 'submodule',
// visible: true,
})| Param | Description | Type | Default Value | necessary |
|---|---|---|---|---|
| loader | dynamic import module | () => Promise<Record<string, T extends ComponentType>> | - | β |
| loading | A spinner for displaying loading state | ComponentType | - | β |
| submodule | maybe you didn't export default, you need it | string | - | β |
| visible | whether to render immediately after the components in the view are preloaded | boolean | true | β |
| suspense | use react <Suspense> for displaying loading state | boolean | - | β |
dynamicwill return a HOC withonEndprop, which will call back after the component is dynamically rendered to adapt to complex and changeable business scenarios, such as custom loading package elements/or computing component rendering time-consuming, etc.
function CommonLoading (props: { moduleName: string }) {
const { moduleName } = props
const [loading, setLoading] = useState(true)
const Com = useMemo(()=>dynamic({ loader: () => import(`${moduleName}`)}),[moduleName])
// custom loading
return <Spin spinning={loading}>
<Com onEnd={()=>{ setLoading(false)}} />
</Spin>
}
<CommonLoading moduleName={moduleName} />Preloader - Manually to preload based on
flag
const preload = new Preloader(options)
preload.run('flag') // plugin flag| Param | Description | Type | Default Value | necessary |
|---|---|---|---|---|
| publicPath | yout server publicPath | string | - | β |
Preloader's
publicPathis the same as RouteResourcePreloadPlugin'spublicPath
PreloadLink - Automatic the preloading of resources based on
flag
<PreloadLink flag="flagA" >
Preload Component
</PreloadLink>| Props | Description | Type | Default Value | necessary |
|---|---|---|---|---|
| flag | the preloading flag | string | - | β |
| children | children ReactNode | ReactNode | - | β |
| action | trigger preload action | string (init / inview / hover) | hover | β |
| onClick | PreloadLink click event | () => void | - | β |
| className | PreloadLink classname | string | - | β |
| publicPath | yout server publicPath | string | - | β |
PreloadLink's
publicPathis the same as RouteResourcePreloadPlugin'spublicPath
Plugin
Webpack-RouteResourcePreloadPlugin
RouteResourcePreloadPlugin's
publicPathis the same as PreloadLink'spublicPath
new RouteResourcePreloadPlugin({
// [the-preloading-flag]: ['path']
// project's components(modules)
modulePreloadMap: {
"flagA": ["../components/A"]
},
// module-federation's components(modules)
mfPreloadMap: {
"flagMF": ["xxx/Components"]
},
// static assets (just like js/css/png/jpg/font, etc.)
assetPreloadMap: {
"flagA": ['https://domain.com/xxx.png']
}
})| Params | Description | Type | Default Value | necessary |
|---|---|---|---|---|
| modulePreloadMap | project's components(modules) | modulePreloadMap Object | - | β |
| mfPreloadMap | module-federation's components(modules) | mfPreloadMap Object | - | β |
| assetPreloadMap | static assets | assetPreloadMap Object | - | β |
| publicPath | your server publicPath | string | - | β |
Others
init / inview / hover
value Description init Trigger preload after PreloadLink rendering inview Trigger preload after PreloadLink in the view hover Trigger preload after your mouse hover in the PreloadLink
modulePreloadMap Object
{
"flagA": ["../components/A"],
// [the-preloading-flag]: ['your project's components path']
}mfPreloadMap Object
{
"flagMF": ["ling_core/Components"]
// [the-preloading-flag]: ['your module-federation's components path']
}assetPreloadMap Object
{
"flagA": ['https://domain.com/xxx.png']
// [the-preloading-flag]: ['your static assets link'] (image/font/svg/css/js/...)
}2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago