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 手稿》
React 按需加载 - 代码分隔的更多相关文章
- angularJs按需加载代码(未验证)
一网友写的AngularJs按需加载代码,但未验证,放着备用. application.config( function($routeProvider) { ...
- react按需加载(getComponent优美写法),并指定输出模块名称解决缓存(getComponent与chunkFilename)
react配合webpack进行按需加载的方法很简单,Route的component改为getComponent,组件用require.ensure的方式获取,并在webpack中配置chunkFil ...
- Ant Design React按需加载
Ant Design是阿里巴巴为React做出的组件库,有统一的样式及一致的用户体验 官网地址:https://ant.design 1.安装: npm install ant --save 2.引用 ...
- react中使用antd按需加载(第一部)
什么是react按需加载?简单来说就是当我们引用antd的时候需要引入全局css样式,这会对性能造成一定的影响,那么使用按需加载以后就不需要引入css全局样式了,直接引入功能模块即可,既然需要设置按需 ...
- 前端性能优化之按需加载(React-router+webpack)
一.什么是按需加载 和异步加载script的目的一样(异步加载script的方法),按需加载/代码切割也可以解决首屏加载的速度. 什么时候需要按需加载 如果是大文件,使用按需加载就十分合适.比如一个近 ...
- ant-design如果按需加载组件
Ant Design React按需加载 Ant Design是阿里巴巴为React做出的组件库,有统一的样式及一致的用户体验 官网地址:https://ant.design 1.安装: npm in ...
- .NET中的按需加载/延迟加载 Lazy<T>
业务场景: 在项目开发中,经常会遇到特定的对象使用的加载问题,有的实例对象我们创建之后并非需要使用,只是根据业务场景来调用,所以可能会导致很多无效的实例加载 延迟初始化出现于.NET 4.0,主要用于 ...
- 深入浅出的webpack4构建工具---webpack+vue+router 按需加载页面(十五)
1. 为什么需要按需加载? 对于vue单页应用来讲,我们常见的做法把页面上所有的代码都打包到一个bundle.js文件内,但是随着项目越来越大,文件越来越多的情况下,那么bundle.js文件也会越来 ...
- webpack 代码拆分,按需加载
转自:https://segmentfault.com/a/1190000007649417?utm_source=weekly&utm_medium=email&utm_campai ...
随机推荐
- filters和scope在ElasticSearch Faceting模块的应用
filters和scope在ElasticSearch Faceting模块的应用 使用ElasticSearch的Facet功能时,有一些关键点需要记住.首先,faceting的结果只会基于查询结果 ...
- java 模拟简单搜索
Java 模拟简单搜索 实体类 package org.dennisit.entity; /** * * * @version : 1.0 * * @author : 苏若年 <a href=& ...
- 11.Hibernate一对多关系
创建JavaBean 一方: Customer private long cust_id; private String cust_name; private long cust_user_id; p ...
- 初识css3 3d动画效果
(先看我博客右上角的3d盒子动画效果,目前没做兼容处理,最好最新的chrome看)无意间看到网上css3写的3d动画效果,实在炫酷,以前理解为需要js去计算去写,没想到css直接可以实现.于是开始研究 ...
- ROS多线程编程
int main(int argc, char **argv) { ros::init(argc, argv, "multi_sub"); multiThreadListener ...
- 101 Hack October'14
拖了近一个月的总结.(可能源于最近不太想做事:() A题 给出n个长度都为n的字符串,你只可以对每个字符串分别排序,问当每个字符串按升序排序之后,每一列是否也是升序的. #include <cm ...
- JS创建和存储 cookie的一些方法
在js中cookie的操作与存储及清除cookie都与时间有关,我们只要把cookie过期时间进行有效的设置我们就可以控制它的存储了,下面我来给大家总结一下js中cookie的一些使用技巧 创建和存储 ...
- DVWA 之low级别sql注入
将Security level设为low,在左侧列表中选择“SQL Injection”,然后在右侧的“User ID”文本框中输入不同的数字就会显示相应的用户信息. 我们首先需要判断这里所传输的参数 ...
- Flask session到期时间设置 用户登录与登出
flask版本 1.1.1 最近学习Flask开发,看官方文档产生疑问,就是session有效期的问题,默认貌似是没有有效期的,只有关闭浏览器session才会失效,其实控制session的有效期非常 ...
- PyCharm在同一个包(package)下,如何把一个.py文件导入另外一个.py文件下
PyCharm在同一个包(package)下,如何把一个.py文件导入另外一个.py文件下 在同一个包下只需要用import 掉以后就可以找到模块所在的位置,但是如果不在同一个包下,在需要返回父级调用 ...