缓存、并发、监控详解 | 从零基础到精通 | 包含前端、后端和数据库优化
性能直接影响用户体验、转化率和搜索排名。一个快速的应用能留住用户,一个慢的应用会让用户离开。
// 使用Performance API
const perfData = performance.getEntriesByType('navigation')[0];
console.log('DNS查询时间:', perfData.domainLookupEnd - perfData.domainLookupStart);
console.log('TCP连接时间:', perfData.connectEnd - perfData.connectStart);
console.log('请求时间:', perfData.responseStart - perfData.requestStart);
console.log('响应时间:', perfData.responseEnd - perfData.responseStart);
console.log('DOM解析时间:', perfData.domInteractive - perfData.domLoading);
console.log('总加载时间:', perfData.loadEventEnd - perfData.fetchStart);
// 测量自定义指标
performance.mark('start');
// ... 执行操作 ...
performance.mark('end');
performance.measure('operation', 'start', 'end');
const measure = performance.getEntriesByName('operation')[0];
console.log('操作耗时:', measure.duration);// 动态导入
const module = await import('./heavy-module.js');
// React代码分割
const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<HeavyComponent />
</Suspense>
);
}// 使用现代格式
<picture>
<source srcset="image.webp" type="image/webp">
<source srcset="image.jpg" type="image/jpeg">
<img src="image.jpg" alt="描述">
</picture>
// 响应式图片
<img
srcset="small.jpg 480w, medium.jpg 768w, large.jpg 1024w"
sizes="(max-width: 480px) 100vw, (max-width: 768px) 80vw, 1024px"
src="medium.jpg"
alt="描述"
>
// 懒加载
<img src="placeholder.jpg" loading="lazy" alt="描述">// 优化前:O(n²)
function findDuplicates(arr) {
const result = [];
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
result.push(arr[i]);
}
}
}
return result;
}
// 优化后:O(n)
function findDuplicates(arr) {
const seen = new Set();
const result = new Set();
for (const num of arr) {
if (seen.has(num)) {
result.add(num);
}
seen.add(num);
}
return Array.from(result);
}const mysql = require('mysql2/promise');
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'password',
database: 'myapp',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
// 使用连接池
const connection = await pool.getConnection();
const [rows] = await connection.query('SELECT * FROM users');
connection.release();// 使用消息队列处理耗时任务
const queue = require('bull');
const emailQueue = new queue('email');
// 添加任务到队列
app.post('/send-email', async (req, res) => {
await emailQueue.add({ email: req.body.email });
res.json({ success: true });
});
// 处理队列中的任务
emailQueue.process(async (job) => {
await sendEmail(job.data.email);
});-- 创建索引
CREATE INDEX idx_email ON users(email);
CREATE INDEX idx_user_status ON posts(user_id, status);
-- 查看查询计划
EXPLAIN SELECT * FROM users WHERE email = 'test@example.com';
-- 避免全表扫描
-- 不好:
SELECT * FROM users WHERE YEAR(created_at) = 2024;
-- 好:
SELECT * FROM users WHERE created_at >= '2024-01-01' AND created_at < '2025-01-01';-- 避免N+1查询
-- 不好:
const users = await User.find();
for (const user of users) {
user.posts = await Post.find({ user_id: user.id });
}
-- 好:
const users = await User.find().populate('posts');
-- 只查询需要的字段
SELECT id, name, email FROM users; // 比 SELECT * 更快
-- 使用LIMIT
SELECT * FROM users LIMIT 10;// 第1层:浏览器缓存
Cache-Control: public, max-age=3600
// 第2层:CDN缓存
Cache-Control: public, max-age=86400
// 第3层:应用缓存(Redis)
const redis = require('redis');
const client = redis.createClient();
app.get('/api/users/:id', async (req, res) => {
const cacheKey = `user:${req.params.id}`;
// 检查缓存
const cached = await client.get(cacheKey);
if (cached) {
return res.json(JSON.parse(cached));
}
// 从数据库获取
const user = await User.findById(req.params.id);
// 缓存1小时
await client.setEx(cacheKey, 3600, JSON.stringify(user));
res.json(user);
});
// 第4层:数据库查询缓存
-- 使用查询缓存
SET GLOBAL query_cache_size = 268435456;// Node.js使用事件驱动,天然支持高并发
// 但要避免阻塞事件循环
// 不好:同步操作
const data = fs.readFileSync('large-file.txt');
// 好:异步操作
const data = await fs.promises.readFile('large-file.txt');
// 使用Worker处理CPU密集任务
const { Worker } = require('worker_threads');
const worker = new Worker('./worker.js');
worker.on('message', (result) => {
console.log('Result:', result);
});// 限流
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分钟
max: 100 // 限制100个请求
});
app.use(limiter);
// 熔断
const CircuitBreaker = require('opossum');
const breaker = new CircuitBreaker(async () => {
return await externalService.call();
}, {
timeout: 3000,
errorThresholdPercentage: 50,
resetTimeout: 30000
});
breaker.fallback(() => {
return 'Service unavailable';
});// 使用APM工具
const apm = require('elastic-apm-node').start({
serviceName: 'my-app',
serverUrl: 'http://localhost:8200'
});
// 自定义指标
apm.captureError(error);
apm.startTransaction('request', 'http.request');
// 监控响应时间
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
console.log(`${req.method} ${req.path} - ${duration}ms`);
});
next();
});优化前:
- 首页加载时间:5.2s
- 首次内容绘制:3.1s
- 最大内容绘制:4.5s
- 数据库查询平均耗时:200ms
优化后:
- 首页加载时间:1.8s(提升65%)
- 首次内容绘制:0.8s(提升74%)
- 最大内容绘制:1.2s(提升73%)
- 数据库查询平均耗时:45ms(提升77%)
优化措施:
1. 启用HTTP/2和gzip压缩
2. 图片优化和CDN加速
3. 代码分割和懒加载
4. 数据库索引优化和缓存
5. 连接池和异步处理性能优化是一个系统工程,需要从多个方面综合考虑。持续监控和改进是关键。
现在你已经掌握了性能优化的核心知识。
性能优化没有银弹,需要根据实际情况选择合适的优化方案。持续测量、分析、改进是成功的关键。