@route-resource-preload/react
TypeScript icon, indicating that this package has built-in type declarations

1.0.0-beta.27 • Public • Published

@route-resource-preload/react - Any react can be split

Build Size Version

🚀 Focus on improving the first screen loading speed of applications and providing the best user experience, inspiration comes from the preloading of NextJS.

中文文档

Comparison

Based-on-react.lazy-normal-loading-effect.gif

Based-on-route-resource-preload-effect.gif

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 ?

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?

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/react

Using 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

  1. Step 1: First, you need add plugin in 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']
        }
      })
    ]
  },
}
  1. Step 2: Create a Preloader and run
import { Preloader } from '@route-resource-preload/react'

const preloader = new Preloader()

// execute preloading
preloader.run('flagA')

Method 3 - Automatic Preloading.

  1. Step 1: First, you need add plugin in 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']
        }
      })
    ]
  },
}
  1. Step 2: Dynamic import component and render PreloadLink
import { 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 -

dynamic will return a HOC with onEnd prop, 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 publicPath is the same as RouteResourcePreloadPlugin's publicPath

  • 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 publicPath is the same as RouteResourcePreloadPlugin's publicPath

Plugin

  • Webpack-RouteResourcePreloadPlugin

RouteResourcePreloadPlugin's publicPath is the same as PreloadLink's publicPath

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/...)
}

Package Sidebar

Install

npm i @route-resource-preload/react

Weekly Downloads

1

Version

1.0.0-beta.27

License

MIT

Unpacked Size

24.7 kB

Total Files

10

Last publish

Collaborators

  • awesomedevin