树酱但愿将前端的乐趣带给你们 本文已收录 github.com/littleTreem… 喜欢就star✨html
前沿:按需加载是性能优化其中的一个环节,能够是图片的按需加载,也就是lazyload来实现按需加载的场景,也能够是组件库的引入,只需部分组件的使用而无需全局引入整个组件库的场景,又能够是路由的按需加载,当路由被访问的时候才加载对应组件的场景,以此来实现更高效率的使用等等,本文把“懒加载”也划分为按需加载前端
场景:当一个页面存在须要多个图片加载的场景时,能够经过咱们常常看到的所谓“懒加载”,当滑动到图片相应的位置时再加载图片的信息,以此来实现按需加载,举个最简单的例子,你去逛淘宝的时候,电商网站图片信息是不少的,这个时候若是把当前页面下的图片都将资源请求过来,是很消耗资源的,对网站的体验也是极其很差,只须要加载你当前“视线”下的图片便可,vue技术栈中
vue-lazyload
便可实现,下面聊聊它的使用和原理vue
本质上懒加载就是,在适当的时候加载用户须要看的资源(可视区域),当页面开发时将src路径先预先设置好属性,这样页面加载时图片就不会立刻向服务器请求资源,而是当图片滚动到可视区内时,再给src赋值并加载资源,而
vue-lazyload
就是基于这个概念实现的一个vue的工具库,官方介绍:A Vue.js plugin for lazyload your Image or Component in your application。使用文档点我👈webpack
npm i vue-lazyload
复制代码
在main.js中经过vue实例加载插件git
import Vue from 'vue'
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload);
复制代码
页面中的使用,经过给图片定义v-lazy属性,以下所示github
<ul>
<li v-for="img in list">
<img v-lazy="img.src" >
</li>
</ul>
复制代码
经过几个核心的点来介绍下vue-lazyload原理web
经过Lazy和LazyClass获得了lazy这个对象,看看Lazy类的构造函数,源码连接点我vue-cli
vue-lazyload是经过指令的方式来实现的,定义v-lazy指令,该指令对应的几个回调函数:bind、update、componentUpdated和unbind分别绑定的是lazy对象的add、update、lazyLoadHandler和remove方法,以下所示npm
关于vue指令能够看官方文档进一步了解:官方文档element-ui
指令被bind时会建立一个listener,并将其添加到listener queue里面, 而且搜索target dom节点,为其注册dom事件
checkInView方法被封装到_lazyloadHandler的方法,本质上是lazy构造器中使用的lazyloadHandler()函数,经过checkInView()函数检测位置是否须要加载,若是须要返回true,并触发load函数加载图片
它还经过throttle节流函数来限制一个函数在必定时间内只能执行一次,由于像scroll这些事件触发频率高,不作限制的话,一秒以内可能执行几十次
场景:当我须要使用某个组件库的某个组件时,不想所有加载整个组件库,这个时候就须要按需加载了,能够解决一个首屏加载问题,下降首屏加载时间,举个例子,我如今须要用到element-ui库中的button组件,那我应该如何按需加载呢?
以element-ui为例子,若是全局加载,会致使打包出来的包体积过大,影响交互体验,以下所示就是一个webpack打包后的webpack-bundle-analyzer工具分析出来的report,你能够经过 vue-cli中的命令生成report.html查看
"scripts": {
"build": "vue-cli-service build --report",
}
复制代码
那怎么去经过按需加载去使用组件库,答案是经过babel插件:babel-plugin-component(element 经过fork ant-design库的 )
在babel转码的时候,把整个库element-ui的引用,变为element-ui/lib/button具体模块的引用。这样webpack收集依赖module就不是整个element-ui,而是里面的button
相似如何的转换
如何安装
npm install babel-plugin-component –D
复制代码
使用以下所示👇
在main.js中使用以下
简单理解就是把咱们的组件变成了一个函数,起初不执行它,只有你须要它的时候,也就是页面加载时,才触发它加载进来。
简单而言则是路由懒加载,当咱们用webpack打包并构建应用时,输出的bundle 包会变得很是大,影响页面加载和体验。若是能将不一样路由对应的组件分割成不一样的代码块,而后当路由被访问的时候才加载对应组件,而不是一开始所有加载,这样就更加高效了
能够将异步组件定义为返回一个 Promise (返回的 Promise 应该 resolve 组件自己)
咱们能够使用动态 import语法来定义代码分块点 (split point)
咱们看看import一个组件返回的是什么? promise!
那么如何定义一个可以被 Webpack 自动代码分割的异步组件呢?以下所示
若是你使用的是 Babel去支持import加载,则须要添加 syntax-dynamic-import
插件,才能使 Babel 能够正确地解析语法,不然会报语法错误,以下所示
使用webpack的require.ensure来实现按需加载,不过目前已经被上一节提到的 import() 取代
往期文章