当前位置: 首页 > news >正文

【Android常见问题(五)】- Flutter项目性能优化

文章目录

  • 知识回顾
  • 前言
  • 源码分析
    • 1. 渲染过程
    • 2. 分析工具
    • 3. 优化方法
      • 合理使用const关键词
      • 合理使用组件
      • 管理着色器编译垃圾


知识回顾

前言

项目迭代开发一定程度后,性能优化是重中之重,其中包括了包体积,UI 渲染、交互等多个方面。
通过 Flutter 应用的混淆为入口,我们主要探讨了UI 渲染的优化。

其中就会涉及到一个非常关健的概念 ——「FPS,Frame Per Second」即「每秒展示帧数」,它代表了应用的流畅度。

我们知道,动画和物体动态的运动都是由在一段时间内一系列连续变化的静态帧构成的。

在考虑应用的渲染性能时,我们就是在试图分析应用每秒渲染的帧数。

从物理角度看,对于连续的一系列图像帧,人脑会根据眼睛发出的视觉信号做出反应,一个个静态帧的切换到达一定速度后,就可以欺骗我们的大脑,让我们以为它们是连续的,FPS 就是图像帧切换的速度单位。

因此有人说,物体运动的概念其实就是一种思维的束缚。

当 FPS 达到 10-12 时,大脑便可以感知运动,此时并不流畅,达到 24 FPS 时,人眼就能看到流畅的运动了,但是在电影和视频中,则至少需要每秒 60 帧的速度才可以使人的大脑轻松感知到流畅地运动。
在这里插入图片描述
1000ms / 60 frames = 16.666 ms/frame

我们需要在 16.66 毫秒内完成整个帧的计算,布局和渲染,否则不流畅,就需要掏出我们的 24K 合金双摄眼,找到优化点,让应用保持流畅。


源码分析

1. 渲染过程

Flutter 应用的每一帧都由框架层和引擎层互相协作完成。

最初,某些外部事件(如手势,网络等)或者异步任务会导致屏幕更新,该消息消息页会通知到引擎层。

Flutter 框架层会拦截了该请求,执行 Tickers 相关的任务(如动画)。

这些任务也可能会重新发出一个请求,以供以后的帧渲染。(如动画暂停后再继续,需要在以后的阶段接收另一个 Begin 帧)。

然后,引擎层就可以开始做屏幕渲染工作了,但在开始之前,Flutter 框架依然会拦截该请求,并根据当前的组件结构和尺寸大小计算出更新布局、绘制相关的所有数据。

完成这些任务后,如果最终确定真的要在屏幕上绘制一些东西,它就会将需要渲染的新数据发送到 Flutter Engine,做最终的屏幕更新。

在这里插入图片描述

整个过程都在 Flutter 的 UI 线程中运行,如若阻塞,就会卡顿。

通常,应用开发者不需要关心引擎层的逻辑,但并不意味着我们不需要关心渲染性能。

引擎层的功能其实也是单一的,他只是拿到框架层的数据去做渲染而已。但是框架层是由我们控制的,我们所写的每一个组件都在框架层之上。

如何将传递给引擎层的更新数据做到最优,就是渲染优化时我们需要考虑的问题。

这些更新数据就是由 Flutter 中重要的三棵树生成的,建议不熟悉的读者去回看之前的这篇文章。

我们需要做的就是让 Flutter 中重建组件的个数尽量少。

2. 分析工具

在 Android Studio 中,找到 Flutter Performance (View > Tool Windows > Flutter Performance),就可以直接看到正在重建的 widget 数量。

这里,勾选 Show widget rebuild information 复选框,此功能也能够帮助你检测帧的渲染和显示时间是否超过 16ms。

3. 优化方法

合理使用const关键词

const 您可以通过将其附加到Widget的构造函数来抑制Widget的重建(它与Widget缓存时的状态相同)。

构建组件时使用 const 关键词,可以抑制 widget 的重建。
const 在 Dart 中用于声明常量,应用到 widget 中就相当于告诉 Flutter,“我这个组件不会碎状态更新而改变了。”,因此达到了减少重建的效果。

使用 const 也需要注意如下几点:

当const 修饰类的构造函数时,它要求该类的所有成员都必须是final的。
const 变量只能在定义的时候初始化。
合理利用 const 关键词,可以在很大程度上优化应用的性能

合理使用组件

