Vue项目中遇到的HTTP请求队列阻塞问题及解决方案

一、背景

1. 业务场景

登录系统->进入首页(首页主要展示一些图片)->切换至列表页面

2. 问题现象

列表页面接口一直未响应。

3. 原因排查&分析

  • 由于内网、外网文件服务无法互通,首页有7个图片资源请求一直未响应(通过<img src="xxx.png" />标签加载),导致列表页面的请求一直处于pending状态。
  • 页面切换时,未释放上一个页面的请求

浏览器对相同域名的资源请求有并发数量限制(通常为6~8个请求),为了放在服务器过载和确保用户体验。

二、解决方案

1. 将静态资源和API服务分散到不同的域名

优点

  • 可解决http请求阻塞问题

缺点

  • 需要更多域名支持

2. 减少网络请求

优点

  • 理论上可解决此问题
  • 会带来一些性能提升

缺点

  • 解决此问题不适用

3. 使用图片懒加载

img标签设置loading="lazy"属性 <img src="xxxx.png" loading="lazy">

优点

  • 简单,只需要设置一个属性即可

缺点

  • 兼容性不是很好,IE不适用,适用于现代浏览器
  • 页面图片资源过多时,除了视窗中的图片会加载,靠近视窗即将出现的图片资源也会加载,可能无法限制请求的数量

4. 页面切换时利用src=""中断图片资源请求(推荐)

优点

  • 可完美解决此问题

缺点

  • img标签需要设置一个特定的属性,避免其他框架中的图片也被清除(如系统导航栏的logo)
Home.vue 复制代码
<template>
  <img src="xxxx1.png"	/>
  <img src="xxxx2.png"	/>
  <img src="xxxx3.png"	/>
  <img src="xxxx4.png"	/>
  <img src="xxxx5.png"	/>
  <img src="xxxx6.png"	/>
  <img src="xxxx7.png"	/>
</template>

<script>
export default {
  beforeRouteLeave() { // 页面离开时中断图片资源请求
    const images = container.querySelectorAll(`img[data-cancelable]`)// 此处data-cancelable可自定义配置,通过options传递
    images.forEach(image => {
      image.src = options.placeholder || '' 
    })
  }
}
</script>

三、插件封装

1. 插件

ClearImageRequest.js 复制代码
/*
 图片请求中断插件
*/
export default {
  install(Vue, options = {}) {
    Vue.prototype.this.$clearImageRequest = function() {
      const container = this.$el || document
      const images = container.querySelectorAll(`img[data-cancelable]`)// 此处data-cancelable可自定义配置,通过options传递
      images.forEach(image => {
        image.src = options.placeholder || '' 
      })
    }

    Vue.mixin({
      beforeRouteLeave() {
        if (options.autoClear) { // 自动清除
          this.$clearImageRequest()
        }
      }
    })
  }
}

2. 使用

main.js 复制代码
import Vue from 'vue'
import ClearImageRequest from './plugins/ClearImageRequest.js'

Vue.use(ClearImageRequest, {
  autoClear: true, // 切换页面,自动中断图片资源请求
  placeholder: '', // 占位图,可选
})

// 调用方法手动中断图片资源请求
this.$clearImageRequest()
相关推荐
paopaokaka_luck几秒前
基于SpringBoot+Uniapp的健身饮食小程序(协同过滤算法、地图组件)
前端·javascript·vue.js·spring boot·后端·小程序·uni-app
90后的晨仔3 小时前
🚨XSS 攻击全解:什么是跨站脚本攻击?前端如何防御?
前端·vue.js
90后的晨仔3 小时前
Vue 模板语法完全指南:从插值表达式到动态指令,彻底搞懂 Vue 模板语言
前端·vue.js
90后的晨仔4 小时前
Vue 3 应用实例详解:从 createApp 到 mount,你真正掌握了吗?
前端·vue.js
SY_FC4 小时前
uniapp input 聚焦时键盘弹起滚动到对应的部分
javascript·vue.js·elementui
爱吃香蕉的阿豪5 小时前
SignalR 全解析:核心原理、适用场景与 Vue + .NET Core 实战
vue.js·microsoft·c#·.netcore·signalr
OpenTiny社区8 小时前
把 SearchBox 塞进项目,搜索转化率怒涨 400%?
前端·vue.js·github
ReturnTrue8688 小时前
Vue路由状态持久化方案,优雅实现记住表单历史搜索记录!
前端·vue.js
武昌库里写JAVA9 小时前
「mysql」Mac osx彻底删除mysql
vue.js·spring boot·毕业设计·layui·课程设计
Rika9 小时前
手写mini-vue之后,我写了一份面试通关手册
前端·vue.js