赛博朋克 3D Banner 性能优化实录
2026年05月29日1 次阅读0 人喜欢
Three.js性能优化前端CyberpunkReactNext.js
问题背景
首页 CyberpunkBanner 加载后持续高负载渲染,Chrome Performance Trace 中出现大量 AnimationFrame / FireAnimationFrame / GPUTask / DroppedFrame,在 Intel MacBook Pro + Chrome 下明显掉帧。
根因分析
| 问题 | 组件 | 影响 |
|---|---|---|
| Bloom + Vignette + mipmapBlur 无条件挂载 | PostProcessing |
GPU 压力最大的部分 |
| 300 雨滴逐帧更新 + 随机漂移 | RainEffect |
CPU 每帧循环 300 次随机计算 |
| 8 个灯光每帧更新全部属性 | CyberpunkLights |
持续 rAF 负载 |
| dpr=[1, 1.5] + antialias:true | Canvas |
首屏持续动画下偏重 |
结论:首页应该从"持续运行的游戏场景"改成"博客首页展示场景"——流畅优先,增强效果按需开启。
解决方案:三级性能档位
新增 PerformanceTier = 'low' | 'medium' | 'high',自动检测分级:
typescript
// 判断依据
- navigator.hardwareConcurrency(CPU 核心数)
- navigator.deviceMemory(内存)
- prefers-reduced-motion(系统偏好)
- WebGL renderer 字符串(Intel UHD / Intel HD)
- 是否移动端
- URL 参数 ?perf=low|medium|high 强制覆盖
档位规则
| 档位 | 条件 | DPR | Bloom | 雨效 | 灯光呼吸 |
|---|---|---|---|---|---|
| high | 独显 + >=8GB + >=8核 | [1, 1.25] | intensity=0.7, mipmapBlur | 300 粒子 | 每帧更新 |
| medium | Intel 集显 / <=8GB / <=6核 | 1 | intensity=0.35, 无mipmap | 120 粒子 | 每100ms |
| low | 移动端 / <=4GB / <=4核 / reduced-motion | 1 | intensity=0(关闭) | 不渲染 | 关闭 |
具体改动
1. Canvas 配置
diff
- dpr={[1, 1.5]}
- gl={{ antialias: true, ... }}
+ dpr={performanceTier === 'high' ? [1, 1.25] : 1}
+ gl={{ antialias: true, ... }} // 所有档位保留抗锯齿
2. Bloom 后处理
- 整个
EffectComposer改为条件挂载:仅夜间 high 档位 + 首屏可见时开启 - low 档位:Bloom intensity = 0
- medium 档位:Bloom intensity = 0.35,无 mipmapBlur
- 白天模式默认关闭 Bloom
3. 雨效(RainEffect)
- 新增
count和enabledprops - 横向漂移每 3 帧计算一次(减少随机数开销)
enabled=false时跳过所有 useFrame 更新
4. 灯光动画(CyberpunkLights)
- 静态属性只设置一次:color/distance/decay/angle/penumbra 不再每帧赋值
- low 档位:关闭所有灯光呼吸动画
- medium 档位:每 100ms 更新一次 intensity
- high 档位:保持原有每帧呼吸效果
5. 滚动离开首屏后暂停
typescript
const isHeroVisible = scrollProgress < 1.05;
离开首屏后:
- 关闭 EffectComposer(Bloom)
- 关闭雨效
- 关闭灯光呼吸动画
6. 旧代码清理
- 删除
isLowEndDevice()函数(被detectPerformanceProfile替代) - 删除
lowEnd状态(被performanceProfile替代) prefersReducedMotion不再触发静态回退,而是降级为 low 档位(仍可看到 3D 场景)
7. 开发调试
console.table输出当前档位、DPR、各开关状态、GPU rendererRendererStatsLogger每 3 秒输出 renderer.info(calls/triangles/points)
涉及文件
| 文件 | 改动 |
|---|---|
CyberpunkBanner.tsx |
性能档位检测、Canvas 降级、PostProcessing 条件挂载、滚动暂停 |
CyberpunkLights.tsx |
静态属性首帧设置、动画降频、low 档关闭呼吸 |
RainEffect.tsx |
动态 count/enabled props、漂移降频 |
回滚方案
bash
git revert <commit-hash>
本次改动为独立 commit,所有变更集中在 3 个文件,可一键还原。
验收标准
- 首页默认打开明显更流畅
- Intel MacBook Pro + Chrome 不再严重掉帧
- 滚动离开首屏后 CPU/GPU 占用下降
- 赛博朋克视觉仍然保留
- 高性能设备仍可开启完整效果
- 低性能设备自动降级
- 不破坏热点、自由探索、昼夜主题、Debug 面板
- 所有档位保留抗锯齿(修复锯齿问题)