📜  React 中的代码拆分

📅  最后修改于: 2022-05-13 01:56:48.012000             🧑  作者: Mango

React 中的代码拆分

Code-Splitting 是 Webpack、Rollup 和 Browserify 等打包工具支持的一项功能,它可以创建多个可以在运行时动态加载的包。
随着网站变得越来越大并深入到组件中,它变得越来越重。当包含第三方库时尤其如此。代码拆分是一种有助于生成能够动态运行的包的方法。它还有助于提高代码效率,因为捆绑包包含所有必需的导入和文件。
捆绑及其效率:捆绑是将导入的文件与单个文件合并的方法。它是在Webpack、Rollup、Browserify的帮助下完成的,因为它们可以创建许多可以在运行时动态加载的包。
借助代码拆分,可以实现“延迟加载”,即只使用当前需要的代码。

  • 默认导入方式如下:
javascript
import { add } from './math';
console.log(add(x, y));
 
// Here x, y are two numbers


javascript
import("./math").then(math => {
  console.log(math.add(x, y));
});
 
// Here x, y are two numbers


javascript
import React, { Suspense } from 'react';
const Component = React.lazy(() => import('./Component'));
function MyComponent() {
  return (
    
      Loading...
}>     
); }


javascript
import React, { Suspense } from 'react';
 
const ComponentOne =
 React.lazy(() => import('./ComponentOne'));
const ComponentTwo =
 React.lazy(() => import('./ComponentTwo'));
function MyComponent() {
  return (
Loading...
}>
); }


javascript
import React, { Suspense } from 'react';
import ErrorBoundary from './ErrorBoundary';
const ComponentOne = React.lazy(() =>
 import('./ComponentOne'));
const ComponentTwo = React.lazy(() =>
 import('./ComponentTwo'));
const MyComponent = () => (
  
    Loading...
}>   
);


javascript
import React from 'react';
import Suspense from 'react';
import lazy from 'react';
import {Route, Switch, BrowserRouter }
            from 'react-router-dom';
 
const HomePage = lazy(() =>
 import('./routes/HomePage'));
const AboutUs = lazy(() =>
 import('./routes/AboutUs'));
const App = () =>
 (Loading...
}> );


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


javascript

import("./math").then(math => {
  console.log(math.add(x, y));
});
 
// Here x, y are two numbers

一旦 Webpack 获得这种类型的语法,代码拆分就会自动启动。使用 Create React App 时,它已经设置好,可以立即使用。
如果使用 Webpack,应遵循 Webpack 代码拆分指南。可以在 https://webpack.js.org/guides/code-splitting/ 找到说明。
在使用 Babel 时,必须确保 Babel 不会转换导入语法,而是可以动态解析它。这可以使用 https://classic.yarnpkg.com/en/package/babel-plugin-syntax-dynamic-import 包来完成。
React.lazy 和 Suspense:由于 React.lazy 和 Suspense 目前还不能在服务器上渲染,建议使用 https://github.com/gregberge/loadable-components 在服务器中进行代码拆分-呈现的应用程序。 React.lazy 有助于将动态导入呈现为常规组件。
前:

import Component from './Component';

后:

const Component = React.lazy(() => import('./Component'));

Bundle 将在第一次渲染该组件时自行加载,其中包含该组件。
然后应该在 Suspense 组件中呈现惰性组件,这有助于在惰性组件加载的同时反映一些后备内容。

javascript

import React, { Suspense } from 'react';
const Component = React.lazy(() => import('./Component'));
function MyComponent() {
  return (
    
      Loading...
}>     
); }

fallback prop 可以接受 React 的任何元素,这些元素将在等待组件加载时呈现。 Suspense 组件可以放置在惰性组件上方的任何位置。此外,可以用一个 Suspense 组件包装多个惰性组件。

javascript

import React, { Suspense } from 'react';
 
const ComponentOne =
 React.lazy(() => import('./ComponentOne'));
const ComponentTwo =
 React.lazy(() => import('./ComponentTwo'));
function MyComponent() {
  return (
Loading...
}>
); }

错误边界:当某些模块由于任何问题而无法加载时,将触发错误。通过使用合适的错误页面,可以正确处理这些错误并为用户提供良好的体验。

javascript

import React, { Suspense } from 'react';
import ErrorBoundary from './ErrorBoundary';
const ComponentOne = React.lazy(() =>
 import('./ComponentOne'));
const ComponentTwo = React.lazy(() =>
 import('./ComponentTwo'));
const MyComponent = () => (
  
    Loading...
}>   
);

基于路由的代码拆分:很难在代码中实现代码拆分,捆绑包可以平均拆分,这将改善用户体验。
例子:

javascript

import React from 'react';
import Suspense from 'react';
import lazy from 'react';
import {Route, Switch, BrowserRouter }
            from 'react-router-dom';
 
const HomePage = lazy(() =>
 import('./routes/HomePage'));
const AboutUs = lazy(() =>
 import('./routes/AboutUs'));
const App = () =>
 (Loading...
}> );

命名导出: React.lazy 当前仅支持默认导出。如果要导入使用命名导出的模块,则必须创建一个默认重新导出的中间模块。这确保了摇树的工作并防止了未使用的组件的拉入。

javascript

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