Flutter动态渲染:如何做到高一致性、高性能?
2023-12-02 11:48:28
最近,我们小组尝试使用集团DinamicX的DSL,通过下发DSL模板实现Flutter端的动态化模板渲染。在解决了性能方面的问题后,又面临了一个新的挑战——渲染一致性。
如何在不降低渲染性能的前提下,大幅度提升Flutter与Native之间的渲染一致性呢?
思路
在初版渲染架构设计时,我们主要采用了Flutter自带的RenderObject
体系来实现DSL模板的渲染。RenderObject
体系虽然提供了强大的渲染能力,但同时也带来了两个问题:
- 渲染性能低。
RenderObject
体系的渲染过程非常复杂,涉及到大量的计算和布局操作,这使得渲染性能相对较低。 - 渲染不一致。由于Flutter与Native的渲染引擎不同,因此在某些情况下会出现渲染不一致的问题。例如,Flutter中使用
Text
组件渲染的文字在Native端可能会出现模糊或错位的情况。
为了解决这两个问题,我们对渲染架构进行了重新设计。我们将RenderObject
体系与Native的渲染引擎相结合,采用混合渲染的方式来实现DSL模板的渲染。
具体来说,我们将DSL模板划分为两部分:
- 静态部分。静态部分是指不会随着数据变化而改变的部分。例如,模板中的布局结构和样式。
- 动态部分。动态部分是指会随着数据变化而改变的部分。例如,模板中的数据内容。
静态部分采用RenderObject
体系来渲染,动态部分采用Native的渲染引擎来渲染。这样,既可以保证渲染性能,又可以保证渲染一致性。
实践
在实际项目中,我们使用了这种混合渲染的方式来实现DSL模板的渲染。结果表明,这种方式可以大幅度提升Flutter与Native之间的渲染一致性,同时也不会降低渲染性能。
例如,在我们的项目中,有一个页面需要展示一个列表。列表中的每一项都包含一个图片、一个标题和一个。图片和标题是静态部分,是动态部分。
使用RenderObject
体系渲染整个列表,渲染性能非常低。因为RenderObject
体系需要对列表中的每一项都进行计算和布局操作。
使用混合渲染的方式渲染列表,渲染性能大大提高。因为混合渲染的方式只对列表中的图片和标题进行计算和布局操作,而描述部分则直接由Native的渲染引擎来渲染。
此外,混合渲染的方式还可以保证渲染一致性。因为列表中的图片和标题是由Flutter的渲染引擎来渲染的,而描述部分是由Native的渲染引擎来渲染的。因此,Flutter与Native之间的渲染一致性得到了保证。
结论
Flutter动态渲染虽然有着诸多优势,但在实践中却往往面临着高一致性与高性能之间的两难选择。通过采用混合渲染的方式,我们可以同时兼顾高一致性和高性能,从而打造出更加出色的Flutter动态渲染应用。