《前端那些事》聊聊前端的按需加载

简介: 前沿:按需加载是性能优化其中的一个环节,可以是图片的按需加载,也就是lazyload来实现按需加载的场景,也可以是组件库的引入,只需部分组件的使用而无需全局引入整个组件库的场景,又可以是路由的按需加载,当路由被访问的时候才加载对应组件的场景,以此来实现更高效率的使用等等,本文把“懒加载”也划分为按需加载

微信截图_20220512160636.png


前沿:按需加载是性能优化其中的一个环节,可以是图片的按需加载,也就是lazyload来实现按需加载的场景,也可以是组件库的引入,只需部分组件的使用而无需全局引入整个组件库的场景,又可以是路由的按需加载,当路由被访问的时候才加载对应组件的场景,以此来实现更高效率的使用等等,本文把“懒加载”也划分为按需加载


1.图片按需加载


场景:当一个页面存在需要多个图片加载的场景时,可以通过我们经常看到的所谓“懒加载”,当滑动到图片相应的位置时再加载图片的信息,以此来实现按需加载,举个最简单的例子,你去逛淘宝的时候,电商网站图片信息是很多的,这个时候如果把当前页面下的图片都将资源请求过来,是很消耗资源的,对网站的体验也是极其不好,只需要加载你当前“视线”下的图片即可,vue技术栈中vue-lazyload即可实现,下面聊聊它的使用和原理


1.1 vue-lazyload是什么


本质上懒加载就是,在适当的时候加载用户需要看的资源(可视区域),当页面开发时将src路径先预先设置好属性,这样页面加载时图片就不会马上向服务器请求资源,而是当图片滚动到可视区内时,再给src赋值并加载资源,而vue-lazyload就是基于这个概念实现的一个vue的工具库,官方介绍:A Vue.js plugin for lazyload your Image or Component in your application。使用文档点我👈


1.2 正确使用姿势


  • 安装


npm i vue-lazyload 


  • 如何使用


在main.js中通过vue实例加载插件


import Vue from 'vue'
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload);


页面中的使用,通过给图片定义v-lazy属性,如下所示


<ul>
  <li v-for="img in list">
    <img v-lazy="img.src" >
  </li>
</ul>


1.3实现原理


通过几个核心的点来介绍下vue-lazyload原理


微信截图_20220512160656.png


  • 定义LazyClass核心函数并获取lazy对象


通过Lazy和LazyClass得到了lazy这个对象,看看Lazy类的构造函数,源码链接点我


微信截图_20220512160709.png


  • 定义自定义指令lazy,区分vue版本 1x和2x的定义


vue-lazyload是通过指令的方式来实现的,定义v-lazy指令,该指令对应的几个回调函数:bind、update、componentUpdated和unbind分别绑定的是lazy对象的add、update、lazyLoadHandler和remove方法,如下所示


微信截图_20220512160726.png


关于vue指令可以看官方文档进一步了解:官方文档


  • 通过addLazyBox给图片dom绑定scroll事件,并push到监听队列(listener queue)


指令被bind时会创建一个listener,并将其添加到listener queue里面, 并且搜索target dom节点,为其注册dom事件


微信截图_20220512160738.png


  • 通过checkInView检测判断当前dom是否可以加载图片


checkInView方法被封装到_lazyloadHandler的方法,本质上是lazy构造器中使用的lazyloadHandler()函数,通过checkInView()函数检测位置是否需要加载,如果需要返回true,并触发load函数加载图片


它还通过throttle节流函数来限制一个函数在一定时间内只能执行一次,因为像scroll这些事件触发频率高,不做限制的话,一秒之内可能执行几十次


微信截图_20220512160751.png


2.组件的按需加载


场景:当我需要使用某个组件库的某个组件时,不想全部加载整个组件库,这个时候就需要按需加载了,可以解决一个首屏加载问题,降低首屏加载时间,举个例子,我现在需要用到element-ui库中的button组件,那我应该如何按需加载呢?


2.1 组件库的按需加载


以element-ui为例子,如果全局加载,会导致打包出来的包体积过大,影响交互体验,如下所示就是一个webpack打包后的webpack-bundle-analyzer工具分析出来的report,你可以通过 vue-cli中的命令生成report.html查看


"scripts": {
    "build": "vue-cli-service build --report",
 }


微信截图_20220512160803.png


那怎么去通过按需加载去使用组件库,答案是通过babel插件:babel-plugin-component(element 通过fork ant-design库的 )


