鸿蒙Flutter实战:15-Flutter引擎Impeller鸿蒙化、性能优化与未来
Flutter 技术原理
Flutter 是一个主流的跨平台应用开发框架,基于 Dart 语言开发 UI 界面,它将描述界面的 Dart 代码直接编译成机器码,并使用渲染引擎调用 GPU/CPU 渲染。
渲染引擎的优势
使用自己的渲染引擎,这也是 Flutter 与其他跨平台框架最大的区别。
与 React Native 等高度依赖原生组件的框架不同,Flutter 摆脱了原生组件依赖,界面布局更加灵活,多端展示效果高度一致。由于渲染引擎自建,性能优化空间更大,这也是为什么Flutter 以流畅著称。
Impeller 渲染引擎由来
Flutter 的渲染引擎经历了多次迭代,早期全端使用 Skia, 后来为了解决 iOS 上着色器编译卡顿问题,Flutter 团队开发了新一代渲染引擎 Impeller。由于表现优异,Impeller 已经成为 Flutter 未来的发展方向。
渲染引擎将着色器编译成GPU指令,也就是二进制代码。
着色器是一种图形绘程序,它定义了如何绘制一个图形,比如颜色、形状、变换等。
Flutter在解决卡顿问题上,基于Skia做了多次努力和尝试,始终不尽人意,最终才有了Impeller。
Impeller 的设计目标包括: 消除首次卡顿、降低帧渲染驱动开销、利用现代 GPU 并行渲染能力
Impeller 与 Vulkan
Vulkan 是 OpenGL 推出的下一代图形 API,在安卓上,Flutter Impeller 调用 Vulkan 实现界面渲染。
- Impeller 实现了常用的着色器,支持参数化,通过预编译色器来避免编译卡顿问题
- 分层架构简化了渲染过程,每一层基于下层能力执行特定功能,高效且易用于维护更新
- 绘制命令容易聚合,易于拆分和并行
- 渲染设计与图形API解耦
Impeller 鸿蒙化
Impeller 的鸿蒙化基于 Vulkan, 通过 ArkUI 提供的 XComponent 组件承载 Flutter 视图。
与其他平台一样,通过 Method Channel , Dart 调用 ArkTS 来实现原生能力的调用。
XComponent 如何承载 Flutter 视图
通过 XComponet 获取到系统底层的 OHNativeWindow 实例, 这个就是鸿蒙的原生窗口,通过鸿蒙提供的扩展 VK_OHOS_surface, 将这个窗口转成一个 Vulkan 中的 VKSurface, 进而通过 VKSwapchain 实现了窗口绘制。
外接纹理:系统产生的图形图像如何嵌入 Flutter 显示
借助 XComponent,Flutter 绘制的界面可以显示在鸿蒙中。那么如果是非 Flutter 绘制的界面,如系统相机、视频等,如何嵌入到 Flutter 界面中呢?这就涉及到外接纹理了。
以相机为例,如果在 Flutter 中使用相机,当然最基础的可以通过 Method Channel 通信,将数据传递过来,但这个过程显然非常耗时,性能堪忧。另外一种方案是通过挖孔,叠加系统页面和 Flutter 画面,但这可能带来两套界面的操作、动画不一致问题。鸿蒙化采用了难度更高的数据导入方案,即将外部数据导入到 Flutter,将这些数据以纹理组件形式绘制。
鸿蒙化外接纹理涉及编码数据传输,如何解决性能问题
NativeBuffer 由鸿蒙提供, 通过它可以实现内存共享。那么外部导入的数据,通过 NativeBuffer,可以直接让 GPU 使用,避免了因数据拷贝造成的性能损失。
无论是 VKImage, 还是 GLTexture,都可以使用 NativeBuffer。
如何解决花屏问题
与安卓不同,Impeller 鸿蒙化方案采用了 GPU 硬件级的同步机制,保护数据读取,防止数据竞争,避免图像的花屏,通过 CPU 解耦,减少了空转时间,提高了性能。
Flutter 引擎侧不需要等待 Buffer 读写完成再调用绘制能力,只要保证 GPU 在绘制队列时,涉及 Buffer 数据的信号量状态为已读取即可,减少了 CPU 空等时间造成的性能损失。
渲染管线预加载
Impeller 通过预编译着色器避免了 Skia 中的运行时编译,但启动时需要加载这些着色器(也就是加载渲染管线),这就会出现明显的白屏时间。要解决这一问题,那就需要预加载渲染管线。
鸿蒙 Flutter 在运行时,首先创建 Dart 虚拟机解析 UI,在这个过程中同步进行渲染管线加载,从而实现首帧快速上屏,时延降低 50ms。
这部分不需要开发者操作,SDK 会自动完成。
混合开发加载优化:页面预加载
从原生 ArkUI 页面跳转到 Fluter 页面,需要先初始化 Flutter 引擎(这个过程耗时较长),再渲染首帧页面,这就会出现明显卡顿。
开发者可以提前手动调用 Flutter 引擎初始化 API,来解决这一卡顿问题。例如用户在触摸发生时,同步初始化 Flutter 引擎,等到用户抬手以后,就可以立即跳转到 Flutter 页面,整个过程会更加流程。
性能测试
通过预加载,可以节省一半的跳转时间。与 Skia 方案相比,Impeller 的转场流畅度提升显著。
与 Skia 方案相比,Impeller 方案在性能上表现更好。
鸿蒙 Flutter 的未来
鸿蒙 Flutter 适配团华为主导,计划每年推出 1-2 个比较大的版本,这两个大版本通过 fork 官方当时的主要版本来实现。至于能否将鸿蒙适配的部分合并到 Flutter 官方,还要看 Google 的态度。
结合前段时间 Flutter 社区版本 Flock 的推出,笔者持乐观态度。虽然 Google 在 Flutter 更新这方面进度缓慢,但社区版本带来不少想象力。多个 SDK 版本并存并不意味着分裂,竞争带来更多的活力。这点可以参考 Java,除了甲骨文主导的 OracleJDK, 还有 OpenJDK, AdoptOpenJDK 等十几种社区版本。
除了已有的插件开发方式,鸿蒙 Flutter 计划推出一种成本更低的方案,即通过一种统一接口描述,自动生成各端调用代码,省去开发者的编码工作。
总结
Flutter 作为一种流行的跨平台框架,支持鸿蒙是大势所趋。华为躬身入局,为 Flutter 社区带来了强劲动力。
从目前各方反馈来看,Flutter 应该是仅次于 ArkTs 的最佳适配方案。 不论是官方、还是开源社区、亦或是广大的开发者,都对 Flutter 有着强烈的诉求。 HarmonyOS 希望更多应用尽快适配鸿蒙,开发者或者是厂商,也希望以更低的成本最快上架;ArkTS 仍然有不少需要改进之处,就拿热重载一项与之对比,Flutter 不论从易用性、稳定性和成熟度已经遥遥领先。
对于平台独有的特性,如鸿蒙中的各种 Picker 组件、免权限按钮等,这与在其他平台上一样,是属于原生语言独有的优势所在。
虽然 Flutter 鸿蒙化已经初见成效,不少三方 Flutter 应用也快速适配上架,但生态建设仍需诸多时间,三方库还需要共建共享。
鸿蒙未来可期,Flutter 的鸿蒙化,为这个沉寂许久的框架,带来了新鲜血液。
参考资料
- Flutter lmpeller鸿蒙化实践 (第一期)
- Flutter 新一代图形渲染器 Impeller
- Understanding Impeller: A Deep Dive into Flutter’s Rendering Engine
- Flock
相关文章:

