随着项目的包越来越大,加载越来越慢,觉得有必要添加一个进度条,最起码让用户知道页面正在加载,而不是卡死了。
进度条用的是NProgress
。思路是,NProgress
的包使用cdn
加载,因为需要尽可能快的显示进度条,所以不能一并打包。在页面进入后就显示进度条,加载后完成进度条。
首先,有两个地方需要有显示进度条的代码。一个是在在index.html
中,因为在现在包的过程中加就需要显示进度条。第二个地方是进入每个路由的时候。这个是在PrivateRoute
(包裹路由的拦截组件)的componentWillReceiveProps
钩子中。
if (nextProps.path !== this.props.path && !NProgress.status) { NProgress.start() }
然后,完成进度条的地方。这个地方比较难找。
- 不能在
PrivateRoute
中根据子组件是否加载完成判断,因为不知道子组件是否加载完成。 - 不能在
PrivateRoute
中根据document.getElementById('root').childElementCount
进行判断,原因同上。当然,可以设置一个全局定时器,在定时器中实时判断,但这样并不好。 - 不能通过
dva-loading
判断,因为在加载过程中,loading.global
会多次变化。 - 不能在
index.js
中通过dva
的config
注入onReducer
之类的钩子判断,因为不是所有的页面都有model
。 - 最后成功的方法,通过
MutationObserver
进行DOM
监听。不过,这个监听是在index.js
中,不在PrivateRoute
中,不知道为什么,在路由拦截组件里监听会不完整。
// index.js // 监听 #root 元素--以实现页面加载完成后取消 NProgress 进度条 // 不放到 PrivateRoute 里面,是因为在那里监听不完全,原因未知 function observeRoot() { if (!supportMutationObserver) { console.log('浏览器不支持DOM监听') return } const targetNode = document.body const config = { childList: true, subtree: true, characterData: true } const callback = () => { let root = document.getElementById('root') || {} if (NProgress.status && root.childElementCount) { NProgress.done() } } let observer = new MutationObserver(callback) observer.observe(targetNode, config) } observeRoot()