微信截图_20220512160814.png


在babel转码的时候,把整个库element-ui的引用,变为element-ui/lib/button具体模块的引用。这样webpack收集依赖module就不是整个element-ui,而是里面的button

类似如何的转换


微信截图_20220512160824.png


如何安装


npm install babel-plugin-component –D


使用如下所示👇


微信截图_20220512160835.png


在main.js中使用如下


微信截图_20220512160847.png


2.2 项目中组件的按需加载


简单理解就是把我们的组件变成了一个函数,起初不执行它,只有你需要它的时候,也就是页面加载时,才触发它加载进来。


微信截图_20220512160858.png


3.路由中的按需加载


简单而言则是路由懒加载,当我们用webpack打包并构建应用时,输出的bundle 包会变得非常大,影响页面加载和体验。如果能将不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,而不是一开始全部加载,这样就更加高效了


3.1 vue的异步组件加载


可以将异步组件定义为返回一个 Promise (返回的 Promise 应该 resolve 组件本身)


微信截图_20220512160907.png


3.2 结合Webpack 2和ES语法使用import()


我们可以使用动态 import语法来定义代码分块点 (split point)


我们看看import一个组件返回的是什么?  promise!


微信截图_20220512160917.png


那么如何定义一个能够被 Webpack 自动代码分割的异步组件呢?如下所示


微信截图_20220512160926.png


如果你使用的是 Babel去支持import加载,则需要添加 syntax-dynamic-import 插件,才能使 Babel 可以正确地解析语法,否则会报语法错误,如下所示


微信截图_20220512160926.png


3.3 webpack的require.ensure() [不推荐]


使用webpack的require.ensure来实现按需加载,不过目前已经被上一节提到的 import() 取代


微信截图_20220512160949.png


往期文章




相关文章
|
前端开发 UED CDN
前端代码分割和按需加载策略
前端应用的规模不断增长,为了提高网页加载速度和减少初始加载时间,前端代码分割和按需加载策略变得越来越重要。本文将深入探讨前端代码分割和按需加载的策略,以及如何使用现代前端工具来实现这些优化。
202 0
|
2月前
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
188 2
|
2月前
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
55 0
|
2月前
|
人工智能 自然语言处理 运维
前端大模型应用笔记(一):两个指令反过来说大模型就理解不了啦?或许该让第三者插足啦 -通过引入中间LLM预处理用户输入以提高多任务处理能力
本文探讨了在多任务处理场景下,自然语言指令解析的困境及解决方案。通过增加一个LLM解析层,将复杂的指令拆解为多个明确的步骤,明确操作类型与对象识别,处理任务依赖关系,并将自然语言转化为具体的工具命令,从而提高指令解析的准确性和执行效率。
|
2月前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
2月前
|
机器学习/深度学习 弹性计算 自然语言处理
前端大模型应用笔记(二):最新llama3.2小参数版本1B的古董机测试 - 支持128K上下文,表现优异,和移动端更配
llama3.1支持128K上下文,6万字+输入,适用于多种场景。模型能力超出预期,但处理中文时需加中英翻译。测试显示,其英文支持较好,中文则需改进。llama3.2 1B参数量小,适合移动端和资源受限环境,可在阿里云2vCPU和4G ECS上运行。
130 1
|
2月前
|
前端开发 算法 测试技术
前端大模型应用笔记(五):大模型基础能力大比拼-计数篇-通义千文 vs 文心一言 vs 智谱 vs 讯飞vsGPT
本文对比测试了通义千文、文心一言、智谱和讯飞等多个国产大模型在处理基础计数问题上的表现,特别是通过链式推理(COT)提示的效果。结果显示,GPTo1-mini、文心一言3.5和讯飞4.0Ultra在首轮测试中表现优秀,而其他模型在COT提示后也能显著提升正确率,唯有讯飞4.0-Lite表现不佳。测试强调了COT在提升模型逻辑推理能力中的重要性,并指出免费版本中智谱GLM较为可靠。
前端大模型应用笔记(五):大模型基础能力大比拼-计数篇-通义千文 vs 文心一言 vs 智谱 vs 讯飞vsGPT
|
3月前
|
SpringCloudAlibaba JavaScript 前端开发
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
分布式组件、nacos注册配置中心、openfegin远程调用、网关gateway、ES6脚本语言规范、vue、elementUI
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
|
4月前
|
存储 前端开发 JavaScript
前端语言串讲 | 青训营笔记
前端语言串讲 | 青训营笔记
51 0