🔫一个页面1111个Ajax接口请求,还是人吗💀💣

前言

当你打开开发者工具,看到瀑布流里密密麻麻的接口请求时------血压是不是瞬间拉满?前端性能被拖垮、页面卡成PPT、用户疯狂流失...

正文

🚀 请求并发控制

1、并行请求队列

javascript 复制代码
// 请求队列类
class RequestQueue {
  constructor(maxConcurrent = 5) {
    this.maxConcurrent = maxConcurrent; // 设最大并发请求数为5
    this.queue = []; // 用于存储待处理的请求队列
    this.activeCount = 0; // 当前正在处理的请求数
  }
  
  add(requestFn, priority = 0) {
    return new Promise((resolve, reject) => {
      this.queue.push({ requestFn, resolve, reject, priority });
      this.queue.sort((a, b) => b.priority - a.priority); // 优先级排序
      this._next();
    });
  }

  _next() {
    while (this.activeCount < this.maxConcurrent && this.queue.length) {
      const { requestFn, resolve, reject } = this.queue.shift();
      this.activeCount++;
      
      requestFn()
        .then(resolve)
        .catch(reject)
        .finally(() => {
          this.activeCount--;
          this._next();
        });
    }
  }
}

// 使用示例
const apiQueue = new RequestQueue(5); // 最大并发5
apiQueue.add(() => fetch('/api/user'), 10); // 高优先级
apiQueue.add(() => fetch('/api/products'), 1); // 低优先级

优化要点

  • 可配置的并发数量(通常建议4-6个)
  • 基于优先级的请求调度
  • 自动队列管理,无需手动控制

2、智能权衡优先级

关键请求优先首屏 数据 > 次要 数据 > 后台预加载
依赖关系处理 :建立请求依赖图,确保顺序执行

🚀 缓存

1、内存

javascript 复制代码
const apiCache = new Map();

function cachedFetch(url, options = {}) {
  const { ttl = 60000 } = options; // 默认缓存1分钟
  const cacheKey = generateCacheKey(url, options);
  
  if (apiCache.has(cacheKey)) {
    const { data, timestamp } = apiCache.get(cacheKey);
    if (Date.now() - timestamp < ttl) {
      return Promise.resolve(data);
    }
  }
  
  return fetch(url, options)
    .then(res => res.json())
    .then(data => {
      apiCache.set(cacheKey, { data, timestamp: Date.now() });
      return data;
    });
}

function generateCacheKey(url, options) {
  return `${options.method || 'GET'}:${url}:${JSON.stringify(options.body)}`;
}

2、智能权衡缓存

IndexedDB持久化缓存

大容量数据存储

长期缓存解决方案

CDN边缘缓存

配置适当的Cache-Control头

对静态API响应启用CDN缓存

🚀 中间层(BFF)

1、nodejs来做(前端开发人员,有些公司是后端来搭中间层的,不过前端也可以搭,具体情况具体分析)。

bff(英文叫 backend for frontend,中文翻译:服务于前端的后端)。

前端用nodejs来写再合适不过了。

实话说这玩意就是,方便我们前端去自由地 优化性地 去组装后端接口返回来给我们的数据,可能后端有时候返回来的数据比较随心所欲,我们前端得到数据后就需要大量地大规模地进行各种组装,各种洗数据。

有时候,前端和后端,后端和前端之间的沟通导致口角扯皮等等导致效率降低,还不如前端自行地去决定数据的各种结构和形态。

所以出现了bff

ssr(服务端渲染),返回整个页面的html字符串,浏览器直接显示就好了,不用再经过js各种组装各种render等等,ssr它自己在服务器端直接就渲染好了,一次性打包给前端,可能说到这里,你很熟悉了,没错就是seo 首屏加载的优先选择方案

这里呢,如果是前端的小伙伴,要做bff,那么也就是说要做部分后端的工作了,推荐使用nodejs去做。nodejs 服务框架推荐用:expressKoaegg等等。自行去查看哈。

js 复制代码
客户端 → BFF → 微服务A
            → 微服务B
            → 微服务C

核心功能

接口聚合:合并多个微服务调用

数据转换:前端所需的数据格式处理

协议转换:GraphQL/RESTful适配

2、接口聚合

javascript 复制代码
// BFF路由示例
router.get('/user-dashboard', async (ctx) => {
  const [user, orders, messages] = await Promise.all([
    userService.getUser(ctx.userId),
    orderService.getRecentOrders(ctx.userId),
    messageService.getUnreadMessages(ctx.userId)
  ]);
  
  ctx.body = {
    user,
    lastOrders: orders.slice(0, 5),
    unreadCount: messages.length
  };
});

3、GraphQL配置

graphql 复制代码
query {
  user(id: "123") {
    name
    email
    posts(limit: 5) {
      title
      comments {
        count
      }
    }
  }
}

按需获取数据

减少网络往返

🚀 协议

1、HTTP/2

多路复用 :同域名下所有请求共享一个TCP连接
头部压缩 :减少重复头部传输
服务器推送:主动推送相关资源

2、域名分片

html 复制代码
<!-- 静态资源分片 -->
<img src="https://static1.example.com/image1.jpg">
<img src="https://static2.example.com/image2.jpg">

<!-- API端点分片 -->
<script>
  const API_ENDPOINTS = [
    'https://api1.example.com',
    'https://api2.example.com'
  ];
</script>

3、数据压缩

Brotli压缩:比gzip更高的压缩率

nginx 复制代码
# Nginx配置
brotli on;
brotli_types application/json;

图片等数据压缩: 图片转成data_url、js压缩(丑化处理)

总结

记住,没有放之四海皆准的完美方案,只有最适合当前业务场景的解决方案。

相关推荐
flash俊杰1 分钟前
Electron 桌面应用的进程模型:为什么 fork Next.js standalone
前端
沙蒿同学11 分钟前
我把架构约定编译成了会变红的测试:Wails v2 + Go + Vue3 桌面脚手架实战
前端·后端·github
cpolar技术支持14 分钟前
本地 Playwright 测试报告怎么远程复盘?Trace Viewer 跑起来后,用 cpolar 分享失败现场
前端·自动化测试·测试工具·cpolar·playwright
wordbaby14 分钟前
企业级后台管理系统路由设计与最佳实践指南
前端
胡志辉的博客23 分钟前
【完全开源】IP 纯净度检测 可一键部署到自己的CF
前端·javascript·chrome·ip·chromium
Hilaku1 小时前
作为面试官,我最怕遇到什么样的候选人?
前端·javascript·程序员
TiDi1 小时前
Pinia优化重复请求
前端
web3d5202 小时前
01-用 Leafletjs 10 分钟搭一张水利一张图(Vue3 + Vite 实战)
前端·javascript
晚安日记wanna2 小时前
Vue2 的 defineProperty 差在哪四层追问筛掉九成候选人
前端·vue.js·面试
TiDi2 小时前
吸顶导航交互实现
前端