鸿蒙Flutter实战:15-Flutter引擎Impeller鸿蒙化、性能优化与未来

news2025/1/7 16:29:40

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 实现界面渲染。

  1. Impeller 实现了常用的着色器,支持参数化,通过预编译色器来避免编译卡顿问题
  2. 分层架构简化了渲染过程,每一层基于下层能力执行特定功能,高效且易用于维护更新
  3. 绘制命令容易聚合,易于拆分和并行
  4. 渲染设计与图形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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2271959.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UniApp | 从入门到精通:开启全平台开发的大门

UniApp | 从入门到精通:开启全平台开发的大门 一、前言二、Uniapp 基础入门2.1 什么是 Uniapp2.2 开发环境搭建三、Uniapp 核心语法与组件3.1 模板语法3.2 组件使用四、页面路由与导航4.1 路由配置4.2 导航方法五、数据请求与处理5.1 发起请求5.2 数据缓存六、样式与布局6.1 样…

法拉利F80发布 360万欧元限量799辆 25年Q4交付

今日,法拉利旗下全新超级跑车——F80正式发布,新车将作为法拉利GTO和法拉利LaFerrari(参数丨图片) Aterta的继任者,搭载V6混合动力系统,最大综合输出功率高达1632马力。售价360万欧元,全球限量生…

【pytorch练习】使用pytorch神经网络架构拟合余弦曲线

在本篇博客中,我们将通过一个简单的例子,讲解如何使用 PyTorch 实现一个神经网络模型来拟合余弦函数。本文将详细分析每个步骤,从数据准备到模型的训练与评估,帮助大家更好地理解如何使用 PyTorch 进行模型构建和训练。 一、背景 …

电脑steam api dll缺失了怎么办?

电脑故障解析与自救指南:Steam API DLL缺失问题的全面解析 在软件开发与电脑维护的广阔天地里,我们时常会遇到各种各样的系统报错与文件问题,其中“Steam API DLL缺失”便是让不少游戏爱好者和游戏开发者头疼的难题之一。作为一名深耕软件开…

Conda 安装 Jupyter Notebook

文章目录 1. 安装 Conda下载与安装步骤: 2. 创建虚拟环境3. 安装 Jupyter Notebook4. 启动 Jupyter Notebook5. 安装扩展功能(可选)6. 更新与维护7. 总结 Jupyter Notebook 是一款非常流行的交互式开发工具,尤其适合数据科学、机器…

组合的能力

在《德鲁克最后的忠告》一书中,有这样一段话: 企业将由各种积木组建而成:人员、产品、理念和建筑。积木的设计组合至少和其供给一样重要。……对于一切程序、应用软件以及附件来说,重要的是掌握将已有的软件模块组合的能力&…

去掉el-table中自带的边框线

1.问题:el-table中自带的边框线 2.解决后的效果: 3.分析:明明在el-table中没有添加border,但是会出现边框线. 可能的原因: 由 Element UI 的默认样式或者表格的某些内置样式引起的。比如,<el-table> 会通过 border-collapse 或 border-spacing 等属性影响边框的显示。 4…

大模型与EDA工具

EDA工具&#xff0c;目标是硬件设计&#xff0c;而硬件设计&#xff0c;您也可以看成是一个编程过程。 大模型可以辅助软件编程&#xff0c;相信很多人都体验过了。但大都是针对高级语言的软件编程&#xff0c;比如&#xff1a;C&#xff0c;Java&#xff0c;Python&#xff0c…

【HarmonyOS之旅】基于ArkTS开发(一) -> Ability开发一

目录 1 -> FA模型综述 1.1 -> 整体架构 1.2 -> 应用包结构 1.3 -> 生命周期 1.4 -> 进程线程模型 2 -> PageAbility开发 2.1 -> 概述 2.1.1 ->功能简介 2.1.2 -> PageAbility的生命周期 2.1.3 -> 启动模式 2.2 -> featureAbility接…

BART:用于自然语言生成、翻译和理解的去噪序列到序列预训练

摘要&#xff1a; 我们提出了BART&#xff0c;一种用于预训练序列到序列模型的去噪自编码器。BART通过以下方式训练&#xff1a;(1) 使用任意的噪声函数对文本进行破坏&#xff0c;(2) 学习一个模型来重建原始文本。它采用了一种标准的基于Transformer的神经机器翻译架构&#…