鸿蒙Flutter实战:15-Flutter引擎Impeller鸿蒙化、性能优化与未来
Flutter 技术原理 Flutter 是一个主流的跨平台应用开发框架,基于 Dart 语言开发 UI 界面,它将描述界面的 Dart 代码直接编译成机器码,并使用渲染引擎调用 GPU/CPU 渲染。 渲染引擎的优势 使用自己的渲染引擎,这也是 Flutter 与其…...
C语言冒泡排序教程简介
冒泡排序(Bubble Sort)是一种简单的排序算法,因其工作原理像气泡一样逐渐上浮而得名。其基本思想是通过一轮一轮地比较相邻的元素,将较大的元素逐步“冒泡”到数组的尾部。 在本篇博客中,我们将详细讲解冒泡排序的基本…...

Fabric链码部署测试
参考链接:运行 Fabric 应用程序 — Hyperledger Fabric Docs 主文档 (hyperledger-fabric.readthedocs.io) (2)fabric2.4.3部署运行自己的链码 - 知乎 (zhihu.com) Fabric2.0测试网络部署链码 - 辉哥哥~ - 博客园 (cnblogs.com) 1.启动测试…...

k620老显卡,装cuda.等。
CUDA安装教程(超详细)-CSDN博客 1.下载支持12.0以上的驱动 NVIDIA RTX Driver Release 550 R550 U12 (553.50) | Windows 11 解压。安装。一路下一步。查看结果 2.下载 cuda CUDA Toolkit Archive | NVIDIA Developer 安装cuda时,第一次…...

网站常用功能模块-鉴权
一:JWT是什么? 常用鉴权方式有很多种,今天主要介绍基于token的鉴权方式JWT(Json JSON Web Token)。因为这种方式实现起来方便快捷。整体实现逻辑如下 第一次登陆时,前端携带账号和密码请求登录接口。服务…...

直接插入排序、折半插入排序、2路插入排序、希尔排序
本篇是排序专栏博客的第一篇,主要探讨以 “插入” 为核心思想的排序算法该如何实现 文章目录 一、前言二、直接插入排序1. 算法思想与操作分析2. 代码实现version 1version 2 3. 复杂度分析 三、折半插入排序1. 算法思想与操作分析2. 代码实现3. 复杂度分析 四、2路…...
FQ-GAN代码解析
主要看 model 、loss 和 data 部分如何实现和处理的。 model—VQ_modelsVQModelEncoderVectorQuantizerDecoder loss—VQLoss_triple_codebook model—VQ_models 创建vq_model直接根据传入的模型压缩倍率8/16初始化对应的VQ_8/VQ_16,两者都是初始化一个VQModel的类…...

