作者 DBCdouble

一、前言

本文将基于上一篇文章《Webpack4+Babel7优化70%速度》所搭建的环境去做动态路由加载,同时完成 React16 和 React-Router4 的升级工作,使整个项目的技术栈以及性能体验尽可能达到最佳状态。

二、背景

我们知道,Webpack主要从两个方面进行优化,一个是提升构建速度,另一个则是减小文件体积,而在上一篇文章《Webpack4+Babel7优化70%速度》中,我们已经完成了提升构建速度的部分,这一章我们将通过实现动态加载路由的方式来将最终生成的打包文件拆分成多个子文件来减小bundle.js的体积,这样就能极大的减小首屏加载过慢的痛点,至此之后,也就再也不用担心随着应用越来越大,bundle.js的体积越来越大导致首屏加载的速度越来越慢的问题了。

三、升级模块

这里一个个模块安装升级是为了更准确地来把控更新之后有可能引起的报错

1、React16

npm install react@16.8.4 --save复制代码

这里安装目前react的最新版本v16.8.4,安装完成之后开启项目,发现页面报错,如图:

出现上面的报错的原因是React v15.5及以上版本已经将PropTypes模块剔除,然后执行

npm install prop-types --save 

将代码中

 import { PropTypes } from 'react' 

代码修改为

import PropTypes from 'prop-types'

注意:除了入口文件下的代码需要替换PropTypes,你项目中使用到的第三方库内部也有可能使用到了 

import { PropTypes } from 'react'

,遇到这种情况,需要将该第三方库升级到最新版本,包括react-router之前的老版本就是依赖于react库中的PropTypes作数据类型判断,所以接下来升级react-router

2、react-router-dom(这里使用react-router-dom,它基于react-router,加入了在浏览器运行环境下的一些功能)

npm uninstall react-router && npm install react-router-dom --save复制代码

react-router-dom依赖react-router,所以我们使用npm安装依赖的时候,只需要安装相应环境下的库即可,不用再显式安装react-router

  • 将代码中的

     import { Link } from 'react-router' 

    修改为

     import { Link } from 'react-router-dom'
  • 因为react-router4.x版本较之前版本改动较大,基本需要重写项目中的路由层

四、路由配置

1、入口文件

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';import App from './app';ReactDOM.render(<BrowserRouter><App /></BrowserRouter>,document.getElementById('app')
);复制代码

BrowserRouter是一个高阶组件,内置history的api来保持 UI 和 URL 的同步

2、路由配置

// routes.js
import Home from './home';
import About from './about';
import Help from './help';export default [{path: '/',exact: true,component: Home
}, {path: '/about',component: About
}, {path: '/help',component: Help
}];复制代码
// app.js
import React from 'react';
import { Switch, Route } from 'react-router';
import routes from './routes';class App extends React.Component {render() {return (<Switch>{routes.map((route, i) => <Route key={i} exact={!!route.exact} path={route.path} component={route.component} />)}</Switch>);}
}export default App;复制代码

Switch用于渲染与路径匹配的第一个子 <Route><Redirect>

五、异步动态加载路由和Code Splitting

异步动态加载路由从狭义上理解就是页面上没有出现的页面不加载对应的js和css,只加载当前页面展示出来页面的js和css,通过动态导入(dynamic imports)文件的方式实现代码拆分

1、封装一个高阶函数来异步加载组件

//async_load.js
import React, { Component } from 'react'
export default (loadComponent, placeholder = '拼命加载中...') => {return class AsyncComponent extends Component {unmount = falseconstructor () {super()this.state = {Child: null}}componentWillUnmount () {this.unmount = true}async componentDidMount () {const { default: Child } = await loadComponent()if (this.unmount) returnthis.setState({Child})}render () {const { Child } = this.statereturn (Child ? <Child {...this.props} /> : placeholder)}}
}复制代码

2、修改路由配置文件

