目录
前言
为什么要代码分割?
第三方库方案——react-loadble
“lazy 方法 + Suspense 组件”方案
在 React16.6 版本之前,代码分割通常是由第三方库来完成的,比如 react-loadble(核心思路为: 高阶组件 + webpack dynamic import)。在 React16.6 版本中提供了 Suspense 和 lazy 这两个方法来实现代码分割。
React 项目打包时,如果不进行异步组件的处理,那么所有页面所需要的 js 都在同一文件中(bundle.js),整个js文件很大,从而导致首屏加载时间过长。为了解决这个的问题,现在像 Webpack、 Browserify 等打包器都支持了代码分割技术。
react-loadable 插件是一个轻量级的代码分割组件,是一个用于加载具有动态导入的组件的高阶组件。
英文官方文档:https://www.npmjs.com/package/react-loadable
中文翻译版文档:https://www.jianshu.com/p/462bb9d1c982
React Loadable 简介:React Loadable 简介
react-loadable 的使用:React 性能优化之组件动态加载(react-loadable)
我的实践:
// ./src/utils/loadable
import React from "react";
import { Spin } from "antd";
import Loadable from "react-loadable";
export default (loader) => {
return Loadable({
loader,
loading() {
return (
);
},
});
};
// routes.js
import loadable from "./src/utils/loadable";
const Home = loadable(() => import("./views/Home"));
const routes = [
{
path: "/Home",
component: Home,
title: "首页",
},
]
export default routes;
lazy 方法 + Suspense 组件 的使用示例:
import React, {lazy, Suspense} from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
Loading...
上述代码中还用到了import()方法,下面介绍下:
import() 函数是由 TS39 提出的一种动态加载模块的规范实现,其返回是一个 promise。
import() 源码如下:
function import(url) {
return new Promise((resolve, reject) => {
const script = document.createElement("script");
const tempGlobal = "__tempModuleLoadingVariable" + Math.random().toString(32).substring(2);
script.type = "module";
script.textContent = `import * as m from "${url}"; window.${tempGlobal} = m;`;
script.onload = () => {
resolve(window[tempGlobal]);
delete window[tempGlobal];
script.remove();
};
script.onerror = () => {
reject(new Error("Failed to load module script with URL " + url));
delete window[tempGlobal];
script.remove();
};
document.documentElement.appendChild(script);
});
}