=== 先测清楚瓶颈在哪 === 后端单点实测(都很快,不是问题所在): /logs/my-scope 10ms /logs/label/namespace/values 25ms /logs/label-values?scoped astralx 23ms /logs/label/app/values scoped 18ms 结论:慢的是**前端每次都重新走一遍请求链**(切数据源 / 切命名空间 / 重开面板 都会触发),三四次往返串起来 + 每次都有 loading 态,用户看到的就是转圈。 === 后端:label 候选值短缓存 === services/log_query.go:60 秒 TTL,key = sourceId|label|selector|时间窗(按 5 分钟取整), 上限 500 条并做过期清理。理由:下拉值的时效性要求很低—— 新上线的 app 晚 1 分钟出现在候选里完全可以接受。 LokiLabelValuesBatch 内部逐个走 LokiLabelValues,所以批量接口自动受益。 === 前端:内存缓存 + 飞行中请求合并 === api/logs/index.ts:60 秒 TTL 的 Map,**缓存 Promise 而不是结果**, 所以并发的相同请求共享同一次飞行(去重);失败立刻剔除缓存,避免缓存错误。 带 AbortSignal 的调用不参与缓存(用户主动取消的请求不应共享给别人)。 额外导出 invalidateLabelCache(),数据源变更时可手动清。 === 预期效果 === 首次打开:与之前相同(~100ms 量级) 再次切换 / 重开面板:直接命中内存,0 请求 服务端重复请求:25~40ms → 微秒级