Vue 中实现图片预加载 + 懒加载原理实现

博客主要围绕Vue展开,介绍了Vue中的懒加载和预加载相关内容,这两项技术在前端开发中对优化性能等方面有重要作用。

##懒加载----------------------------------------------------

 插件---------
. 安装插件:
npm install vue-lazyload --save-dev


使用插件
main.js 中使用:

import VueLazyLoad from 'vue-lazyload'
Vue.use(VueLazyLoad,{
    error:'./static/error.png',                        //报错需要的图片
    loading:'./static/loading.png'					// 替换需要的图片
})
 
图片替换:

 vue文件中将需要懒加载的图片绑定 v-bind:src 修改为 v-lazy 

<img class="item-pic" v-lazy="newItem.picUrl"/>
 
 
图片懒加载原理实现
	getBoundingClientRect
      DOM 元素包含一个getBoundingClientRect 方法, 执行该方法返回当前DOM节点相关的Css边框集合,其中有一个Top 属性代表当前DOM 节点距离浏览器窗口顶部的高度,只需判断top值是否小于当前浏览器窗口的高度(window.innerHeight),若小于说明已经进入用户视野,然后替换为真正的图片即可
          另外使用getBoundingClientRect 作图片懒加载需要注意三点
            1。 因为需要监听scroll 事件,不停的判断top 的值和浏览器高度的关系,请对监听事件进行函数节流
            2. 当屏幕首次渲染时,不会触发scroll 事件,请主动调用一次事件处理程序,否则若用户不滚动则首屏的图片会一直使用懒加载的默认图片
            3. 当所有需要懒加载 的图片都被加载完,需要移除事件监听,避免不必要的内存占用


 intersectionObserver
      intersectionObserver作为一个构造函数,传入一个回调函数作为参数,生成一个实例observer,
      这个实例有一个observe方法用来观察指定元素是否进入了用户的可视范围,随即触发传入构造函数中的回调函数
      同时给回调函数传入一个entries 的参数,记录着这个实例观察的所有元素的对象,其中intersectionRatio 属性表示图片已经进入可视范围百分比,大于0 表示已经有部分进入了用户视野
      此时替换为真实的图片,并且调用实例的unobtrusive 将这个img 元素从这个实例的观察列表的去除

JS---方法一: getBoundingClientRect

  let imgList1 = [...document.querySelectAll("img")]
    let num = imgList1.length

    let lozyload1 = (()=>{
      let count = 0 
     return function(){
       let newArr = []
        imgList1.forEach((item, index)=>{
        let Rect =  item.getBoundingClientRect()
        if(Rect.top < window.innerHeight){
          Rect.src = Rect.dataset.src 
          newArr.push(index)
          count ++
          if(count === num ){
            document.removeEventListener("srcoll" , lozyload1)
          }
        }
      })
      //删除已加载完毕的图片
      imgList1 = imgList1.filter((_ , index)=> !newArr.includes(index))
    } 
    })()
    这里调用了throttle 的节流函数
    lozyload1 = proxy(lozyload1 , 100)
    document.addEventListen("srcoll" , lozyload1)
    手动执行一次,加载首屏图片
    lozyload1()



方法二:----intersectionObserver

   let imgList2 = [ ...document.querySelectAll("img") ]

      let lozyload2 = (()=>{
        实例化observer
        let observer = new IntersectionObserver( entries =>{
          entries 存储着所有观察元素的intersectionObserverEntry 配置
          entries.forEach(entry=>{
            if(entry.intersectionRatio > 0 ){
              entry.target.src = entry.target.dataset.src 
              //取消观察
              observer.unobserve(entry.target)
            }
          })
        })

        imgList2.forEach(img=>{
          observer.observe(img)
        })
      })

      lozyload2()

##Vue中的预加载-------------------------------------


 
 

解析代码: HTML:  img 标签为背景图, loading 图, P 标签为显示的百分比, 
	
	JS: imgArr 为 所有的图片信息 , 
			imgCount: 为动态的显示百分比

Vue的生命周期: mounted ,在页面加载完成时执行 loading 函数,

	在methods :中执行方法:   先将data 中的数据写到methods 中( 本人比较懒, 不想调用this ) 
		然后对所有的imgArr 进行遍历 ,  最后  image.onload 方法 , 代码在下面

在这里插入图片描述