如何恢复已删除的 Telegram 消息 [iOSamp;Android]
Telegram 是一款功能强大的消息应用程序,因其易用性、隐私保护和众多炫酷功能而深受用户喜爱。然而,有时我们会不小心删除重要的消息。在这种情况下你应该做什么? 本文将为您提供简单有效的解决方案来恢复 Telegram 上已删除的消息ÿ…...
asp.net core中的 Cookie 和 Session
在 Web 开发中,用户会话管理是非常重要的,尤其是在需要保持用户状态和身份验证的应用中。ASP.NET Core 提供了多种状态管理技术,如 Cookie 和 Session,它们可以帮助你管理用户会话、存储数据并实现用户身份验证等功能。下面将详细…...
Python实现一个简单的 HTTP echo 服务器
一个用来做测试的简单的 HTTP echo 服务器。 from http.server import HTTPServer, BaseHTTPRequestHandler import jsonclass EchoHandler(BaseHTTPRequestHandler):def do_GET(self):# 构造响应数据response_data {path: self.path,method: GET,headers: dict(self.headers…...
Ruby 中文编码
Ruby 中文编码 在 Ruby 编程语言中处理中文编码是一个常见的需求,尤其是在中国和其他使用中文的地区。Ruby 是一种动态、开放源代码的编程语言,它支持多种字符编码,包括中文编码。本文将探讨在 Ruby 中处理中文编码的几种方法,以…...

淘金优化算法的信息共享与更新机制改进
淘金优化算法作为一种模拟自然界淘金过程的启发式搜索算法,在解决复杂优化问题时展现出独特优势。然而,其性能在很大程度上依赖于信息共享与更新机制的有效性。传统机制在面对高维、多模态等复杂问题时,往往存在信息交流不畅、更新滞后等问题,导致算法陷入局部最优或收敛速…...
Python中的ast.literal_eval:安全地解析字符串为Python对象
Python中的ast.literal_eval:安全地解析字符串为Python对象 什么是ast.literal_eval?为什么说它是“安全”的? 如何使用ast.literal_eval?示例1:将字符串转换为列表示例2:将字符串转换为字典示例3ÿ…...

【AI数学基础】线性代数:内积和范数
(观前提醒,这是工科AI相关的数学基础的学习笔记,不是数学专业的文章,所以没有严谨的证明和定义,数院大神请勿批评) 2. 内积和范数 2.1 内积的定义 从代数的角度来说,内积是两个向量之间的一种…...
Go语言的 的泛型(Generics)核心知识
Go语言的泛型(Generics)核心知识 引言 在编程语言的发展历程中,泛型是一项重要的特性。它使得程序员能够编写更加灵活和可重用的代码,减少了代码重复,提高了类型安全性和性能。从最初的C和Java,到现代的R…...

C++vector
1. vector 的介绍及使用 1.1vector的介绍 vector的文档介绍 1.vector是表示可变大小数组的序列容器 2.就像数组一样,vector也采用的连续存储空间来存储元素,也就是意味着可以采用下标对vector 的元素进行访问,和数组一样高效但是又不像数组…...

如何配置【Docker镜像】加速器+【Docker镜像】的使用
一、配置Docker镜像加速器 1. 安装/升级容器引擎客户端 推荐安装1.11.2以上版本的容器引擎客户端 2. 配置镜像加速器 针对容器引擎客户端版本大于1.11.2的用户 以root用户登录容器引擎所在的虚拟机 修改 "/etc/docker/daemon.json" 文件(如果没有…...
Docker--Docker Network(网络)
Docker Network(网络)是Docker容器之间和容器与外部网络之间的通信和连接的一种机制。以下是对Docker Network的详细解释: 一、Docker网络的重要性 Docker容器网络是为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作…...
Vue项目中生成node_modules文件夹的两种常用方法及npm优势
在Vue项目中生成node_modules文件夹的过程非常简单,主要步骤如下: 1、使用 npm 安装依赖包; 2、使用 yarn 安装依赖包。其中,推荐使用npm安装依赖包,原因如下: 兼容性更广:npm是Node.js的默认包管理工具,具有更高的兼容性。社区支持:npm拥有更大的用户基础和社区支持,…...

如何在 Ubuntu 22.04 上安装 Cassandra NoSQL 数据库教程
简介 本教程将向你介绍如何在 Ubuntu 22.04 上安装 Cassandra NoSQL 数据库。 Apache Cassandra 是一个分布式的 NoSQL 数据库,旨在处理跨多个普通服务器的大量数据,并提供高可用性,没有单点故障。Apache Cassandra 是一个高度可扩展的分布…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...

回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...

Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...