注册

抛开场景,一味的吹捧路由懒加载就像在耍流氓🤣

异步路由长啥样?


原理不做过多介绍(大家都知道),直接上代码了


一般来说,只有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中资源加载顺序如下



  1. index.html
  2. main.js
  3. 如果index.html中引入了其他资源, 比如jquery, lodash...,也会优先download这些资源(哪怕你配置的defer或者async)
  4. 当main加载并执行后,才会触发路由逻辑,并开始加载XxxA.[hash].js
  5. 加载XxxA.[hash].js成功,开始解析执行XxxA,XxxA页面才会被正常渲染

以上过程中,白屏的开始是main的加载和执行(包含了路由逻辑)的时间消耗产生的,而XxxA.[hash].js的加载解析和执行,又无疑增加了空档期,这样白屏时间也就被延长了


若index.html中引入了若干其他script资源,并且处于http1.1的服务器环境中,这个现象就会变得特别明显



  • 因为1.1多路复用对于资源的请求数量有限制,chrome下6个作为一组

我们可以借助network和performance进行实际演示说明:


为了演示,我们将网络调慢些(实际上客户的网络环境也有这样的情况


image.png


network



后续每组都需等待前一组加载完成,才开始加载



image.png


只有main加载成功并执行,才会触发路由逻辑,从而开始加载XxxA脚本。如果网络慢,main.js加载过程就会更长,从而间接导致XxxA脚本的加载和解析执行被推迟, 这无疑也就延长了白屏时间!!🦮


performance截图 (异步路由)


image.png


performance截图 (非异步路由)



此时代码逻辑被打进了main.js中,直接第一波解析执行即可,很明显缩短了白屏时间。



image.png


对比一下,就可以一目了然,哎,什么也不说了~


总结


异步路由并不能100%缩短白屏时间,最关键的是我们要知道“首屏”这个词的意义,它并不是单指index.html入口,它可以是SPA中的任何一个路由(结合混合移动开发场景就知道了)


So:



  • 如果SPA中的“首屏”只有一个,不存在移动混合开发场景或者路径分享场景(比如分享微信,支付宝等),那所有路由都可以进行异步加载
  • 如果存在移动混合开发场景或者路径分享场景,那对应的路由请不要异步加载,使用import即可。

好了,到此结束,如果对您有帮助,还望点个小💖💖


作者:jerrywus
链接:https://juejin.cn/post/7216213764777328697
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册