性能优化 #
性能指标 #
关键指标 #
| 指标 | 目标值 | 说明 |
|---|---|---|
| 响应时间 | < 50ms | 搜索响应时间 |
| 无结果率 | < 5% | 无结果搜索比例 |
| 点击率 | > 30% | 搜索结果点击率 |
| 首屏时间 | < 1s | 页面首次渲染时间 |
索引优化 #
减少记录大小 #
javascript
// ❌ 避免:存储大量不必要数据
{
"objectID": "1",
"name": "Product",
"fullDescription": "很长的描述...", // 不需要全文
"internalNotes": "...", // 内部数据
"auditLog": [...] // 日志数据
}
// ✅ 推荐:只存储必要数据
{
"objectID": "1",
"name": "Product",
"description": "简短描述",
"price": 999
}
优化可搜索属性 #
javascript
// ✅ 限制可搜索属性数量
searchableAttributes: [
'name',
'brand',
'category'
]
// ✅ 使用unordered取消位置权重
searchableAttributes: [
'name',
'unordered(description)'
]
使用filterOnly #
javascript
// 不需要分面统计的字段
attributesForFaceting: [
'brand',
'category',
'filterOnly(user_id)', // 仅筛选
'filterOnly(internal_id)' // 仅筛选
]
查询优化 #
限制返回字段 #
javascript
// ✅ 只返回需要的字段
const results = await index.search('iphone', {
attributesToRetrieve: ['name', 'price', 'image']
});
合理分页 #
javascript
// ✅ 合理的每页数量
hitsPerPage: 20
// ❌ 避免过大
hitsPerPage: 100
使用offset替代page #
javascript
// 对于深度分页,使用offset
const results = await index.search('iphone', {
offset: 1000,
length: 20
});
前端优化 #
防抖处理 #
javascript
let debounceTimer;
input.addEventListener('input', (e) => {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
search(e.target.value);
}, 300);
});
结果缓存 #
javascript
const cache = new Map();
async function cachedSearch(query) {
if (cache.has(query)) {
return cache.get(query);
}
const results = await index.search(query);
cache.set(query, results);
return results;
}
预取热门搜索 #
javascript
// 应用启动时预取热门搜索
async function prefetchPopular() {
const popular = ['iphone', 'samsung', 'laptop'];
await Promise.all(
popular.map(q => index.search(q, { hitsPerPage: 5 }))
);
}
网络优化 #
使用CDN #
javascript
// 配置最近的数据中心
const client = algoliasearch('APP_ID', 'API_KEY', {
hosts: {
read: ['app-id-dsn.algolia.net'],
write: ['app-id.algolia.net']
}
});
批量请求 #
javascript
// ✅ 使用multipleQueries
const { results } = await client.multipleQueries([
{ indexName: 'products', query: 'iphone' },
{ indexName: 'articles', query: 'iphone' }
]);
// ❌ 避免多次单独请求
const products = await index1.search('iphone');
const articles = await index2.search('iphone');
缓存策略 #
浏览器缓存 #
javascript
// 使用localStorage缓存
function getCachedResults(query) {
const key = `search_${query}`;
const cached = localStorage.getItem(key);
if (cached) {
const { data, timestamp } = JSON.parse(cached);
if (Date.now() - timestamp < 5 * 60 * 1000) { // 5分钟有效
return data;
}
}
return null;
}
function setCachedResults(query, data) {
const key = `search_${query}`;
localStorage.setItem(key, JSON.stringify({
data,
timestamp: Date.now()
}));
}
服务端缓存 #
javascript
// Node.js使用内存缓存
const NodeCache = require('node-cache');
const cache = new NodeCache({ stdTTL: 300 }); // 5分钟
async function searchWithCache(query) {
const cached = cache.get(query);
if (cached) return cached;
const results = await index.search(query);
cache.set(query, results);
return results;
}
监控与告警 #
性能监控 #
javascript
async function monitoredSearch(query) {
const start = Date.now();
try {
const results = await index.search(query);
const duration = Date.now() - start;
// 记录性能数据
logPerformance({
query,
duration,
hits: results.nbHits
});
return results;
} catch (error) {
logError(error);
throw error;
}
}
告警设置 #
javascript
// 设置性能告警阈值
const THRESHOLDS = {
responseTime: 100, // ms
noResultRate: 0.05, // 5%
errorRate: 0.01 // 1%
};
function checkAlerts(metrics) {
if (metrics.avgResponseTime > THRESHOLDS.responseTime) {
sendAlert('响应时间过长');
}
if (metrics.noResultRate > THRESHOLDS.noResultRate) {
sendAlert('无结果率过高');
}
}
性能检查清单 #
- [ ] 记录大小 < 10KB
- [ ] 可搜索属性 < 10个
- [ ] 每页结果 < 50条
- [ ] 使用filterOnly优化分面
- [ ] 前端实现防抖
- [ ] 实现结果缓存
- [ ] 使用批量请求
- [ ] 配置监控告警
总结 #
性能优化要点:
| 要点 | 说明 |
|---|---|
| 索引优化 | 减少记录大小、优化属性 |
| 查询优化 | 限制字段、合理分页 |
| 前端优化 | 防抖、缓存、预取 |
| 网络优化 | CDN、批量请求 |
| 监控 | 性能监控、告警 |
接下来,让我们学习 安全配置。
最后更新:2026-03-28