5.3 KiB
5.3 KiB
串行加载 vs 并行加载对比
📊 旧逻辑(并行加载)
时间轴:
0s ┌──────┐
│loadAd│ 启动
└──┬───┘
├─────────┐
1s │ 加载 A │
├─────────┤
2s │ 加载 B │ (同时进行)
├─────────┤
3s │ 加载 C │
└─────────┘
4s ┌──────┐
│start │ 启动定时器
└──┬───┘
│
5s ├→ 检查是否有可展示的广告
6s ├→ 检查
7s ├→ 检查
8s ├→ 检查(找到 A,ecpm 满足)
├→ 展示 A ✓
问题:
❌ 浪费:B 和 C 也加载了但可能用不上
❌ 等待:4-8秒才检查到可以展示
❌ 频率限制:3个广告同时请求
🎯 新逻辑(串行加载)
时间轴:
0s ┌──────┐
│loadAd│ 启动
└──┬───┘
│
0.5s ├─────────┐
│ 加载 A │
└─────────┘
1.5s ↓ 成功!ecpm 满足
├→ 立即展示 A ✓
优势:
✓ 节省:只加载了 A
✓ 快速:1.5秒就展示
✓ 成功率高:单个请求不触发频率限制
如果 A 失败的情况:
0.5s ├─────────┐
│ 加载 A │
└─────────┘
1.5s ↓ 失败 ✗
1.6s ├─────────┐
│ 加载 B │
└─────────┘
2.6s ↓ 成功!
├→ 立即展示 B ✓
📈 性能对比
| 指标 | 旧逻辑 | 新逻辑 | 改进 |
|---|---|---|---|
| 最快展示时间 | ~8秒 | ~1.5秒 | 5倍提速 |
| 平均流量消耗 | 3个广告 | 1-2个广告 | 节省50%+ |
| SDK请求次数 | 3次 | 1-3次 | 按需请求 |
| CPU占用 | 定时器持续轮询 | 事件驱动 | 更低 |
| 成功率 | 受频率限制影响 | 避免频率限制 | 更高 |
🔄 真实场景模拟
场景A: 第一个就成功(最常见)
旧逻辑:
0s: 加载 A、B、C(同时)
5s: A完成(✓), B完成(✓), C完成(✓)
8s: 定时器检查 → 展示A
总耗时: 8秒
浪费: B和C的流量
新逻辑:
0s: 加载 A
1.5s: A完成(✓) → 立即展示A
总耗时: 1.5秒
浪费: 0
场景B: 第一个失败,第二个成功
旧逻辑:
0s: 加载 A、B、C(同时)
5s: A失败(✗), B完成(✓), C完成(✓)
8s: 定时器检查 → 跳过A → 展示B
总耗时: 8秒
浪费: C的流量
新逻辑:
0s: 加载 A
1.5s: A失败(✗) → 立即加载B
3s: B完成(✓) → 立即展示B
总耗时: 3秒
浪费: 0
场景C: ecpm不足需要多个
旧逻辑:
0s: 加载 A、B、C(同时)
5s: A(ecpm低), B(ecpm低), C(ecpm高)
8s: 定时器检查 → 跳过A,B → 展示C
总耗时: 8秒
新逻辑:
0s: 加载 A
1.5s: A完成但ecpm低 → 立即加载B
3s: B完成但ecpm低 → 立即加载C
4.5s: C完成ecpm高 → 立即展示C
总耗时: 4.5秒
💰 成本节省(每天10000次展示)
流量成本
旧逻辑:
每次展示加载: 3个广告
每个广告请求: ~50KB
每天: 10000 × 3 × 50KB = 1.43GB
新逻辑:
成功率80%,平均1.2个广告
每天: 10000 × 1.2 × 50KB = 0.57GB
节省: 0.86GB (60%)
SDK请求配额
很多 SDK 有每日请求限制,新逻辑可以:
- 减少请求次数
- 延长配额使用时间
- 避免触发频率限制
📱 用户体验对比
| 用户场景 | 旧逻辑 | 新逻辑 |
|---|---|---|
| 打开应用到看到广告 | 8-10秒 | 1.5-3秒 |
| 等待时的体验 | 长时间空白 | 快速响应 |
| 流量消耗感知 | 高(后台偷跑流量) | 低(按需加载) |
| 应用流畅度 | 卡顿(同时3个请求) | 流畅(单个请求) |
🎯 最佳实践建议
1. 广告位优先级排序
// 按 ecpm 历史数据排序
var adids = config.allAdIds.sorted {
getHistoryEcpm($0) > getHistoryEcpm($1)
}
2. 添加超时机制
// 单个广告加载超时
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
if self.isLoadingAd && self.currentLoadingAdId == adId {
self.loadNextAd() // 超时,加载下一个
}
}
3. 智能重试
// 网络错误可以重试,其他错误跳过
if error.code == .networkError {
retry(adId)
} else {
loadNextAd()
}
✅ 迁移检查清单
- 修改
add(adId:)方法,不立即加载 - 添加队列管理逻辑
- 实现
loadNextAd()方法 - 实现
autoShowLoadedAd()方法 - 修改状态回调处理
- 移除定时器依赖
- 保持 API 兼容性
- 添加详细日志
- 测试各种场景
🚀 预期结果
重新编译运行后,你会看到:
✅ 日志更清晰:
"开始加载广告 [1/3]: A"
"开始加载广告 [2/3]: B"
✅ 展示更快速:
1-3秒内展示(vs 之前的8秒)
✅ 流量更节省:
平均只加载1.2个广告(vs 之前的3个)
✅ 成功率更高:
避免频率限制,自动尝试下一个
总结: 新的串行加载逻辑在速度、成本、成功率上都有显著提升!🎉