移动端性能优化实战:CosmicInterestsSection 全面瘦身(第一期)

Today
1 min read
1,926 views
189 likes
Category
Beginner
#Web 性能#GSAP#ScrollTrigger#Canvas#Next.js#移动端优化

背景

首页的 CosmicInterestsSection 拥有较多的视觉元素与滚动剧情:

  • 海浪式卡片动画(WaveCardsEffect
  • 巨幅无缝滚动标题(INTERESTS
  • 多阶段滚动叙事(覆盖→横滑→幕布→涟漪→博客)
  • 门户挖洞与环形光效(PortalOverlay,Canvas 2D)
  • 博客转场与粒子(RippleBlogSection

在移动端,这些效果叠加会带来较明显的掉帧与滚动“漂浮感”。本文记录一次“可牺牲美观换性能”的实战优化,目标是在移动端做到“稳、顺、轻”。

痛点定位

  • 无缝滚动大字使用 GSAP ticker 与滚轮 Observer 双通道推进,常驻主线程并频繁触发样式更新。
  • onUpdate 中多处 setState 在每帧触发,导致 React 重渲染过于频繁。
  • PortalOverlay 每帧 RAF 重绘 Canvas(波形 + 星点 + 渐变),移动端成本高。
  • ScrollTrigger 区间过长、pinType: fixed 与 backdrop-blur 容易导致合成压力。

优化策略(移动端)

  • 禁用 GSAP ticker 与 Observer,将 INTERESTS 文本改为 CSS @keyframes 单向慢速。
  • 移动端不使用 backdrop-blur
  • 调整 ScrollTrigger:pinType: transform,缩短 end,降低 scrub
  • 简化滚动阶段:保留“覆盖→简介→博客”,跳过“横滑兴趣卡片”和“涟漪衔接”。
  • 降级 PortalOverlay:不绘制环形光效(ring),减少/移除 sparkles,必要时仅在进度变化时绘制。
  • 保持兴趣卡片数量不变(按产品要求),但避免在移动端横滑与复杂交互。

取舍说明(美观 vs 性能)

  • 放弃文字和横滑的强联动与方向反转,改为稳定的 CSS 缓慢滚动或静态显示。
  • PortalOverlay 光效弱化或关闭,保留主题感但减少 GPU/CPU 占用。
  • 滚动剧情缩短,减少状态切换与复合层抖动。

第一轮落地改动

  • .text-seamless-scroll(移动端)改为 CSS @keyframes 单向慢速动画;禁用 GSAP ticker 与 Observer。
  • 移除移动端的 backdrop-blur
  • 调整 ScrollTrigger(移动端):pinType: transform、缩短 end、降低 scrub
  • 简化移动端阶段:覆盖→简介→博客,跳过横向滑动与涟漪。
  • 降级 PortalOverlay(移动端):ringEnabled={false}sparkles=0、降低波形参数。

桌面端效果不变;仅对移动端进行降级,以稳定滚动与提升帧率。

基准与验证

  • 使用现有 useMobilePerformance() 作为移动端识别与分级入口。
  • DevTools Performance/Rendering 检查:JS 执行、样式计算与合成层减少。
  • 观察 rAF 与 GC 峰值下降、掉帧片段减少。

后续计划(分期)

  • 第二期:按性能分级延迟挂载 RippleBlogSection 的 R3F 粒子(低端设备不挂载)。
  • 第三期:将 onUpdate 的多处 setState 统一做帧合并/阈值更新。
  • 第四期:对 PortalOverlay 进一步做“进度驱动渲染”与采样步长自适应。

进度打卡

  • [x] 第一轮(本文):移动端文本 CSS 化 + 关闭 ticker/observer + ScrollTrigger/Overlay 降级 + 简化阶段。
  • [ ] 第二轮:粒子延迟挂载与分级计数。
  • [ ] 第三轮:setState 帧合并与阈值更新。
  • [ ] 第四轮:PortalOverlay 渲染自适应。

如需还原完整视觉,可为高性能设备保留原效果;本文的降级策略是“按需启用”的移动端 fallback。

CleanLove

Written by CleanLove

Full-stack developer passionate about modern web technologies

Initializing application
Loading page content, please wait...