主题
APM 系统的标准分层架构(三大平面)
shell
┌─────────────────────────────────────────────────────────────┐
│ 展示层 (Presentation) │
│ Web Console / 告警平台 / API Gateway │
└─────────────────────────────────────────────────────────────┘
▲
│ 查询/聚合
┌─────────────────────────────────────────────────────────────┐
│ 数据存储与计算层 (Storage/Compute) │
│ 时序数据库(ES/TiDB) + 流计算引擎(Flink/Spark) + 索引服务 │
└─────────────────────────────────────────────────────────────┘
▲
│ 上报/推送
┌─────────────────────────────────────────────────────────────┐
│ 数据采集与传输层 (Collector/Agent) │
│ Agent探针(Java/Python/Node/浏览器SDK) → Kafka/RPC │
└─────────────────────────────────────────────────────────────┘
▲
│ 埋点/注入
┌─────────────────────────────────────────────────────────────┐
│ 目标应用系统 (Target System) │
│ 你的H5页面 → 后端微服务 → 数据库/缓存/第三方API │
└─────────────────────────────────────────────────────────────┘DOMContentLoaded async 脚本虽然不阻塞HTML解析,但会阻塞 DOMContentLoaded
内联样式块会阻塞 DOMContentLoaded 直到样式表解析完成
如果域名解析慢或不可用,会阻塞页面
上报性能数据
javascript
// 只有5%的用户上报性能数据
if (random() > 0.05) {
return; // 大部分用户不执行,性能影响为0
}
navigator.sendBeacon('/api/performance', JSON.stringify(data))合并小图片为雪碧图
css
/* 使用 CSS Sprite */
.sprite {
background-image: url('sprite.png');
background-repeat: no-repeat;
}
.sprite-close { background-position: 0 0; width: 20px; height: 20px; }
.sprite-delete { background-position: -25px 0; width: 20px; height: 20px; }
.sprite-mingxi { background-position: -50px 0; width: 20px; height: 20px; }监控指标
🟦 蓝色 (HTML) HTML文件 解析HTML文档的网络请求和解析时间。 xxxx.html 自身的加载和解析。
🟨 黄色 (Script) JavaScript 加载、解析和执行JS脚本的时间。这是优化的重点区域。 performance.js的加载与执行。 黄色块过长,说明监控脚本执行耗时多(你之前观察到的资源加载51ms就是黄色的部分)。
🟪 紫色 (Styles) CSS 解析CSS样式和计算样式(Recalculate Style)的时间。 页面内联样式和任何外部CSS的处理。
🟩 绿色 (Layout) 布局/渲染 计算页面元素几何位置(Layout / Reflow)的时间。 频繁的DOM操作会触发此过程,也是你代码中需要避免多次操作loading元素显示隐藏的原因。
🟥 红色 (Paint) 绘制 将像素绘制到屏幕上的时间。 首次绘制(FP)和首次内容绘制(FCP)。
⬜ 灰色 (System) 系统/空闲 浏览器系统本身的开销,或主线程处于空闲状态。 可能包含垃圾回收(GC)等操作。
⬛ 深灰 (Idle) 空闲 主线程没有任务在处理。 理想的空闲时段,适合用来安排requestIdleCallback()执行非关键任务。
使用 WebP 图片
html
<picture>
<source srcset="image.webp" type="image/webp">
<img src="image.png" alt="描述">
</picture>重点应该放在图片优化和缓存策略上,而不是网络层优化
添加缓存策略
javascript
// 在响应头中设置缓存
// 静态资源缓存 1 年
Cache-Control: public, max-age=31536000, immutable
// HTML 文件不缓存
Cache-Control: no-cache, no-store, must-revalidate监控实际用户加载时间
// 添加真实用户监控 (RUM)
javascript
window.addEventListener('load', () => {
const perfData = {
fcp: performance.getEntriesByType('paint')
.find(e => e.name === 'first-contentful-paint')?.startTime,
lcp: performance.getEntriesByType('largest-contentful-paint')[0]?.startTime,
ttfb: performance.getEntriesByType('navigation')[0]?.responseStart,
loadTime: performance.now()
}
console.log('用户加载数据:', perfData)
// 上报到监控系统
// navigator.sendBeacon('/api/performance/rum', JSON.stringify(perfData))
})