// routes.js
import React from 'react';
import Load from './async_load';export default [{path: '/',exact: true,component(props) {// 这里的 component 函数也是一个高阶组件return <Load {...props} load={() => import('./home')} />;}
}, {path: '/about',component(props) {return <Load {...props} load={() => import('./about')} />;}
}, {path: '/help',component(props) {return <Load {...props} load={() => import('./help')} />;}
}];复制代码

当涉及到动态代码拆分时,webpack 提供了两个类似的技术。对于动态导入,第一种,也是优先选择的方式是,使用符合 ECMAScript 提案 的 import() 语法。第二种,则是使用 webpack 特定的 require.ensure

完成以上配置之后开启打包,出现一下错误

因为import语法还处于提案阶段,所以需要通过安装Babel的插件@babel/plugin-syntax-dynamic-import才能使用,安装完成之后需要在配置babel-loader的options:

{plugins: ['@babel/plugin-syntax-dynamic-import']
}复制代码

完成以上的步骤之后,想必已经没问题了吧,于是启动项目,又报错了:

在这个报错上我停留了太久,于是把问题抛给了一个朋友(大佬),在webpack在github上的Issue找到了答案,原来是webpack的4.29.x版本有bug

于是我回退了版本webpack@4.28.2,最终启动成功,可以看到bundle.js被拆分成多个子js文件

在浏览器打开开发者工具点击network查看请求的js文件,可以看到每进入一个新的页面,会动态加载一个新的js

进入首屏路由页面

进入另外一个路由页面

六、总结

不得不说升级老项目过程很痛苦,坑也很多。但是把坑一个个填完,最终完美升级也是一件很有意思,很有成就感的事。希望这篇文章能对你有所帮助。

文章有任何不清楚或者不准确的地方,麻烦在评论区指出

转载于:https://juejin.im/post/5c7f2b2e6fb9a049c43e6d68

Webpack按需加载秒开应用相关推荐

  1. require.ensure实现webpack按需加载

    webpack使用require.ensure将vue页面打包成独立的chunk文件,也可以将多个vue页面合并成一个chunk文件,以实现生产环境按需加载. 下面给出官网的require.ensur ...

  2. EasyDSS高性能流媒体服务器前端重构(五)- webpack + vue-router 开发单页面前端实现按需加载 - 副本...

    为了让页面更快完成加载, 第一时间呈现给客户端, 也为了帮助客户端节省流量资源, 我们可以开启 vue-router 提供的按需加载功能, 让客户端打开页面时, 只自动加载必要的资源文件, 当客户端操 ...

  3. webpack v3 结合 react-router v4 做 dynamic import — 按需加载(懒加载)

    为什么要做dynamic import? dynamic import不知道为什么有很多叫法,什么按需加载,懒加载,Code Splitting,代码分页等. 总之,就是在SPA,把JS代码分成N个页 ...

  4. Angular (SPA) WebPack模块化打包、按需加载解决方案完整实现

    Angular (SPA) WebPack模块化打包.按需加载解决方案完整实现 参考文章: (1)Angular (SPA) WebPack模块化打包.按需加载解决方案完整实现 (2)https:// ...

  5. webpack和vue的按需加载组件、console、抓包

    1.webpack和vue的按需加载组件 webpack特有的懒加载文件的方式,很大的提升了webpack打包SPA应用的在性能方面. 而从webpack2以后require.ensure已经被imp ...

  6. vscode vue解决跨域_Vue + WebPack + Typescript初学者VSCode项目 (按需加载、跨域调试、await/async)...

    万事开头难,一个好的Hello World程序可以节省我们好多的学习时间,帮助我们快速入门.Hello World程序之所以是入门必读必会,就是因为其代码量少,简单易懂.但我觉得,还应该做到功能丰富, ...

  7. webpack中实现按需加载

    当页面中一个文件过大并且还不一定用到的时候,我们希望在使用到的时候才开始加载这个文件俗称按需加载.这样可以减少页面的响应时间,提高访问速度. 使用webpack打包的出来的文件要实现以上的要求有两种方 ...

  8. webpack v3 结合 react-router v4 做 dynamic import — 按需加载(懒加载)

    为什么要做dynamic import? dynamic import不知道为什么有很多叫法,什么按需加载,懒加载,Code Splitting,代码分页等. 总之,就是在SPA,把JS代码分成N个页 ...

  9. Webpack实战(九):实现资源按需加载-资源异步加载

    第八篇[<教你搞懂webpack如果实现代码分片(code splitting)>] (https://blog.csdn.net/lfcss/article/details/104099 ...

最新文章

  1. 如何用html语言定位img,html经常使用标签(图像标签img,连接标签a,锚点定位,及路径)...
  2. linux光盘补救,Linux_忘记root密码时使用Linux系统光盘进行补救的方法,救援模式即rescue ,这个模式主 - phpStudy...
  3. Python入门 HelloWorld
  4. LeetCode 683. K 个空花盆(set/滑动窗口)
  5. android xml导进数据库,Android通过xml文件配置数据库
  6. linux日志2 1,cmd log 21 和 cmd 21 log的区别
  7. ExtDeprecationWarning: Importing flask.ext.bootstrap is deprecated, use flask_bootstrap instead.
  8. java中文api在线测试_万邑通开发者网站 - API在线测试
  9. 极通首次为中小企业量身定制EWEBS极速版
  10. 戴尔服务器怎么u盘安装win7系统教程,戴尔电脑怎么用u盘装win7系统教程
  11. 标准Modbus通讯协议格式
  12. [历年IT笔试题]2014微软校园招聘笔试试题
  13. CentOS8中如何支持TL-WDN7200H无线USB网卡?
  14. macbook 唤醒后不能输入密码
  15. 盘点老外对女人的爆笑称呼
  16. 0811 iOS开发完整学习路线
  17. 1000个微信小程序源码分享
  18. 小时候真傻,居然想着快快长大
  19. httpclient+jsoup实现小说线上采集阅读
  20. centos7更换内核后出现 pstore: unknown compression: deflate 问题解决

热门文章

  1. 【AI白身境】深度学习必备图像基础
  2. 中国高炉煤气脉冲袋式除尘器市场需求分析与竞争战略规划研究报告2022-2028年版
  3. Lua 通过 alien 库调用 zlib 压缩/解压
  4. vb制作可输出函数的通用DLL---VB_DLL_Link用法
  5. linux脚本结束语,读《Linux Shell脚本攻略》第9章笔记—结束语
  6. 移动端弹出遮罩层禁止页面滚动,遮罩里面的框允许滚动如何实现。
  7. java基础学习总结——对象转型
  8. 如何构建银行数据仓库
  9. 我跟17位顶级游戏策划人学到的3个产品方法论
  10. 产品经理面试中如何攻克有关用户体验的问题?