Flutter导航过渡时复用Canvas绘制背景组件并避免重绘/冗余GPU计算的可行性问询
Flutter导航过渡时复用Canvas绘制背景组件并避免重绘/冗余GPU计算的可行性问询
各位好,我现在碰到一个Flutter性能优化的棘手问题,想请教下有没有可行的解决思路:
我做的App里每个页面都套着同一个固定结构的Scaffold,代码大概是这样的:
Scaffold( backgroundColor: Colors.red, // 这里必须用实色(比如白/黑),完全不能有透明 body: Stack( alignment: Alignment.center, children: [ // 这个BackgroundImage是固定不变的,每个页面都用它 const Positioned.fill(child: BackgroundImage()), // 只有这个child会随不同页面变化 Positioned.fill(child: child), // 桌面端专属的顶部按钮栏,也是固定的 if (Platform.isWindows || Platform.isMacOS) const Positioned( child: AppBarButtons(), top: 0.0, right: 0.0, left: 0.0, ), ], ), );
而这个BackgroundImage内部是用CustomPaint基于Canvas绘制的,里面涉及到shader和ui.Image的渲染,开销不小:
CustomPaint( // 我已经开了isComplex标记想让它缓存,但导航过渡时还是会重绘 isComplex: true, painter: FadeGradientPainter( shader: program, image: instance.dartUiImage, opacityLevel: opacityLevel, fit: BoxFit.cover, flip: instance.isFlipped, borderRadius: Corners.p12.windowScaled, ), size: Size(size.width, size.height), ),
现在的核心矛盾点:
- Scaffold必须用完全不透明的实色背景,所以我没办法把
BackgroundImage抽出来放到Navigator外面的全局Stack里 - 这个背景还得跟着页面的Scale+Fade导航过渡动画一起动,这也是它不能脱离当前页面上下文的另一个原因
我现在的诉求是:能不能通过GlobalKey或者其他什么技术手段,把这个BackgroundImage组件从旧页面的Widget树里“转移”到新页面的树结构中,避免每次导航都重新计算shader、重新绘制,减少不必要的GPU开销?毕竟每次都重复做同样的shader应用工作,实在太浪费性能了。
内容来源于stack exchange
相关产品推荐
相关产品推荐

