在create-react-app中使用Code Splitting实现按需加载js
为了减少HTTP请求,我们会把代码打包到一个文件里。
Code splitting可以把打包的文件分割成不同的块,并实现按需加载。
下面是在create-react-app中使用方法。
简单示例
- 创建项目
npx create-react-app code-splitting
- 在src文件夹里创建文件texts.js
const hello = 'Hello World!'; export { hello };
- 修改App.js
class App extends Component { constructor(props){ super(props); this.state = {}; } componentDidMount(){ import('./texts') .then(({hello}) => { this.setState({ msg: hello, }) }) .catch(err => { }); } render() { return ( <div className="App"> <div>{this.state.msg || 'loading...'}</div> </div> ); } } export default App;
- Chrome中network
分割react的组件
使用React Loadable分割,React Loadable还能创建 loading states, error states, timeouts, preloading,等状态。
原来的引用方式:
import OtherComponent from './OtherComponent';
const MyComponent = () => (
<OtherComponent/>
);
使用React Loadable启用了Code splitting的方式:
import Loadable from 'react-loadable';
const LoadableOtherComponent = Loadable({
loader: () => import('./OtherComponent'),
loading: () => <div>Loading...</div>,
});
const MyComponent = () => (
<LoadableOtherComponent/>
);
例子:
- 添加依赖
yarn add react-loadable
-
新建一个组件
Hello.js
import React from 'react'; export default () => ( <div>Hello world.</div> )
- 在App.js中引用Hello
import Loadable from 'react-loadable'; const LoadableOtherComponent = Loadable({ loader: () => import('./Hello'), loading: () => <div>Loading...</div>, }); const Hello = () => ( <LoadableOtherComponent/> );
- 在render函数里渲染
-
从network里可以看到又多了一个js文件
根据路由分割
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Loadable from 'react-loadable';
const Loading = () => <div>Loading...</div>;
const Home = Loadable({
loader: () => import('./routes/Home'),
loading: Loading,
});
const About = Loadable({
loader: () => import('./routes/About'),
loading: Loading,
});
const App = () => (
<Router>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
</Switch>
</Router>
);
-
安装依赖
yarn add react-router-dom
-
创建路由页面
routes/Home.js
import React from 'react'; export default () => ( <div>Home</div> )
routes/About.js
import React from 'react'; export default () => ( <div>About</div> )
- 在App.js中引用路由页面
const Loading = () => <div>Loading...</div>; const Home = Loadable({ loader: () => import('./routes/Home'), loading: Loading, }); const About = Loadable({ loader: () => import('./routes/About'), loading: Loading, });
- 配置路由
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom'; ... render() { return ( <Router> <div> <div>{this.state.msg || 'hello'}</div> <Hello/> <div> <Link to={'/'}>home</Link> <Link to={'/about'}>about</Link> </div> <Switch> <Route exact path="/" component={Home}/> <Route path="/about" component={About}/> </Switch> </div> </Router> ); }
- 在Chrome中查看network,可以看到第一次点击about的时候,浏览器会异步加载about组件的js
完整代码可以在github上看到:
https://github.com/shengoo/react-demo/tree/master/code-splitting