zoukankan      html  css  js  c++  java
  • React 按需加载

    代码分隔

    我们现在大多数React项目都是以Webpack 或者 Browserify等将一堆的jsx文件组织一起,并且由一个类似index.js的入口文件串联起来的单页面web页面。

    例如:

    
    // math.js
    export function add(a, b) {
      return a + b;
    }
    

    App:

    
    // app.js
    import { add } from './math.js';
    
    console.log(add(16, 26)); // 42
    

    打完包后:

    
    function add(a, b) {
      return a + b;
    }
    
    console.log(add(16, 26)); // 42
    

    从这个例子可以看出,打完包后将所有的js都压缩到一个文件里了。随着项目越来越大,打包的文件也会越来越大,如果再引入一些第三方的js库,那就更庞大了。

    接下来介绍一下如何将React代码分隔。(以下内容是16.6.0版本才支持的)

    Code Splitting会帮助你的应用实现lazy load.

    这么做,即使没有减少整个项目的代码量,也会避免在项目初始加载时,加载没必须的js,从而使用项目性能有所提升。

    import()

    最简单直接的方式就是引入动态 import 实现代码分隔。

    使用 动态 import 之前:

    
    import { add } from './math';
    
    console.log(add(16, 26));
    

    使用动态 import 后:

    
    import("./math").then(math => {
      console.log(math.add(16, 26));
    });
    
    注意,动态 import 并不是标准的EcmaScript,所以需要配置 babel-plugin-syntax-dynamic-import

    React.lazy

    React.lazy 可以以一个React标准组件的方法渲然一个动态引入的组件。

    以前的做法:

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

    使用 React.lazy

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

    这样在组件MyComponent渲然的时候才加载OtherComponent

    React.lazy 必须使用动态 import() 引入组件,必须返回一个 Promise Component

    React.lazy 目前不支持服务端渲然

    Suspense

    假如在 React.lazy 时,import 失败或者异常时,我们需要给于提示,或者一个默认的组件,我们就需要使用 Suspense .

    例如:

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

    fallback 也是一个组件,但不能通过 动态 import 引入的组件.

    Suspense 只能包裹一个单结点,如果有多个 动态 import 的组件需要放在一个 Suspense 中时,可以使用类似 React.Fragmet 包裹一下,也可以使用其他的 React 组件包裹。例如:

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

    基于Router的代码分隔

    基于 Router 的代码分隔,也是我们通常所说的按需加载。是我们推荐的方式。

    例如:

    
    import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
    import React, { Suspense, lazy } from 'react';
    
    const Home = lazy(() => import('./routes/Home'));
    const About = lazy(() => import('./routes/About'));
    
    const App = () => (
      <Router>
        <Suspense fallback={<div>Loading...</div>}>
          <Switch>
            <Route exact path="/" component={Home}/>
            <Route path="/about" component={About}/>
          </Switch>
        </Suspense>
      </Router>
    );
    

    Named Exports

    React.lazy 目前只支持 default 导出,不支持命名导出。例如,只支持:

    
    export default () => {
      return(<div>I am a Lazy component</div>);
    }
    

    如果要支持命令导出,需要重新再 export ,例如:

    
    // ManyComponents.js
    export const MyComponent = /* ... */;
    export const MyUnusedComponent = /* ... */;
    
    
    // MyComponent.js
    export { MyComponent as default } from "./ManyComponents.js";
    
    
    // MyApp.js
    import React, { lazy } from 'react';
    const MyComponent = lazy(() => import("./MyComponent.js"));
    

    推荐阅读 《React 手稿》

  • 相关阅读:
    Mysql基本操作、C++Mysql简单应用、PythonMysql简单应用
    Mysql安装步骤
    MVC EF 移除建表时自动加上s的复数形式
    MVC autofac 属性注入
    layui table默认选中指定行
    js slice 假分页
    sql 根据身份证号码计算年龄
    pointer-events: none
    /Date(1555554794000)/ 转换为日期格式
    sql 查询字段如果为null 则返回0的写法
  • 原文地址:https://www.cnblogs.com/lovellll/p/10113274.html
Copyright © 2011-2022 走看看