🔫一个页面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压缩(丑化处理)

总结

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

相关推荐
粥里有勺糖19 分钟前
视野修炼-技术周刊第122期 | 发光图片制作
前端·javascript·github
Carlos_sam1 小时前
OpenLayers:封装Tooltip
前端·javascript
工呈士1 小时前
MobX与响应式编程实践
前端·react.js·面试
嘉小华1 小时前
Android Lifecycle 使用
前端
Sherry0071 小时前
实时数据传输协议:WebSocket vs MQTT
前端·websocket
然我1 小时前
JavaScript的OOP独特之道:从原型继承到class语法
前端·javascript·html
腹黑天蝎座1 小时前
如何更好的实现业务中图片批量上传需求
前端
嘉小华1 小时前
Android Lifecycle 源码解析
前端
不_喜1 小时前
游戏开发零散知识点和优化记录
前端
去伪存真1 小时前
提交规范靠吼没用,看我用“shell+husky螺丝刀”,一键给40多个项目上锁
前端·eslint