8000 GitHub - mitermayer/react-loosely-lazy: Use advanced React async components patterns today
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

mitermayer/react-loosely-lazy

 
 

Repository files navigation

react-loosely-lazy

A future focused async component loading library for React. Comes packed with loading phases to enable fine-grained performance optimisations.

Why?

Today, React's native solution for asynchronously loading components, React.lazy, does not work on the server. To get around this, developers have had to invent their own solutions to the problem such as react-loadable and loadable-components. These libraries however will not be compatible with Suspense out of the box and their APIs are quite different to the direction the React team are taking. It's also clear that this has become such a core part of building React apps at scale that it makes sense to rely on React to fill this requirement rather than third party libraries.

In addition to this we have to consider that, certainly from a performance point of view, not all components are created equal. It does not make sense to load components which are required for your user's first meaningful paint at the same time as those which are not. Doing so will impact your user's experience negatively. Likewise it is best to be able to opt-out of SSR for a component if you know that this will delay response times from the server significantly or if the component will not be able to be rendered in your Node environment.

React Loosely Lazy solves both of these problems with a server side compatible API that looks just like Suspense, while also providing an opt-in, phase based loading mechanism.

Features

  • Same code on server and client, handling SSR transparently
  • Loading priority support via phases
  • Customisable deferred loading and phases definition
  • Preloading support
  • Works with both React.render() and React.hydrate()
  • Babel plugin that works on both client and server to ensure cleaner code and synchronous imports in Node

Usage

In your app

import { lazyForPaint, LazySuspense } from 'react-loosely-lazy';

const MyAsyncComponent = lazyForPaint(() => import('./MyComponent'));
const Loading = () => <div>loading...</div>;
const App = () => (
  <LazySuspense fallback={Loading}>
    <AsyncMyComponent />
  </LazySuspense>
);

In your webpack config

Server

module: {
  rules: [{
    test: /\.js$/,
    use: [
      {
        loader: 'babel-loader',
        options: {
            presets: [...yourPresets],
            plugins: [...yourOtherPlugins, ['react-loosely-lazy/babel-plugin']],
        },
      },
    ]
  }]
}

Client

module: {
  rules: [{
    test: /\.js$/,
    use: [
      {
        loader: 'babel-loader',
        options: {
            presets: [...yourPresets],
            plugins: [...yourOtherPlugins, ['react-loosely-lazy/babel-plugin', { client: true }]],
        },
      },
    ]
  }]
}

Installation

npm i react-loosely-lazy
# or
yarn add react-loosely-lazy

Documentation

Basic use case: SSR + async loading of a component required for the first meaningful paint

import { lazyForPaint, LazySuspense } from 'react-loosely-lazy';

const AsyncMyComponent = lazyForPaint(() => import('./MyComponent'));
const App = () => (
  <LazySuspense fallback="...">
    <AsyncMyComponent />
  </LazySuspense>
);

No SSR use case: Fallback on SSR + async loading the component on the client

import { lazyAfterPaint, LazySuspense } from 'react-loosely-lazy';

const AsyncMyComponent = lazyAfterPaint(() => import('./MyComponent'), {
  ssr: false,
});
const App = () => (
  <LazySuspense fallback={<MyComponentSkeleton />}>
    <AsyncMyComponent />
  </LazySuspense>
);

Phase loading use case: SSR + specific phase loading

import { lazyAfterPaint, useLazyPhase, LazySuspense } from 'react-loosely-lazy';

const AsyncMyComponent = lazyAfterPaint(() => import('./MyComponent'));

const App = () => {
  const { startNextPhase } = useLazyPhase();
  // eg start loading MyComponent after the app is mounted
  useEffect(() => {
    startNextPhase();
  }, [startNextPhase]);

  return (
    <LazySuspense fallback="...">
      <AsyncMyComponent />
    </LazySuspense>
  );
};

Trigger loading use case: No SSR & loading on user iteraction

import { lazy, LazyWait, LazySuspense } from 'react-loosely-lazy';

const AsyncMyComponent = lazy(() => import('./MyComponent'));
const App = () => {
  const [shouldLoad, setLoad] = useState(false);

  return (
    <>
      <button onClick={() => setLoad(true)}>Load</button>
      <LazyWait until={shouldLoad}>
        <LazySuspense fallback={shouldLoad ? <MyComponentSkeleton /> : null}>
          <AsyncMyComponent />
        </LazySuspense>
      </LazyWait>
    </>
  );
};

Examples (currently broken)

Note: The examples are currently not working as intended so it's best not to use them for now. We will be fixing these shortly!

See react-loosely-lazy in action: run npm run start and then go and check: http://localhost:8080/

Contributing

Thank you for considering a contribution to react-loosely-lazy! Before doing so, please make sure to read our contribution guidelines.

Development

To test your changes you can run the examples (with npm run start). Also, make sure you run npm run preversion before creating you PR so you will double check that linting, types and tests are fine.

License

Copyright (c) 2020 Atlassian and others. Apache 2.0 licensed, see LICENSE file.

With ❤️ from Atlassian

About

Use advanced React async components patterns today

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 73.6%
  • JavaScript 26.4%
0