这里面有个小坑, 就是图片动态加载时, 需求添加require , 用require 标签包裹下 ,   下面是图片   ,::::: 和img 图片路径

在这里插入图片描述

### Vue 图片懒加载最佳实践 图片懒加载是现代 Web 开发中一项重要的性能优化技术,特别是在图片密集型的网站和应用中。以下是实现 Vue 图片懒加载的最佳实践[^4]。 #### 1. 原理与步骤 图片懒加载的核心原理是通过监听滚动事件或使用 Intersection Observer API 检测图片是否进入视口范围,只有当图片进入视口时才加载其实际内容。在 Vue 中,可以通过自定义指令、第三方插件或组件的方式实现懒加载功能[^1]。 #### 2. 自定义指令实现懒加载 通过 Vue 的自定义指令,可以手动实现图片懒加载功能。这种方式灵活性较高,适合需要深度定制的场景。 ```javascript Vue.directive(&#39;lazy&#39;, { inserted(el, binding) { const observer = new IntersectionObserver((entries) => { if (entries[0].isIntersecting) { el.src = binding.value; observer.disconnect(); } }); observer.observe(el); } }); ``` 在模板中使用该指令: ```html <img v-lazy="&#39;path/to/image.jpg&#39;" src="placeholder.jpg" /> ``` #### 3. 使用第三方插件 Vue 社区提供了多个成熟的图片懒加载插件,如 `vue-lazyload-img` 和 `v-lazy-image`,这些插件封装了懒加载逻辑,简化了开发流程[^3]。 ##### 示例:使用 `vue-lazyload-img` 安装插件并初始化: ```bash npm install vue-lazyload-img ``` 在项目中引入并配置: ```javascript import Vue from &#39;vue&#39;; import VueLazyloadImg from &#39;vue-lazyload-img&#39;; Vue.use(VueLazyloadImg, { preLoad: 1.3, error: &#39;error.png&#39;, loading: &#39;loading.gif&#39; }); ``` 在模板中使用: ```html <lazy-image src="path/to/image.jpg" alt="Lazy Image" /> ``` #### 4. 利用 Intersection Observer API 现代浏览器支持的 Intersection Observer API 是实现图片懒加载的高效方式。相比传统的滚动事件监听器,它具有更好的性能表现[^4]。 示例代码: ```javascript const lazyImages = document.querySelectorAll(&#39;img.lazy&#39;); const observer = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; img.classList.remove(&#39;lazy&#39;); observer.unobserve(img); } }); }, { rootMargin: &#39;200px&#39; }); lazyImages.forEach((img) => observer.observe(img)); ``` 结合 Vue 使用时,可以在 `mounted` 生命周期中初始化 Intersection Observer[^4]。 #### 5. 预加载与路由切换优化 在单页应用中,用户可能在页面间快速切换。为了提升用户体验,可以在路由切换时预加载下一个页面的图片资源。例如,利用 Vue Router 的导航守卫提前触发图片加载逻辑[^2]。 ```javascript router.beforeEach((to, from, next) => { const nextRouteImages = to.meta.images || []; Promise.all(nextRouteImages.map((src) => preloadImage(src))).then(() => { next(); }); }); function preloadImage(src) { return new Promise((resolve, reject) => { const img = new Image(); img.onload = resolve; img.onerror = reject; img.src = src; }); } ``` #### 6. 全局状态管理 对于复杂的单页应用,可以借助 Vuex 管理图片加载状态和配置。例如,将所有图片加载进度存储在 Vuex store 中,并通过计算属性动态更新视图。 ```javascript // Vuex store state: { imageLoadingStatus: {} }, mutations: { setImageLoading(state, { src, status }) { Vue.set(state.imageLoadingStatus, src, status); } }, actions: { loadImages({ commit }, images) { images.forEach((src) => { preloadImage(src).then(() => { commit(&#39;setImageLoading&#39;, { src, status: &#39;loaded&#39; }); }).catch(() => { commit(&#39;setImageLoading&#39;, { src, status: &#39;error&#39; }); }); }); } } ``` #### 7. 性能监控与调试 在生产环境中,可以通过工具(如 Lighthouse 或 Performance API)监控图片懒加载的效果。确保懒加载逻辑不会对主线程造成过多压力,并且图片能够在合适的时间点加载完成[^4]。 --- ###
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值