vue——懒加载(异步延迟和彻底懒加载)

引入问题

单页面应用的致命问题: 首屏加载极慢

原因:
脚手架默认把所有组件集中打包为一个巨大的app.js文件,
首屏一次性全部下载。


本章教程皆以Vue脚手架初始示例为例:

npm run serve:
这里的app.js就包含了所有的组件(Home.vue和About.vue),此时文件大小124KB《在这里插入图片描述
npm run build:(打包项目)
可以看到app.js中也会包含所有组件
在这里插入图片描述


所以我们应该采用优化策略——懒加载
(用户想看什么就只下载什么,用户暂时不想看的,就没必要下载!)

一、默认: 异步延迟加载

定义:
先下载并显示首页内容。其它页面组件在不影响主屏下载速度的情况下进行 异步下载

优点: 既加快首屏加载的速度,又能享受单页面应用带来的好处。
缺点: 偷跑流量

步骤:

  1. 千万不要在router/index.js开头过早的引入除首页之外的其它页面组件。
    凡是用Import引入的东西,vue都会打包在app.js中,在首屏下载。

  2. 改造路由字典项:

		{
			  path:"/相对路径", 
			  //使用匿名函数自调
			  component: ()=>import(
				   // 打包时的分段名:自定义js文件名.xxx.js
				   /* webpackChunkName: "自定义js文件名" */
				   "../views/页面组件.vue"
			  )
		}

结果图解

使用异步延迟加载后:

npm run build(打包项目):
可以看到使用异步延迟后,打包后的js分为了两个,一个是About.xxx.js,一个是Home.xxx.js
在这里插入图片描述
异步延迟加载的文件后 rel = "prefetch"异步先获得,但不需要立刻加载显示
在这里插入图片描述


npm run serve:
在首页时也异步下载两个js文件,一个是Home.vue组件,114KB;一个是About.vue组件,12.6KB
此时突出缺点:用户未点开About组件但已经下载,浪费流量
在这里插入图片描述

二、彻底懒加载(手动配置)

定义:
如果用户不请求下一个页面组件,则不会提前下载其他页面组件

优点: 节约流量.
缺点: 首次切换页面时需要临时下载页面组件,可能会慢

步骤

1. 实现异步延迟加载的两步

i. 不要提前引入
ii. component变成匿名箭头函数

		{
			  path:"/相对路径", 
			  //使用匿名函数自调
			  component: ()=>import(
				   // 打包时的分段名:自定义js文件名.xxx.js
				   /* webpackChunkName: "自定义js文件名" */
				   "../views/页面组件.vue"
			  )
		}

2. 配置脚手架,去掉prefetch

i 在脚手架根目录,创建vue.config.js
ii. 在vue.config.js中添加以下固定代码
iii. 强调: 必须重启npm run serve

		module.exports={
			  chainWebpack:config=>{
				    config.plugins.delete("prefetch")
				    //删除index.html开头的带有prefetch属性的link
				    //不要异步下载暂时不需要的页面组件文件
			  }
		}

结果图解

npm run build(打包项目):
dist/js 中的js文件跟异步延迟加载一样,仍为两个
在这里插入图片描述
但是index.html中少了rel = "prefetch"属性的link
在这里插入图片描述
npm run serve:
打开首页时,只有app.js文件下载(Home组件)
在这里插入图片描述
切换成About组件时,才开始下载about.js
在这里插入图片描述

### Vue Treeselect 组件懒加载后的选项回显解决方案 对于 `Vue Treeselect` 组件,在处理大量数据时,通常会遇到性能瓶颈。为了优化用户体验并提高效率,可以采用懒加载技术来逐步加载子节点的数据。然而,当涉及到已选择项的回显时,则需要特别注意如何确保这些选定项能够正确显示。 #### 1. 数据结构设计 在定义树形菜单的数据源时,应遵循特定格式以便于组件识别哪些节点已经被选中。每个节点对象应当至少包含三个属性:`id`, `label` 和 `children`. 如果某个节点有子节点,则其对应的 children 数组不应为空;反之则设为 null 或 undefined 表明该层无更多分支[^3]. ```json [ { "id": 1, "label": "Node A", "children": [ {"id": 2,"label":"Child of Node A","children":null} ] } ] ``` #### 2. 使用 loadOptions 方法动态获取子节点 通过配置`:load-options="loadOptions"` 属性指定一个函数用于异步请求子节点列表。此方法接收两个参数——当前被点击展开的父级节点以及回调函数 callback 。一旦成功取得新一批次的数据后需调用callback传递结果集给组件继续渲染剩余部分[^4]: ```javascript methods:{ async loadOptions({action,node,callback}){ const response=await fetch(`/api/getChildren?id=${node.id}`); let data=response.json(); setTimeout(()=>{ //模拟网络延迟 callback(data); },500); } } ``` #### 3. 处理初始状态下的默认值展示问题 如果页面初次加载时就存在预置的选择项(即回显),那么必须提前准备好完整的路径信息供前端解析成可视化的层级关系。这可以通过向服务器发送额外查询获得整个链条上的所有祖先节点直至根部为止,并将其构造成符合预期的形式赋值给v-model绑定变量完成初始化工作[^5]: ```html <template> <treeselect v-model="selectedValue" :options="treeData" :load-options="loadOptions"/> </template> <script> export default{ data(){ return{ selectedValue:[],//存储最终提交至后台的实际ID集合 treeData:[]//由接口返回组装而成的整体架构描述符 }; }, created:async function(){ try{ var res = await axios.get('/getFullPathById',{params:{ids:this.selectedIds}}); this.treeData=res.data; this.selectedValue=this.selectedIds.map(id=>this.findNodeById(this.treeData,id)); }catch(error){console.error('Failed to initialize:',error);} }, methods:{ findNodeById(nodes,targetId){ for(let i=0;i<nodes.length;i++){ if(nodes[i].id===targetId)return nodes[i]; else if(Array.isArray(nodes[i].children)){ let result=this.findNodeById(nodes[i].children,targetId); if(result!==undefined)return result; } } } } }; </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你脸上有BUG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值