AI搜索上线后网站变慢?一次生产环境提速实测记录
AI搜索 如何提高网站速度|生产环境实测
在过去一年里,越来越多企业站、内容站和工具型网站开始从“传统搜索”转向“AI搜索”:用户不再只输入关键词,而是直接提出自然语言问题,例如“适合跨境电商独立站的支付方案有哪些”“某款产品和竞品相比有什么优势”“帮我找一篇关于网站性能优化的实战文章”。
AI搜索带来的体验提升很明显,但它也引入了一个新的问题:网站速度变慢了。
传统站内搜索通常依赖数据库 LIKE 查询、Elasticsearch、Meilisearch 或 Algolia 等搜索服务,返回的是一组链接或结果列表。而AI搜索往往还会涉及向量检索、语义召回、重排序、上下文拼接、LLM生成回答、权限过滤、缓存命中判断等流程。任何一个环节处理不好,都会让页面加载时间明显增加,甚至出现首屏长时间空白、回答生成缓慢、接口超时等问题。
本文结合一个生产环境项目的实测经验,系统梳理:在接入AI搜索后,如何提高网站速度。文章会从性能指标、问题定位、架构优化、前端优化、后端优化、缓存策略、向量检索优化、LLM响应优化以及上线监控等角度展开。
一、生产环境背景说明
为了便于说明,先介绍本次优化的生产环境背景。
该网站是一个中文内容型网站,主要包含:
- 文章内容约 12 万篇;
- 日均访问量约 8 万 PV;
- 高峰期并发请求约 300~600;
- 用户可以使用站内普通搜索,也可以使用AI搜索;
- AI搜索支持自然语言提问,并基于网站内容生成答案;
- 后端主要使用 Node.js + PostgreSQL + Redis;
- 向量数据库使用 PostgreSQL pgvector;
- 前端使用 Next.js;
- LLM调用外部大模型API。
优化前,AI搜索接口的平均响应时间偏高。部分问题在高峰期甚至会出现 8~15 秒的等待时间,严重影响用户体验。
优化前关键指标
| 指标 | 优化前表现 |
|---|---|
| 首页 LCP | 3.8s |
| 搜索页首屏加载 | 2.9s |
| 普通搜索接口 P95 | 850ms |
| AI搜索接口平均响应 | 6.4s |
| AI搜索接口 P95 | 13.2s |
| AI回答首字输出时间 | 5.1s |
| Redis缓存命中率 | 28% |
| 向量检索平均耗时 | 1.7s |
| LLM调用平均耗时 | 3.8s |
可以看到,真正拖慢体验的并不只是页面加载,而是AI搜索完整链路太长。用户点击搜索后,需要等待很久才能看到AI回答,导致跳出率上升。
二、AI搜索为什么容易拖慢网站?
很多团队在接入AI搜索时,会低估它对网站性能的影响。原因在于,AI搜索不是一个单接口问题,而是一条复杂链路。
一个典型AI搜索流程如下:
- 用户输入问题;
- 前端发送请求到后端;
- 后端进行用户权限校验;
- 对问题进行清洗、改写或意图识别;
- 将问题转换为向量;
- 在向量库中做相似度检索;
- 根据关键词、时间、分类、权限等条件过滤结果;
- 对召回结果进行重排序;
- 拼接上下文;
- 调用大模型生成答案;
- 以流式或普通方式返回前端;
- 前端渲染答案、引用来源、推荐内容等。
其中任何一步过慢,都会影响最终体验。
尤其是以下几个环节最容易成为瓶颈:
- 向量检索没有索引;
- 每次请求都实时生成Embedding;
- 检索结果过多,重排序成本太高;
- 上下文拼接过长,导致LLM响应变慢;
- 没有流式输出,用户必须等完整答案;
- 缓存策略不合理,重复问题无法复用结果;
- 前端首屏资源过大,页面还没加载完接口已经等待;
- 后端请求串行执行,链路被无谓拉长。
三、先定义性能目标,而不是盲目优化
性能优化不能只凭感觉。生产环境优化的第一步,是定义清晰指标。
本次优化目标如下:
| 指标 | 目标 |
|---|---|
| AI搜索首字输出时间 | 小于 1.5s |
| AI搜索完整回答时间 | 小于 5s |
| AI搜索接口 P95 | 小于 6s |
| 搜索页 LCP | 小于 2.5s |
| 向量检索平均耗时 | 小于 300ms |
| Redis缓存命中率 | 大于 60% |
| 页面 JS 首包体积 | 降低 30%以上 |
这里重点说明一个指标:首字输出时间。
对于AI搜索来说,用户并不一定要求完整答案瞬间返回。如果能在 1~2 秒内看到回答开始生成,用户的等待感会明显降低。因此,优化AI搜索时,不应只关注“完整响应耗时”,还要关注“首字返回时间”。
四、前端优化:先让页面快起来
很多AI搜索项目一开始就把优化重点放在模型和后端上,但忽略了前端。实际上,如果搜索页本身加载慢,用户在输入问题之前就已经产生负面体验。
1. 拆分搜索页首屏资源
优化前,搜索页加载了大量非首屏组件,包括:
- 热门文章列表;
- 推荐专题;
- 历史搜索记录;
- 用户反馈组件;
- Markdown渲染器;
- 代码高亮库;
- 图表组件。
这些组件并不一定需要在首屏同步加载。
优化方式:
import dynamic from "next/dynamic";
const MarkdownRenderer = dynamic(() => import("@/components/MarkdownRenderer"), {
ssr: false,
loading: () => 正在加载回答组件...,
});
const FeedbackPanel = dynamic(() => import("@/components/FeedbackPanel"), {
ssr: false,
});
将非关键组件动态加载后,搜索页首屏JS体积明显下降。
2. 搜索框优先渲染
搜索页最重要的元素是搜索框。我们把搜索框、标题、简单说明作为首屏核心内容,其他模块延迟加载。
优化前页面结构大致是:
优化后调整为:
这样用户进入页面后可以更快开始搜索,而不是等待整页资源加载。
3. 减少阻塞渲染资源
对CSS、字体和第三方脚本进行检查后,发现一些统计脚本和客服脚本会阻塞页面加载。处理方式:
- 统计脚本延迟加载;
- 字体使用
font-display: swap; - 首屏图片使用压缩后的WebP;
- 非必要第三方SDK只在用户交互后加载;
- 减少全局CSS体积。
优化后,搜索页 LCP 从 2.9s 降到 1.9s,用户进入页面的速度明显提升。
五、后端优化:拆解AI搜索链路
前端优化只能解决页面体验的一部分。真正决定AI搜索速度的,是后端链路。
优化前,AI搜索接口是一个典型串行流程:
接收问题
↓
权限校验
↓
生成Embedding
↓
向量检索
↓
数据库查询文章详情
↓
结果重排序
↓
拼接Prompt
↓
调用LLM
↓
返回完整答案
问题在于:所有步骤都串行执行,且必须等LLM完整生成后才返回给用户。
优化后,我们将链路拆成两部分:
- 快速响应链路:尽快完成检索并开始流式输出;
- 异步增强链路:记录日志、更新搜索热度、用户行为分析、推荐内容计算等放到异步队列。
六、使用流式输出降低等待感
AI搜索最关键的优化之一,是使用流式输出。
优化前,后端等待LLM生成完整答案后才返回:
用户提问 → 后端处理 → LLM完整生成 → 一次性返回
这种方式下,用户可能等待 5~10 秒都看不到任何内容。
优化后,采用 Server-Sent Events 或 Stream Response:
用户提问 → 检索 → LLM开始生成 → 边生成边返回
示例代码:
export async function POST(req: Request) {
const { question } = await req.json();
const stream = new ReadableStream({
async start(controller) {
const encoder = new TextEncoder();
const contexts = await retrieveContexts(question);
const llmStream = await callLLMStream({
question,
contexts,
});
for await (const chunk of llmStream) {
controller.enqueue(encoder.encode(chunk));
}
controller.close();
},
});
return new Response(stream, {
headers: {
"Content-Type": "text/event-stream; charset=utf-8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
},
});
}
上线后,AI回答首字输出时间从 5.1s 降到 1.4s。虽然完整答案生成时间仍然需要几秒,但用户能立即看到内容开始输出,感知速度大幅提升。
七、缓存策略:不要让相似问题反复计算
AI搜索的成本和耗时都比较高。如果每个问题都从头走一遍完整链路,系统压力会很大。
我们采用了三层缓存。
1. 精确问题缓存
对用户原始问题进行标准化处理:
- 去除首尾空格;
- 统一标点;
- 繁简转换;
- 小写化;
- 去除无意义语气词。
例如:
“怎么提高网站速度?”
“如何提升网站速度”
“网站速度怎么优化?”
这些问题虽然文字不同,但意图相似。对于完全一致的问题,可以直接走精确缓存。
缓存Key示例:
const cacheKey = `ai_search:answer:${hash(normalizedQuestion)}`;
缓存内容包括:
- 最终答案;
- 引用文章;
- 推荐链接;
- 生成时间;
- 使用的模型版本。
2. 语义缓存
精确缓存只能命中完全相同的问题,而AI搜索中大量问题是语义相近但表达不同。因此我们引入语义缓存。
基本思路是:
- 将用户问题转换为向量;
- 在“历史问题向量库”中查找相似问题;
- 如果相似度高于阈值,例如 0.92;
- 直接返回历史答案,或者基于历史答案轻量改写。
这样可以避免大量重复调用LLM。
不过语义缓存要注意风险:相似问题不一定等价。比如:
- “苹果手机怎么提高速度”
- “苹果电脑怎么提高速度”
这两个问题有相似词,但答案不同。因此语义缓存不能只看相似度,还要结合意图分类和实体识别。
3. 检索结果缓存
除了最终答案,检索结果也可以缓存。比如某些热门问题,每次都需要查向量库和文章表,成本较高。我们将 Top K 文档ID缓存起来:
ai_search:retrieval:{question_hash} → [docId1, docId2, docId3]
这样即使不缓存最终答案,也可以减少检索耗时。
优化后,Redis缓存命中率从 28% 提升到 67%,AI搜索平均响应时间明显下降。
八、向量检索优化:从1.7秒降到260毫秒
本次生产环境中,向量检索一开始是最大的瓶颈之一。
1. 为向量字段建立索引
使用 pgvector 时,如果没有合理索引,数据量上来后查询会变慢。
优化前查询:
SELECT id, title, content
FROM articles
ORDER BY embedding <-> $1
LIMIT 10;
在 12 万篇文章数据下,该查询平均耗时约 1.7s。
优化后,为向量字段建立 HNSW 索引:
CREATE INDEX articles_embedding_hnsw_idx
ON articles
USING hnsw (embedding vector_cosine_ops);
如果使用 IVFFlat,也可以:
CREATE INDEX articles_embedding_ivfflat_idx
ON articles
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
对于读多写少的内容站,HNSW查询表现更稳定,适合生产使用。
2. 控制候选数量
很多团队为了“答案更准”,会把 Top K 设置得很大,比如一次召回 100 条甚至 200 条。实际上,候选越多,后续数据库查询、重排序、Prompt拼接都会更慢。
我们实测后发现:
| Top K | 检索耗时 | 答案质量 |
|---|---|---|
| 5 | 180ms | 偶尔信息不足 |
| 10 | 260ms | 较稳定 |
| 20 | 430ms | 略有提升 |
| 50 | 970ms | 提升不明显 |
最终生产环境选择默认 Top K = 10,复杂问题才动态提升到 20。
3. 文档切片要适中
AI搜索通常不是直接对整篇文章做向量化,而是对文章切片。切片太长会影响召回精度,切片太短会导致数量膨胀。
我们测试过三种方案:
| 切片长度 | 优点 | 缺点 |
|---|---|---|
| 300字 | 精细,召回准确 | 切片数量太多 |
| 800字 | 平衡较好 | 需要处理上下文衔接 |
| 1500字 | 数量少 | 召回不够精准 |
最终采用约 700~900 中文字的切片,并保留 100~150 字重叠内容。这样既能保证语义完整,也不会导致向量数量过大。
九、Prompt优化:上下文越长不代表答案越好
AI搜索还有一个常见误区:把尽可能多的内容塞给大模型。
结果是Prompt越来越长,模型响应越来越慢,费用也越来越高。
优化前,我们会把检索到的 10 篇文章摘要和部分正文全部拼接进Prompt,平均上下文长度超过 7000 tokens。LLM响应时间平均 3.8s。
优化后做了三点调整:
1. 只保留高相关片段
不再把整篇文章传给模型,而是只传与问题最相关的段落。
2. 对上下文进行压缩
对于较长内容,先用规则方式提取标题、摘要、核心段落,而不是原样传入。
示例结构:
资料1:
标题:网站速度优化实战
相关内容:介绍了图片压缩、缓存、CDN、数据库索引等方法。
来源:https://example.com/a
资料2:
标题:Next.js 性能优化
相关内容:介绍了动态导入、SSR缓存、边缘渲染等方案。
来源:https://example.com/b
3. 限制最大上下文长度
生产环境中设置了硬限制:普通问题上下文不超过 3000 tokens,复杂问题不超过 5000 tokens。
优化后,LLM平均调用耗时从 3.8s 降到 2.6s,同时答案质量没有明显下降。
十、并行处理:能同时做的不要串行做
优化前,后端很多步骤都是串行执行。例如:
- 记录搜索日志;
- 查询用户信息;
- 获取推荐问题;
- 查询热门文章;
- 写入搜索历史。
这些操作并不都依赖主链路结果。如果全部串行等待,就会拖慢AI搜索。
优化方式是将非核心任务异步化:
const answerPromise = generateAnswer(question);
queue.add("search_log", {
userId,
question,
createdAt: Date.now(),
});
queue.add("update_hot_keyword", {
question,
});
return streamAnswer(answerPromise);
核心原则是:用户当前必须看到的内容同步处理,不影响当前结果的任务全部异步处理。
经过调整,后端主链路减少了约 400~700ms 的无效等待。
十一、数据库查询优化:不要在AI链路里做重查询
AI搜索检索出文档ID后,通常还需要查询文章标题、URL、摘要、发布时间等信息。优化前我们直接查文章主表,并且有一些字段不必要:
SELECT *
FROM articles
WHERE id IN (...);
这会取出大量无关字段,比如正文、作者扩展信息、统计字段等。
优化后改为只查询必要字段:
SELECT id, title, slug, summary, published_at
FROM articles
WHERE id = ANY($1);
并为常用过滤条件加索引:
CREATE INDEX idx_articles_status_published
ON articles(status, published_at DESC);
同时,将文章基础信息写入Redis缓存:
article:meta:{id}
这样向量检索返回ID后,可以优先从缓存批量获取文章元数据,减少数据库压力。
十二、CDN与边缘缓存:静态资源必须离用户更近
AI搜索接口本身很难完全静态化,但页面资源、文章页、图片、CSS、JS都可以通过CDN优化。
本次优化中,我们做了以下处理:
- 所有图片走CDN;
- WebP/AVIF格式自动转换;
- 静态资源设置长期缓存;
- HTML页面根据业务设置短缓存;
- 热门文章页启用边缘缓存;
- 搜索页骨架屏和基础HTML尽量边缘返回。
静态资源缓存示例:
Cache-Control: public, max-age=31536000, immutable
对于内容页:
Cache-Control: public, s-maxage=600, stale-while-revalidate=86400
这样即使源站压力较高,用户访问文章页和搜索页基础内容时仍然能保持较快速度。
十三、生产环境实测结果
经过多轮优化后,生产环境指标变化如下:
| 指标 | 优化前 | 优化后 |
|---|---|---|
| 首页 LCP | 3.8s | 2.1s |
| 搜索页首屏加载 | 2.9s | 1.7s |
| 普通搜索接口 P95 | 850ms | 420ms |
| AI搜索接口平均响应 | 6.4s | 3.2s |
| AI搜索接口 P95 | 13.2s | 5.8s |
| AI回答首字输出时间 | 5.1s | 1.4s |
| Redis缓存命中率 | 28% | 67% |
| 向量检索平均耗时 | 1.7s | 260ms |
| LLM调用平均耗时 | 3.8s | 2.6s |
从结果看,最大的收益来自四个方面:
- 流式输出:显著降低用户等待感;
- 向量索引:大幅降低检索耗时;
- 缓存策略:减少重复计算;
- Prompt压缩:降低LLM响应时间和调用成本。
十四、上线后的监控不能省
性能优化不是一次性工作。AI搜索上线后,必须持续监控。
建议至少监控以下指标:
- AI搜索请求量;
- 平均响应时间;
- P90、P95、P99耗时;
- 首字输出时间;
- 向量检索耗时;
- Embedding生成耗时;
- LLM调用耗时;
- 缓存命中率;
- 错误率;
- 超时率;
- 用户中断率;
- 每次回答平均Token数;
- 单次请求平均成本。
尤其要关注 P95 和 P99,而不是只看平均值。平均值很好看,并不代表用户体验好。很多生产问题都藏在长尾请求里。
十五、最终建议:AI搜索提速的优先级
如果你的站点已经接入AI搜索,但速度不理想,可以按以下优先级优化:
- 先接入流式输出,让用户尽快看到回答;
- 检查向量库是否有索引,避免全表扫描;
- 减少Prompt上下文长度,不要盲目塞内容;
- 增加Redis缓存,优先缓存热门问题和检索结果;
- 前端搜索页拆包,保证搜索框快速可用;
- 异步化非核心任务,缩短主链路;
- 优化数据库查询字段和索引;
- 使用CDN缓存静态资源和热门页面;
- 建立监控面板,持续观察长尾性能;
- 根据问题复杂度动态调整检索和模型策略。
结语
AI搜索确实能提升网站体验,但如果没有做好性能优化,它也可能成为网站速度的最大瓶颈。生产环境中的优化经验表明,AI搜索提速并不只是“换一个更快的模型”这么简单,而是一个系统工程。
真正有效的优化,通常来自链路拆解:前端让页面先快起来,后端让主链路更短,向量检索加索引,缓存减少重复计算,Prompt减少无效上下文,LLM使用流式输出,非核心任务全部异步化。
从本次实测结果看,经过优化后,AI搜索接口 P95 从 13.2 秒降到 5.8 秒,首字输出时间从 5.1 秒降到 1.4 秒,用户等待感明显降低,搜索转化率和停留时间也随之提升。
如果你正在做AI搜索,建议不要等到用户反馈“太慢”之后再优化。性能设计应该从第一天就纳入架构方案。因为在AI搜索时代,网站速度不仅影响SEO和转化率,也直接影响用户是否愿意继续与你的网站对话。