Promise编码小挑战

题目 我们将实现一个 createImage 函数&#xff0c;该函数返回一个 Promise&#xff0c;用于处理图片加载的异步操作。此外&#xff0c;还会实现暂停执行的 wait 函数。 Part 1: createImage 函数 该函数会&#xff1a; 创建一个新的图片元素。将图片的 src 设置为提供的路径…

Dubbo扩展点加载机制

加载机制中已经存在的一些关键注解&#xff0c;如SPI、©Adaptive> ©Activateo然后介绍整个加载机制中最核心的ExtensionLoader的工作流程及实现原理。最后介绍扩展中使用的类动态编译的实 现原理。 Java SPI Java 5 中的服务提供商https://docs.oracle.com/jav…

【Web】软件系统安全赛CachedVisitor——记一次二开工具的经历

明天开始考试周&#xff0c;百无聊赖开了一把CTF&#xff0c;还顺带体验了下二开工具&#xff0c;让无聊的Z3很开心&#x1f642; CachedVisitor这题 大概描述一下&#xff1a;从main.lua加载一段visit.script中被##LUA_START##(.-)##LUA_END##包裹的lua代码 main.lua loca…

在不到 5 分钟的时间内将威胁情报 PDF 添加为 AI 助手的自定义知识

作者&#xff1a;来自 Elastic jamesspi 安全运营团队通常会维护威胁情报报告的存储库&#xff0c;这些报告包含由报告提供商生成的大量知识。然而&#xff0c;挑战在于&#xff0c;这些报告的内容通常以 PDF 格式存在&#xff0c;使得在处理安全事件或调查时难以检索和引用相关…

vscode代码AI插件Continue 安装与使用

“Continue” 是一款强大的插件&#xff0c;它主要用于在开发过程中提供智能的代码延续功能。例如&#xff0c;当你在编写代码并且需要进行下一步操作或者完成一个代码块时&#xff0c;它能够根据代码的上下文、语法规则以及相关的库和框架知识&#xff0c;为你提供可能的代码续…

leetcode(hot100)4

解题思路&#xff1a;双指针思想 利用两个for循环&#xff0c;第一个for循环把所有非0的全部移到前面&#xff0c;第二个for循环将指针放在非0的末尾全部加上0。 还有一种解法就是利用while循环双指针条件&#xff0c;当不为0就两个指针一起移动 &#xff0c;为0就只移动右指针…

vulnhub——Earth靶机

使用命令在kali查看靶机ip arp-scan -l 第一 信息收集 使用 nmap 进行 dns 解析 把这两条解析添加到hosts文件中去&#xff0c;这样我们才可以访问页面 这样网站就可以正常打开 扫描ip时候我们发现443是打开的&#xff0c;扫描第二个dns解析的443端口能扫描出来一个 txt 文件…

k8s基础(1)—Kubernetes-Pod

一、Pod简介 Pod是Kubernetes&#xff08;k8s&#xff09;系统中可以创建和管理的最小单元&#xff0c;是资源对象模型中由用户创建或部署的最小资源对象模型‌。Pod是由一个或多个容器组成的&#xff0c;这些容器共享存储和网络资源&#xff0c;可以看作是一个逻辑的主机‌。…

【FlutterDart】页面切换 PageView PageController(9 /100)

上效果&#xff1a; 有些不能理解官方例子里的动画为什么没有效果&#xff0c;有可能是我写法不对 后续如果有动画效果修复了&#xff0c;再更新这篇&#xff0c;没有动画效果&#xff0c;总觉得感受的丝滑效果差了很多 上代码&#xff1a; import package:flutter/material.…

使用 NestJS 构建高效且模块化的 Node.js 应用程序,从安装到第一个 API 端点:一步一步指南

一、安装 NestJS 要开始构建一个基于 NestJS 的应用&#xff0c;首先需要安装一系列依赖包。以下是必要的安装命令&#xff1a; npm i --save nestjs/core nestjs/common rxjs reflect-metadata nestjs/platform-express npm install -g ts-node包名介绍nestjs/coreNestJS 框…