Flutter 实现的一些效果背后可能会使用 saveLayer() 这个代价很大的方法。
为什么 saveLayer 代价很大?
调用 saveLayer() 会开辟一片离屏缓冲区。将内容绘制到离屏缓冲区可能会触发渲染目标切换,这些切换在较早期的 GPU 中特别慢。

——来自 flutter.cn,https://flutter.cn/docs/testing/best-practices
如下这几个组件,底层都会触发 saveLayer() 的调用,同样也都会导致性能的损耗:

ShaderMask
ColorFilter
Chip,当 disabledColorAlpha != 0xff 的时候,会调用 saveLayer()。
Text,如果有 overflowShader,可能调用 saveLayer() ,
官方也给了我们一些非常需要注意的优化点:

由于 Opacity 会使用屏幕外缓冲区直接使目标组件中不透明,因此能不用 Opacity Widget,就尽量不要用。有关将透明度直接应用于图像的示例,请参见 Transparent image,比使用 Opacity widget 更快,性能更好。

要在图像中实现淡入淡出,请考虑使用 FadeInImage 小部件,该小部件使用 GPU 的片段着色器应用渐变不透明度。

很多场景下,我们确实没必要直接使用 Opacity 改变透明度,如要作用于一个图片的时候可以直接使用透明的图片,或者直接使用 Container:Container(color: Color.fromRGBO(255, 0, 0, 0.5))

Clipping 不会调用 saveLayer()(除非明确使用 Clip.antiAliasWithSaveLayer),因此这些操作没有 Opacity 那么耗时,但仍然很耗时,所以请谨慎使用。

要创建带圆角的矩形,而不是应用剪切矩形,请考虑使用很多 widget 都提供的 borderRadius属性。

管理着色器编译垃圾

有时候,应用中的动画首次运行时会看起来非常卡顿,但是运行多次之后便可以正常运行,这可能就是由于着色器编译混乱导致的。

在图形渲染,着色器相当于是在 GPU 运行的一组代码。想要达到 60fps,需要在 16 毫秒内绘制一个平滑的帧,但是在编译着色器时,它花费的时间可能比应该花费的时间更多,可能会接近几百毫秒,并且会导致丢失数十个帧,将 fps 从 60 降至 6。

解决方法
Flutter 1.20 之后,Flutter 为开发者提供了非常方便的一组命令行工具,由此开发人员可以使用 Skia Shader Language 格式收集最终用户可能需要的着色器, 一旦将 SkSL 着色器打包到应用程序中,当用户打开应用程序时,就会自动进行预编译。

运行应用,添加 --cache-sksl 参数捕获 SkSL 中的着色器:

flutter run --profile --cache-skslflutter run --profile --cache-sksl --purge-persistent-cache

该参数可能会删除 SkSL 着色器捕获的较旧的非 SkSL着色器缓存,因此只能在第一次运行时使用 --cache-sksl。

在不同平台上,可以执行以下命令,使用 SkSL 预热功能构建应用程序:

flutter build apk — bundle-sksl-path flutter_01.sksl.json

相关文章:

【Android常见问题(五)】- Flutter项目性能优化

文章目录 知识回顾前言源码分析1. 渲染过程2. 分析工具3. 优化方法合理使用const关键词合理使用组件管理着色器编译垃圾 知识回顾 前言 项目迭代开发一定程度后,性能优化是重中之重,其中包括了包体积,UI 渲染、交互等多个方面。 通过 Flutt…...

JSON转换:实体类和JSONObject互转,List和JSONArray互转(fastjson版)

//1.java对象转化成String String sJSONObject.toJSONString(javaObject.class); //2. java对象转化成Object Object strJSONObject.toJSON(javaObject.class); //3.String类型转json对象 JSONObject jsonObject JSONObject.parseObject(str); //4. String…...

Java单例模式几种代码详解

