代码之家  ›  专栏  ›  技术社区  ›  Hemadri Dasari

什么是懒惰?

  •  2
  • Hemadri Dasari  · 技术社区  · 6 年前

    我正在通过react官方文件来了解react lazy。

    https://reactjs.org/docs/code-splitting.html#reactlazy

    当呈现此组件时,这将自动加载包含OtherComponent的包。

    React.lazy 接受一个必须调用动态 import() Promise

    正常导入

    import OtherComponent from './OtherComponent';
    function MyComponent() {
        return (
            <div>
               <OtherComponent />
            </div>
        );
    }
    

    const OtherComponent = React.lazy(() => import('./OtherComponent'));
    function MyComponent() {
        return (
           <div>
               <OtherComponent />
          </div>
        );
    }
    

    但是我无法从文档中了解使用lazy导入组件的好处。为什么promise会出现在导入模块/组件的画面中?

    5 回复  |  直到 4 年前
        1
  •  13
  •   Mrchief    6 年前

    单页应用程序(spa)通常通过下载 HTML5 history API . 这创造了一个难以置信的强大的用户体验,因为浏览器永远不需要 刷新 要加载应用程序的任何部分,您可以立即从一个页面/URL导航到另一个页面/URL。

    有许多人试图纠正这一点- asynchronous and deferred loading of scripts 大块 -这样做的目的是尽快下载应用程序的核心或关键部分,然后按需加载其余代码。这解决了上面提到的问题,但是实现代码分裂却非常困难。

    其中一个原因是,像Webpack这样的工具很难找到有效地拆分代码的方法,只需较少的人工干预。在里面 AMD 世界, define / require 帮助您定义代码分割点—这样您可以先加载关键部分,然后按需以异步方式加载rest。

    在这个世界上, lazy 使您能够以较少的手动干预有效地执行此操作。通过定义某事 懒惰的

    这个 () => import('./OtherComponent') 语法也被称为 dynamic import 与静态导入不同: import OtherComponent from './OtherComponent' . 动态导入是异步的,因此它们总是返回一个承诺。A. 确保 视情况而定 在这个延迟加载的模块上, 执行 只有在脚本加载之后。

    考虑下面的片段:

    const PurchaseHistory = lazy(() => import('./components/PurchaseHistory'))
    
    class App extends Component {
      state = {
        purchases: [ ],
      };
    
      componentDidMount() {
        fetch(`some/api/that/returns/data`)
          .then(res => res.json())
          .then(res => {
            this.setState({ purchases: res.data });
          });
      }
      render() {    
        return (
          <div className="app">
            <Suspense fallback={Loader}>
              <PurchaseHistory {...purchases} />
            </Suspense>
          </div>
        );
      }
    }
    

    在上面的代码中,React可以立即用 Loader 在获取成功之前,它甚至不需要加载 PurchaseHistory 组件。这节省了下载时间,减少了内存占用,节省了下载和处理数据所需的CPU周期 采购历史记录 组件。

    Suspense 是React 16.6中的新API。

    并行渲染 ,上面的代码确保React渲染应用程序的速度非常快(比React 16快)。它之所以能够这样做,是因为React知道哪些部分是关键的,哪些部分不是关键的。

    blog post 通过代码示例讨论了所有3个特性。

        2
  •  4
  •   T.J. Crowder    6 年前

    它允许您延迟加载另一个组件的脚本。如果该脚本与其他脚本(例如,不是主捆绑包的一部分)是分开的,那么这将非常有用。

    • 初始启动更快(假设组件不是初始显示的一部分)
    • 如果用户从不执行显示组件的任何操作,则不需要加载另一个组件的脚本(这样就保存了一个HTTP请求和模块消耗的内存加载)

    当然,也有缺点:

    • 当您的组件需要显示时,它将因按需加载另一个组件的脚本而延迟(HTTP请求,顶级模块求值)

    像往常一样,对某些项目来说,取舍是一种方式,而对其他项目来说,取舍是另一种方式。一个大的单页应用程序,有许多用户可能会或可能不会访问的部分可能会受益;一个很小的页面,其中所有的组件可能都在早期呈现,但可能不会。

        3
  •  4
  •   dance2die    6 年前

    简单地说,如果您延迟加载的组件没有被使用,它就不会被下载到浏览器中。

    Hello & Bye 是进口的。 但因为只有 已使用,代码为 不包括在内。

    import React, { lazy, Suspense } from "react";
    import ReactDOM from "react-dom";
    
    const Hello = lazy(() => import("./components/Hello"));
    const Bye = lazy(() => import("./components/Hello"));
    
    function App() {
      return (
        <Suspense fallback={<>Loading...</>}>
          <Hello />
        </Suspense>
      );
    }
    
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);
    

    你可以继续下去 CodeSandbox
    Edit so.answer.53174915

    当你检查 deployed site 在Netlify,
    你可以从网站上看到 拜伊 未加载。

    enter image description here


    无耻的塞子 :如果您想了解更多关于其他用例的信息,请查看我的博客, Loading React Components Dynamically on Demand using React.lazy .

        4
  •  1
  •   guru107    6 年前

    当单页应用程序开始变大时。一次加载所有javascript是没有意义的。假设你在主页上,为Profile部分加载javascript是没有意义的,它会减慢主页的页面加载速度。因此,代码将您的巨大应用程序分割成相当大的块将使应用程序的性能更好。简言之 lazy loading 你的部件。

        5
  •  1
  •   Arnab    6 年前

    基本上,对于普通导入,它将导入父组件所需的所有子组件。但是,对于延迟加载的子组件,它是异步加载的。当子组件本身包含许多其他子组件层次结构时,这确实有助于节省父组件的初始加载时间,并最终延长主页面的加载时间。但是,当对组件使用Lazyloading时,您要lazyload的组件必须用带有fallback属性的“suspence”标记括起来,因为当加载父组件并且随后加载fallback属性中提供的jsx时,延迟加载组件的内容将不可用。