React Loadable---自动代码拆分打开import()

代码拆分是将一个包含entireapp的大捆绑包拆分为多个包含应用程序单独部分的小捆绑包的过程。

这似乎很难做到,但像Webpack这样的工具都内置了这个功能,andReact Loadable的设计目的是让它变得超级简单。

基于路由的拆分与基于组件的拆分

一个常见的建议是将你的应用程序分成不同的路由,并异步加载每个路由。对于许多应用程序来说,这似乎已经足够好用了——作为一个用户,点击一个链接并等待页面加载是一种熟悉的web体验。

但我们可以做得更好

使用大多数路由工具进行React时,路由只是一个组件。他们没有什么特别的地方。所以,如果我们优化了围绕组件拆分而不是路由呢?那会给我们带来什么?

事实证明:相当多。有很多地方不仅仅是路线,你可以很容易地将你的应用程序分开。modal、tabs和更多的UIcomponents会隐藏内容,直到用户做了一些事情来显示内容。

由于路由只是组件,所以我们仍然可以在路由级别轻松地进行代码拆分。

引入React Loadable

React Loadable是一个小库,它使以组件为中心的代码拆分在React中非常容易。

Loadable是一个高阶组件(创建组件的函数),它允许您在将任何模块呈现到应用程序之前动态加载它。

让我们设想两个组件,一个导入并呈现另一个。

import Bar from './components/Bar';

class Foo extends React.Component {
  render() {
    return <Bar/>;
  }
}

现在我们依赖Bar通过同步导入import,但在渲染之前我们不需要它。那我们为什么不推迟呢?

使用动态导入我们可以修改组件以加载Bar异步地

class MyComponent extends React.Component {
  state = {
    Bar: null
  };

  componentWillMount() {
    import('./components/Bar').then(Bar => {
      this.setState({ Bar: Bar.default });
    });
  }

  render() {
    let {Bar} = this.state;
    if (!Bar) {
      return <div>Loading...</div>;
    } else {
      return <Bar/>;
    };
  }
}

但那是一大堆工作,甚至不能处理很多案件。什么时候呢import()失败?服务器端渲染呢?

相反,您可以使用Loadable把问题抽象化

import Loadable from 'react-loadable';

const LoadableBar = Loadable({
  loader: () => import('./components/Bar'),
  loading() {
    return <div>Loading...</div>
  }
});

class MyComponent extends React.Component {
  render() {
    return <LoadableBar/>;
  }
}

自动代码拆分打开import()

当你使用import()有了webpack2,它将自动代码拆分不需要额外的配置

这意味着您只需切换到import()并使用React Loadable。找出你的应用程序的最佳性能。

创建一个很棒的“"Loading…”组件

呈现静态“"Loading…”与用户的通信不够。您还需要考虑错误状态、超时,并使之成为一种良好的体验。

function Loading() {
  return <div>Loading...</div>;
}

Loadable({
  loader: () => import('./WillFailToLoad'), // oh no!
  loading: Loading,
});

为了让这一切变得美好,你的loading component接受不同的道具

加载错误状态

当你loader失败了,你的loading component将收到error将成为错误对象(否则null ).

function Loading(props) {
  if (props.error) {
    return <div>Error! <button onClick={ props.retry }>Retry</button></div>;
  } else {
    return <div>Loading...</div>;
  }
}

回避加载元件闪光

Sometimes components load really quickly (<200ms) and the loading screen onlyquickly flashes on the screen.

大量的用户研究已经证明,这会导致用户感知事物的时间比实际时间长。如果你什么都不显示,用户会觉得速度更快。

所以你的加载组件也会得到一个pastDelay道具只有当组件的加载时间比集合长时,才会出现这种情况延迟 .

function Loading(props) {
  if (props.error) {
    return <div>Error! <button onClick={ props.retry }>Retry</button></div>;
  } else if (props.pastDelay) {
    return <div>Loading...</div>;
  } else {
    return null;
  }
}

此延迟默认为200ms但您也可以自定义延迟在里面Loadable .

Loadable({
  loader: () => import('./components/Bar'),
  loading: Loading,
  delay: 300, // 0.3 seconds
});

当时间到了loader花费的时间太长了

有时网络连接很糟糕,从不解决或失败,它们只是永远挂在那里。这对用户来说太糟糕了,因为他们不知道是应该一直花这么长时间,还是应该尝试刷新。

这个正在加载组件将收到timedOut道具将设置为是的loader已超时

function Loading(props) {
  if (props.error) {
    return <div>Error! <button onClick={ props.retry }>Retry</button></div>;
  } else if (props.timedOut) {
    return <div>Taking a long time... <button onClick={ props.retry }>Retry</button></div>;
  } else if (props.pastDelay) {
    return <div>Loading...</div>;
  } else {
    return null;
  }
}

但是,此功能在默认情况下处于禁用状态。要打开它,你可以通过timeout选项到可装载 .

Loadable({
  loader: () => import('./components/Bar'),
  loading: Loading,
  timeout: 10000, // 10 seconds
});

 

上一篇:[MOPT] 4. Loading Code at Runtime


下一篇:keil报错 error loading software packs