在软件开发中,单例模式是一种常见的设计模式,它的目的是确保一个类在任何情况下都只有一个实例,同时提供一个全局访问点。在Java中,有几种常见的实现单例模式的方式,下面将逐一进行详细解释。 懒汉式(非线…...

PHP代码审计--理论

提供资料: php 基础 : https://www.runoob.com/php/php-tutorial.html php是什么? PHP 是服务器端脚本语言。 首先在学习PHP前需要对HTML 和CSS有一定的认识 PHP 能做什么? PHP 可以生成动态页面内容PHP 可以创建、打开、读取、写入、关…...

在云服务器上,clone github时报Connection timed outexit code: 128

文章目录 问题解决方案 问题 在执行pip install安装依赖时,需要clone github代码,此时报了Connection timed out&exit code: 128错误,原因是访问超时了,此时需要使用代理 fatal: unable to access https://github.com/hugg…...

小型双轮差速底盘寻迹功能的实现

1. 功能说明 寻迹机器人是一种能够跟踪特定物体或线路的机器人。它们通常具有以下功能和特点: ① 传感器:寻迹机器人配备了用于感知环境的传感器,如摄像头、灰度传感器等。这些传感器可以探测地面上的标记、颜色、纹理或其他特定特征&#xf…...

第七篇:k8s集群使用helm3安装Prometheus Operator

安装Prometheus Operator 目前网上主要有两种安装方式,分别为:1. 使用kubectl基于manifest进行安装 2. 基于helm3进行安装。第一种方式比较繁琐,需要手动配置yaml文件,特别是需要配置pvc相关内容时,涉及到的yaml文件太…...

Chrome 75不支持保存成mhtml的解决方法

在Chrome 75之前,可以设置chrome://flags -> save as mhtml来保存网页为mhtml。 升级新版,发现无法另存为/保存网页为MHTML了。 在网上搜索无果后,只得从chromium项目的commits中查找,原来chrome搞了个"Chrome Flag Owner…...

工程监测振弦采集仪应用于岩土工程监测案例

振弦采集仪是一种用于测量地面或岩土中振动参数的仪器,可以对地基、土壤和岩体的性质及其变化进行监测。在岩土工程监测中,振弦传感器被广泛应用于测量土体或岩体的振动情况,以了解地震或其他自然灾害的影响。 以下是一个振弦采集仪应用岩土工…...

配置HDFS单机版,打造数据存储的强大解决方案

目录 简介:步骤:安装java下载安装hadoop配置hadoop-env.sh配置 core-site.xml配置hdfs-site.xml初始化hdfs文件系统启动hdfs服务验证hdfs 结论: 简介: Hadoop分布式文件系统(HDFS)是Hadoop生态系统中的一个…...

U盘删除的文件怎么找回?4个简单方法分享!

“在u盘里不小心删除的文件到底还能不能找回来呀?真的好着急啊!这个u盘对我来说真的很重要,怎么恢复里面的数据呢?请各位大佬帮帮我吧!” 作为一个便捷的存储工具,u盘逐渐获得大众的青睐。在互联网时代&…...

【雕爷学编程】MicroPython动手做(27)——物联网之掌控板小程序2

知识点:什么是掌控板? 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通信,可作为物联网节点,实现物联网应用。同时掌控板上集成了OLED…...

形参动态内存开辟和柔性数组

//柔性数组 //定义:结构体最后一个成员允许是未知大小的数组 // 优点;在开辟空间时,连续开辟,便于释放空间,不会因多次开辟,导致释放空间出错 // 开辟空间时,节省动态开辟次数,节省空间&am…...

【LLM系列之指令微调】长话短说大模型指令微调的“Prompt”

1 指令微调数据集形式“花样”太多 大家有没有分析过 prompt对模型训练或者推理的影响?之前推理的时候,发现不加训练的时候prompt,直接输入模型性能会变差的,这个倒是可以理解。假如不加prompt直接训练,是不是测试的时…...

MacOS使用brew如何下载Nginx

首先,第一步切换源: 切换 brew.git 仓库地址: cd "$(brew --repo)" git remote set-url origin https://mirrors.aliyun.com/homebrew/brew.git 替换 homebrew-core.git 仓库地址: cd "$(brew --repo)/Library/Taps/home…...

linux ftp

使用ftp连接本机进行文件传输 1、下载vsftpd服务器程序 apt install vsftpd 2、使用tcp抓包 tcpdump -nt -i lo port 20 在FTP连接到本地主机(127.0.0.1)时,数据可能通过本地回环接口(loopback interface)传输&…...

你知道HTTP与HTTPS有什么区别吗?

作者:Insist-- 个人主页:insist--个人主页 作者会持续更新网络知识和python基础知识,期待你的关注 目录 一、什么是HTTP? 二、什么是HTTPS? 三、HTTPS 的工作原理 1、客户端发起 HTTPS 请求 2、服务端的配置 3、…...

keil使用printf函数重定串口输出,程序卡在Reset_Handler

最近在做国产芯片GD32F103项目,使用printf()函数重定向USART0串口输出,发现程序没有运行,单步调试发现,程序卡在startup_gd32f10x.s文件的Reset_Handler处,记录一下解决方法。 解决办法: 1、引用头文件#in…...

Redis预热 雪崩 击穿 穿透

redis预热 在Redis中,预热是指在实际的负载之前,提前将数据加载到内存中,以便在请求到来时能够快速响应。预热可以减少冷启动时的延迟,并提高系统的性能。 有几种方法可以进行Redis的预热: 使用持久化机制&#xff1…...

Shell脚本学习-MySQL单实例和多实例启动脚本

已知MySQL多实例启动命令为: mysqld_safe --defaults-file/data/3306/my.cnf & 停止命令为: mysqladmin -uroot -pchang123 -S /data/3306/mysql.sock shutdown 请完成mysql多实例的启动脚本的编写: 问题分析: 要想写出脚…...

技术突破:如何让ARM设备突破x86架构的束缚?

技术突破:如何让ARM设备突破x86架构的束缚? 【免费下载链接】box64 Box64 - Linux Userspace x86_64 Emulator with a twist, targeted at ARM64, RV64 and LoongArch Linux devices 项目地址: https://gitcode.com/gh_mirrors/bo/box64 你是否曾…...

终极指南:如何用AhabAssistantLimbusCompany彻底解放《Limbus Company》游戏时间

终极指南:如何用AhabAssistantLimbusCompany彻底解放《Limbus Company》游戏时间 【免费下载链接】AhabAssistantLimbusCompany AALC,PC端Limbus Company小助手。AALC,Limbus Company Assistant on PC 项目地址: https://gitcode.com/gh_mi…...

SABIC塑料解决方案:宏裕塑胶全面代理原GE塑料高性能材料产品

宏裕塑胶依托源头直采优势整合沙伯基础创新SABIC等国际品牌资源,为制造业客户提供高性价比通用工程塑料原料及全流程技术支撑,助力企业降本增效。其代理产品涵盖PETG、PCTG、PBT、TPEE等全品类工程塑料,专为塑胶制品厂、汽车零部件厂等客户群…...

创业公司如何借助 Taotoken 的多模型聚合能力快速验证产品 AI 功能

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 创业公司如何借助 Taotoken 的多模型聚合能力快速验证产品 AI 功能 对于资源有限的创业团队而言,在产品早期快速验证核…...

告别演讲焦虑:PPTTimer如何让时间管理变得简单智能

告别演讲焦虑:PPTTimer如何让时间管理变得简单智能 【免费下载链接】ppttimer 一个简易的 PPT 计时器 项目地址: https://gitcode.com/gh_mirrors/pp/ppttimer 你是否曾在重要演讲时频繁看表,担心时间不够用?是否在PPT演示中因时间控制…...

为什么你需要英雄联盟Akari助手:3个步骤提升游戏效率的完整指南

为什么你需要英雄联盟Akari助手:3个步骤提升游戏效率的完整指南 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 还在为英雄联盟中繁…...

IDM激活脚本:破解30天限制背后的注册表权限技术内幕

IDM激活脚本:破解30天限制背后的注册表权限技术内幕 【免费下载链接】IDM-Activation-Script IDM Activation & Trail Reset Script 项目地址: https://gitcode.com/gh_mirrors/id/IDM-Activation-Script 你是否曾经因为IDM的30天试用期到期而烦恼&#…...

利用 QiWe API 实现企业微信机器人消息双向交互

1. 什么是企微机器人的“多模态”交互? 早期的微信机器人大多只能处理简单的纯文本对话。然而,在真实的商业客服场景中,客户往往会发送商品图片、发票PDF文件、产品操作视频甚至是语音消息。一个合格的企业级机器人,必须具备处理和…...

冲压送料机远程监控运维管理系统方案

某设备制造商,常年向汽车零部件、电子元器件等行业客户供应各类冲压送料设备,随着市场拓展,其售后运维面临诸多突出问题。一方面,设备分布地域广泛,客户上报故障后,售后服务往往响应滞后且运维成本居高不下…...

从 LangChain 到 LangGraph:大语言模型应用开发框架极简史

大模型应用开发正经历一场静悄悄的革命——从“把LLM接进工作流”走向“为Agent构建操作系统”。作为这场革命的两大核心引擎,LangChain与LangGraph的故事,既是一部框架演进史,也是一部开发者认知升级史。 一、源起:一个框架的诞生与大模型开发的“蛮荒时代” 时间回到202…...