一、为什么要优化网络请求?
现代Web应用中,网络请求的稳定性直接影响用户体验。尤其是在弱网环境下,请求失败率会显著上升。想象这样一个场景:用户在地铁上刷你的电商网站,商品列表接口时通时断,这时候若能自动重试失败请求并展示缓存数据,就能明显提升用户的浏览体验。
二、技术栈选择与基础搭建
(技术栈:Vue3 + Vite + VueUse)
// 项目初始化命令(确保Node.js >=14.18)
npm create vite@latest vueuse-demo --template vue-ts
// 安装依赖
npm install @vueuse/core axios
三、基础请求场景实现
// src/components/ArticleList.vue
<script setup lang="ts">
import { useFetch } from '@vueuse/core'
const { data, error } = useFetch('https://api.example.com/articles')
</script>
<template>
<div v-if="error">哎呀,加载失败啦!</div>
<ul v-else-if="data">
<li v-for="article in JSON.parse(data)" :key="article.id">
{{ article.title }}
</li>
</ul>
</template>
这时候我们获得了一个最基础的网络请求实现,但缺乏容错机制和性能优化。
四、智能重试机制实战
// 增强版请求配置
const { data, retry } = useFetch('https://api.example.com/articles', {
// 失败时自动重试
retry: 3, // 最大重试次数
retryDelay: 1000, // 重试间隔(毫秒)
timeout: 5000, // 单次请求超时时间
}, {
// 响应拦截器
afterFetch(ctx) {
if (ctx.statusCode !== 200) {
ctx.error = new Error('服务端异常')
}
return ctx
}
}).json() // 自动解析JSON
// 手动重试按钮
<button @click="retry()" v-if="error">点击重试</button>
此时我们的请求具备自动容错能力,但频繁请求仍会造成服务器压力。
五、缓存策略深度应用
// 创建缓存管理器
const cacheManager = new Map<string, {
timestamp: number
data: any
}>()
const { data } = useFetch('https://api.example.com/articles', {
// 开启缓存
cache: 'force-cache',
// 自定义缓存键
cacheKey: 'article_list',
// 自定义缓存处理
cacheManager: {
get: key => cacheManager.get(key),
set: (key, value) => cacheManager.set(key, {
timestamp: Date.now(),
data: value
}),
has: key => cacheManager.has(key)
},
// 缓存有效期(10分钟)
cacheMaxAge: 600_000
}).json()
现在我们的应用已具备本地内存缓存能力,但还需要处理缓存更新策略。
六、全功能集成示例
// 完整请求配置示例
const { data, error, retry, isFetching } = useFetch('https://api.example.com/articles', {
// 缓存配置
cache: 'force-cache',
cacheKey: 'articles_v2',
cacheMaxAge: 300_000,
// 重试配置
retry: 2,
retryDelay: 2000,
// 性能优化
refetch: true, // 窗口重新聚焦时刷新
timeout: 8000,
// 请求头
headers: {
'Cache-Control': 'max-age=300'
}
}, {
// 请求拦截器
beforeFetch({ options }) {
options.headers.Authorization = `Bearer ${token.value}`
return { options }
},
// 响应拦截器
afterFetch(ctx) {
if (ctx.data.code !== 0) {
ctx.error = new Error(ctx.data.message)
}
return ctx
}
}).json()
七、技术实现注意事项
- 缓存键设计:推荐使用
接口路径+参数哈希
的方式生成唯一标识 - 内存管理:对于大容量数据建议实现LRU缓存淘汰策略
- 错误边界:需要区分网络错误、超时错误和业务逻辑错误
- TypeScript支持:
interface Article {
id: number
title: string
content: string
}
// 声明响应类型
const { data } = useFetch<Article[]>('...').json()
八、方案优劣势分析
优点:
- 开发效率提升:开箱即用的重试/缓存机制
- 代码可维护性:集中化的请求配置管理
- 用户体验优化:无缝衔接的失败恢复机制
缺点:
- 内存缓存不适合大规模数据
- 嵌套请求处理能力有限
- 文件上传等特殊场景需要特殊处理
九、最佳实践建议
- 结合IndexedDB实现持久化缓存
- 为重要请求配置更高优先级
- 实现可视化的请求瀑布流监控
- 在导航离开时自动取消非必要请求
十、应用场景展望
此方案特别适合以下场景:
- 实时性要求不高的资讯类应用
- 电商平台的商品详情页面
- 移动端弱网环境下的列表展示
- 需要降低服务器压力的公共接口