抛开场景,一味的吹捧路由懒加载就像在耍流氓🤣
异步路由长啥样?
原理不做过多介绍(大家都知道),直接上代码了
一般来说,只有SPA需要异步路由。当配置了异步路由,通过split chunk
,打包后都会生成单独的chunk,以webpack为例,建议添加魔法注释,并开启prefetch,以进一步提升体验
import loadable from '@loadable/component';
const XXXA = loadable(() => import('@/views/xx/XXXA'/* webpackChunkName: 'XXXA', webpackPrefetch: true */));
const XXXB = loadable(() => import('@/views/xx/XXXB'/* webpackChunkName: 'XXXB', webpackPrefetch: true */));
// ...
const allRoutes: IRoute[] = [
{
path: '/xxx-a',
component: XXXA,
},
{
path: '/xxx-b',
component: XXXB,
},
// ...
];
// ...
SPA应用,白屏现象能不能解决??
首先我们要搞明白的是,异步路由给我们解决的痛点是啥?
balabala....
Yes, 你打的很对👍🏾,就是为了缩减🐷包的大小,减少资源加载的时间。
但是,结合页面的加载过程,我先给您下个结论:
“SPA无论怎么优化,都无法避免白屏的现象产生,哪怕网速快,一闪而过(实际上你调成3g或带宽更低的网络,白屏一直伴随着你🤮)”
为啥🤬?
SPA
的入口是index.html
, 初始dom,只有div#app
,并且一般都没有任何样式- 页面加载需要先加载
必要js
,比如main.[hash].js
- 当
main.[hash].js
加载并解析成功,页面才会正常展示,so,空档期一定存在,这就是白屏现象的原因所在(注意:此时和是否有其他路由
没有任何关系)
为什么说异步路由不是100%保险??
问题的根本在于这句话:异步路由能提升首屏用户体验 👀
但是,很多人不知道,这里的首屏并不是单指index.html,举个例子:
对于移动端混合应用开发
,首屏可能变成SPA中的任何一个路由路径
。原因也很简单,APP首页中有很多菜单:每个菜单都可以配置路径,这些路径很可能来自同一个SPA。 我们暂且把这些路径叫做一级路由(不包括index.html)
对于以上场景,首屏
不再单一。
开始划重点
- 上述
一级路由(不包括index.html)
请不要配置成异步加载,使用普通的import
即可, 让它打进主包
中。 - 对于其他
非一级路由
,只是通过push、replace
进行跳转,那么配置为异步路由
就很合适
实际案例分析
还是先下个结论:
比如有个路由/xx-a,它作为一级路由
配置在了APP菜单中,那么它就变成了"所谓的首屏页面",如果我们还是使用异步路由
,就会延长白屏的时间
import loadable from '@loadable/component';
const XxxA = loadable(() => import('@/views/xx/XxxA'/* webpackChunkName: 'XxxA', webpackPrefetch: true */));
// ...
const allRoutes: IRoute[] = [
{
path: '/xxx-a',
component: XXXA,
},
// ...
];
// ...
此时,build目录中存在
main.[hash].js
(包含react路由逻辑
)XxxA.[hash].js
此时,打卡devtools,就会知道,network中资源加载顺序如下
- index.html
- main.js
- 如果index.html中引入了其他资源, 比如jquery, lodash...,也会优先download这些资源(哪怕你配置的defer或者async)
- 当main加载并执行后,才会触发路由逻辑,并开始加载
XxxA.[hash].js
- 加载
XxxA.[hash].js
成功,开始解析执行XxxA,XxxA页面才会被正常渲染
以上过程中,白屏的开始是main的加载和执行(包含了路由逻辑)的时间消耗产生的,而XxxA.[hash].js
的加载解析和执行,又无疑增加了空档期,这样白屏时间也就被延长了
若index.html中引入了若干其他script资源,并且处于http1.1的服务器环境中,这个现象就会变得特别明显
- 因为1.1多路复用对于资源的请求数量有限制,chrome下6个作为一组。
我们可以借助network和performance进行实际演示说明:
为了演示,我们将网络调慢些(实际上客户的网络环境也有这样的情况)
network
后续每组都需等待前一组加载完成,才开始加载
只有main加载成功并执行,才会触发路由逻辑,从而开始加载XxxA
脚本。如果网络慢,main.js加载过程就会更长,从而间接导致XxxA
脚本的加载和解析执行被推迟, 这无疑也就延长了白屏时间!!🦮
performance截图 (异步路由)
performance截图 (非异步路由)
此时代码逻辑被打进了main.js中,直接第一波解析执行即可,很明显缩短了白屏时间。
对比一下,就可以一目了然,哎,什么也不说了~
总结
异步路由并不能100%缩短白屏时间,最关键的是我们要知道“首屏”这个词的意义,它并不是单指index.html入口,它可以是SPA中的任何一个路由(结合混合移动开发场景就知道了)
So:
- 如果SPA中的“首屏”只有一个,不存在
移动混合开发场景
或者路径分享场景
(比如分享微信,支付宝等),那所有路由都可以进行异步加载 - 如果存在
移动混合开发场景
或者路径分享场景
,那对应的路由请不要异步加载,使用import即可。
好了,到此结束,如果对您有帮助,还望点个小💖💖
链接:https://juejin.cn/post/7216213764777328697
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。