Node.js 接口响应太慢,怎么优化性能?
我用 Node.js 写了个 API 接口,前端用 Vue 调用,但每次加载都要等好几秒,本地开发都卡。试过加缓存和减少数据库查询,还是没明显改善。
前端是这样调用的:
<template>
<div v-if="loading">加载中...</div>
<ul v-else>
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
</template>
<script>
export default {
data() { return { items: [], loading: true } },
async mounted() {
const res = await fetch('/api/data');
this.items = await res.json();
this.loading = false;
}
}
</script>
后端就是普通的 Express 路由,查 MongoDB 返回数据。有没有什么靠谱的优化方向?比如流式响应、集群部署,或者我代码哪里写得有问题?
先说几个最可能的原因:
1. MongoDB 查询没有索引
这个是大多数人忽略的。你想啊,如果你的数据量稍微大一点,每次查询都要全表扫描,那肯定慢。比如你按 name 查,就应该在 name 字段上加索引:
2. 返回了太多不必要的字段
很多人写查询是这样的:
改成这样:
3. N+1 查询问题
如果你查询的是关联数据,比如每个用户有个 posts 数组,然后你又循环查了一遍:
改成用 populate 或者聚合查询一次查出来:
4. MongoDB 连接池没配好
Express 默认的 MongoDB 连接可能没配连接池,高并发或者数据量大的时候就会卡:
5. 看一下你的后端代码大概长什么样
你可以先在接口里加点日志,看看是哪部分慢:
运行一下,看控制台哪个 time 最长,就知道瓶颈在哪了。
关于你提到的流式响应
流式响应其实不太适合 JSON API,因为你要返回完整的 JSON 结构,必须等数据全部准备好才能开始发送。流式更适合大文件下载那种场景。对于普通接口,优化数据库查询才是正路。
关于集群部署
这是最后的手段,而且前提是你把单机优化做到位了。如果单线程都慢,集群只会让问题更明显。先把上面几个检查一遍。
你现在可以在后端接口里加上 console.time 看看哪个环节慢,定位到问题再针对性解决。