Open zp1112 opened 6 years ago
我们知道react或者是其他用于写单页应用的框架都是组件化的概念,每个路由每个页面就是一个个大组件,webpack在打包的时候,将所有的文件都打包进一个bundle里面,但是我们往往在a页面的时候不需要加载b页面的东西,理想情况下,用户访问一个页面时,该页面应该只需要加载自己使用到的代码,为了提高性能,webpack支持代码分片,将js代码打包到多个文件中按需加载。 按需加载的方式有两种,一个是 webpack提供的require.ensure(),一个是 ES6提案的import() 下面我们写一个asyncComponent异步加载方法,分别使用这两种方式实现。其实是写了一个高阶组件,高阶组件的理解可以看这篇文章。
webpack提供了require.ensure(),webpack 在编译时,会静态地解析代码中的 require.ensure(),同时将模块添加到一个分开的 chunk 当中。这个新的 chunk 会被 webpack 通过 jsonp 来按需加载。
// asyncCmponent.js import React, { Component } from 'react'; export default function asyncComponent (importFunc) { return class App extends Component { constructor(props) { super(props); this.state = { component: null } }; componentDidMount = () => { importFunc().then(mod => { this.setState({ component: mod.default || mod }) }); } render = () => { const C = this.state.component; return ( C ? <C {...this.props} /> : null ) } } }
调用
import asyncCmponent from './asyncCmponent.js'; const App = asyncCmponent(() => require.ensure([], (require) => require('./App'))); ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') );
打开浏览器,可以看到除了bundle.js还多了个1.js,且bundle的体积被拆分出来了。
es6中我们知道import是用于加载使用export命令定义的模块,import和require的区别在于import是在静态解析阶段执行的,所以它是一个模块之中最早执行的,而require是动态加载的,运行时加载模块,import命令无法取代require的动态加载功能。require到底加载哪一个模块,只有运行时才知道。import命令做不到这一点。因此,有一个提案,建议引入import()函数,完成动态加载。详情请看《es6入门》 import()函数返回的是一个promise。
// 只需修改componentDidMount部分 componentDidMount = () => { importFunc().then(mod => { this.setState({ component: mod.default || mod }) }) }
const App = asyncCmponent(() => import('./App')));
打开浏览器,可以看到同样的效果。boom!!!
很棒!
异步组件加载
我们知道react或者是其他用于写单页应用的框架都是组件化的概念,每个路由每个页面就是一个个大组件,webpack在打包的时候,将所有的文件都打包进一个bundle里面,但是我们往往在a页面的时候不需要加载b页面的东西,理想情况下,用户访问一个页面时,该页面应该只需要加载自己使用到的代码,为了提高性能,webpack支持代码分片,将js代码打包到多个文件中按需加载。 按需加载的方式有两种,一个是 webpack提供的require.ensure(),一个是 ES6提案的import() 下面我们写一个asyncComponent异步加载方法,分别使用这两种方式实现。其实是写了一个高阶组件,高阶组件的理解可以看这篇文章。
webpack提供的require.ensure()
webpack提供了require.ensure(),webpack 在编译时,会静态地解析代码中的 require.ensure(),同时将模块添加到一个分开的 chunk 当中。这个新的 chunk 会被 webpack 通过 jsonp 来按需加载。
调用
打开浏览器,可以看到除了bundle.js还多了个1.js,且bundle的体积被拆分出来了。
ES6提案的import()
es6中我们知道import是用于加载使用export命令定义的模块,import和require的区别在于import是在静态解析阶段执行的,所以它是一个模块之中最早执行的,而require是动态加载的,运行时加载模块,import命令无法取代require的动态加载功能。require到底加载哪一个模块,只有运行时才知道。import命令做不到这一点。因此,有一个提案,建议引入import()函数,完成动态加载。详情请看《es6入门》 import()函数返回的是一个promise。
调用
打开浏览器,可以看到同样的效果。boom!!!