Flutter的理念架构

Flutter架构分为三层

参考官方文档

  • Framework层(dart)
  • flutter engine层(C/C++)
  • embeder层(platform-specific)

Flutter 被设计为一个可扩展的分层系统。它可以被看作是各个独立的组件的系列合集,上层组件各自依赖下层组件。组件无法越权访问更底层的内容,并且框架层中的各个部分都是可选且可替代的。

Framework层

是由dart编写的sdk,实现了一套基础库,包含了material和Cupertino风格UI界面,下面是一些通用的widget组件,渲染,动画,绘制,手势库等等。这个纯dart实现的库被封装为dart:ui。

Flutter engine层

Flutter引擎是Flutter的核心,主要使用C++编写。它提供了Flutter 核心API底层实现,包括图形渲染(通过Skia)、文本布局、文件以及网络IO(Input/Output ==> 内部与外部的通信)、辅助功能支持、插件架构和Dart运行环境及编译环境的工具链。引擎将底层C++代码包装成Dart代码,通过dart:ui暴露给Flutter框架层。

Skia是Google的一个2D绘图引擎库,Chrome和Android均采用Skia作为绘图引擎,在图形转换、文字渲染、位图渲染方面提供了友好、高效的表现。Skia是跨平台的,可以被嵌入到Flutter的IOS SDK中,而不用去研究IOS闭源的Core Graphics / Core Animation。Android自带了Skia,所以Flutter Android SDK比IOS SDK小的多。

Embeder层

为engine层提供了四个task runner,将引擎移植到平台的中间层代码,渲染设置,原生插件,线程管理,事件循环交互等操作。这一层是操作系统适配层,负责管理线程。

Flutter是如何做到一套Dart代码可以编译运行在Android和iOS平台的

Skia引擎渲染,实现多平台渲染一致性

Method Channel机制

为了解决调用原生系统底层能力以及相关代码库复用问题,Flutter为开发者提供了一个轻量级的解决方案,即逻辑层的方法通道(Method Channel)机制。基于方法通过,我们可以将原生代码所拥有的能力以接口的形式暴露给Dart,从而实现Dart代码和原生代码的交互,就像调用了一个普通的Dart API一样。

注意 Method Channel时非线程安全的。原生代码在处理方法调用请求时,如果涉及到异步或者非主线程切换,需要确保回调过程是在原生系统的UI线程中执行的,否则应用可能会出现奇怪的Bug,甚至是Crash。

关于Platform channel

三种类型

  • BasicMessageChannel:用于传递字符串和半结构化的信息
  • MethodChannel:用于传递方法调用(method invocation)
  • EventChannel:用于数据流(event streams)的通信

成员变量

三种Channel之间互相独立,各有用途,但它们在设计上却非常相近。每种Channel均有三个重要成员变量

  • name: String类型,代表Channel的名字,也是其唯一标识符。
  • messager:BinaryMessenger类型,代表消息信使,是消息的发送与接收的工具。
  • codec: MessageCodec类型或MethodCodec类型,代表消息的编解码器。

如何让Flutter编译出来的APP的包大小尽可能变小

Flutter release产物分析

整个APP由APP Framework和Flutter Framework两部分组成

  • APP Framework(可变化的)
  • App:Dart代码AOT编译产物,是动态链接库
  • flutter_assets:Flutter静态资源文件夹,包括图片,字体等

包体积优化方法

删、缩、挪

  • 删:删除无用代码,无用资源。可以手动删除,也可以机器删除,也可以编译时删除。Flutter有一个Tree shaking机制,从Main方法开始,逐级引用,最终没有被引用的代码,诸如类和函数都会被裁减掉。这个就是编译时自动删除。
  • 缩:比如压缩图片资源。
  • 挪:从项目工程或Packages里直接挪到远端,典型是远端下发插件或者安卓里的App Bundle,虽然“挪”对性能来说是有损的(需要动态下发),但是包体积却大大减少。
移除无用代码和无用资源,压缩图片,安卓里拆App bundle
统一编译参数

在Flutter引擎编译时,安卓和IOS的编译参数不同,安卓时-OZ,IOS时-OS,想追求极致包体积的话,是需要使用-OZ的。升级到最新的build-tools,改OS为OZ

动态下发方案

Flutter工程编译安卓包,会编译成4个snapshot文件,分别是

  • isolate_snapshot_instr
  • isolate_snapshot_data
  • vm_snapshot_instr
  • vm_snapshot_data

把isolate_snapshot_data和vm_snapshot_data文件移出来,flutter_assets也移出来。挪动前9.2M,挪动后3.8M,如果App体积庞大,这个收益会更明显。

Flutter渲染优化

重建组件个数尽量少

如果将整个页面写在一个单独的StatefulWidget中,每次setState都会导致不必要的UI重建。拆分组件,使用良好的设计模式和状态管理方案。

构建组件时使用const关键词,可以抑制widget的重建

合理利用const关键词,可以在很大程度上优化应用的性能

需要注意以下两点

  • 当const修饰类的构造函数时,要求该类的所有成员必须是final的。适合StatelessWidget。
  • const变量只能在定义的时候初始化

有些实现的效果背后可能会使用saveLayer()这个代价很大的方法

  • ShaderMask
  • ColorFilter
  • Chip,当disabledColorAlpha!=0xff时,会调用saveLayer()
  • Text,如果有overflowShader,可能调用saveLayer()

官方优化点

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

可以通过设置颜色的透明程度,比如Color.fromRGBO(255, 0, 0, 0.5)

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

管理着色器编译垃圾

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

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

安卓

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

IOS

flutter build ios --bundle-sksl-path flutter_01.sksl.json

Flutter查漏补缺2的更多相关文章

  1. Flutter查漏补缺1

    Flutter 基础知识查漏补缺 Hot reload原理 热重载分为这几个步骤 扫描项目改动:检查是否有新增,删除或者改动,直到找到上次编译后发生改变的dart代码 增量编译:找到改变的dart代码 ...

  2. 《CSS权威指南》基础复习+查漏补缺

    前几天被朋友问到几个CSS问题,讲道理么,接触CSS是从大一开始的,也算有3年半了,总是觉得自己对css算是熟悉的了.然而还是被几个问题弄的"一脸懵逼"... 然后又是刚入职新公司 ...

  3. js基础查漏补缺(更新)

    js基础查漏补缺: 1. NaN != NaN: 复制数组可以用slice: 数组的sort.reverse等方法都会改变自身: Map是一组键值对的结构,Set是key的集合: Array.Map. ...

  4. Entity Framework 查漏补缺 (一)

    明确EF建立的数据库和对象之间的关系 EF也是一种ORM技术框架, 将对象模型和关系型数据库的数据结构对应起来,开发人员不在利用sql去操作数据相关结构和数据.以下是EF建立的数据库和对象之间关系 关 ...

  5. 2019Java查漏补缺(一)

    看到一个总结的知识: 感觉很全面的知识梳理,自己在github上总结了计算机网络笔记就很累了,猜想思维导图的方式一定花费了作者很大的精力,特共享出来.原文:java基础思维导图 自己学习的查漏补缺如下 ...

  6. 20165223 week1测试查漏补缺

    week1查漏补缺 经过第一周的学习后,在蓝墨云班课上做了一套31道题的小测试,下面是对测试题中遇到的错误的分析和总结: 一.背记题 不属于Java后继技术的是? Ptyhon Java后继技术有? ...

  7. 今天開始慢下脚步,開始ios技术知识的查漏补缺。

    从2014.6.30 開始工作算起. 如今已经是第416天了.不止不觉.时间过的真快. 通过对之前工作的总结.发现,你的知识面.会决定你面对问题时的态度.过程和结果. 简单来讲.知识面拓展了,你才干有 ...

  8. Mysql查漏补缺笔记

    目录 查漏补缺笔记2019/05/19 文件格式后缀 丢失修改,脏读,不可重复读 超键,候选键,主键 构S(Stmcture)/完整性I(Integrity)/数据操纵M(Malippulation) ...

  9. 【spring源码分析】IOC容器初始化——查漏补缺(四)

    前言:在前几篇查漏补缺中,其实我们已经涉及到bean生命周期了,本篇内容进行详细分析. 首先看bean实例化过程: 分析: bean实例化开始后 注入对象属性后(前面IOC初始化十几篇文章). 检查激 ...

  10. Django 查漏补缺

    Django 查漏补缺 Django  内容回顾: 一. Http 请求本质: 网络传输,运用socket Django程序: socket 服务端 a. 服务端监听IP和端口 b. 浏览器发送请求 ...

随机推荐

  1. 【赵渝强老师】如何分析Java的内存溢出问题

    一.什么是内存溢出? 内存溢出(OOM:out of memory)通俗理解就是内存不够,通常在运行大型软件或游戏时,软件或游戏所需要的内存远远超出了你主机内安装的内存所承受大小,就叫内存溢出. 在J ...

  2. 16 模块time、datetime、random、hashlib、logging

    1. 时间模块time.datetime 在python中,表示时间有三种方式:时间戳 格式化的时间字符串(Format String): '2022-03-01' 时间元组(struct_time) ...

  3. c++面经系列0:开篇-c++岗位面试都会问些什么?

    本文是C++岗位面试经验分享系列的开篇,敬请持续关注. 在C++岗位面试中,通常首先进行技术面试,若通过则会进行HR面试.HR面试的内容先暂且略过,未来我们会有机会深入探讨,今天我们主要聚焦于技术面试 ...

  4. CSP 联训 3

    好吧,又倒数了,就签了个 T2,100 pts. T1 我把相同颜色的存起来,每种颜色找出枚举选哪两个座位不合法的矩阵的左上和右下,如果找到的矩阵左下和右上也相同,则这个矩阵确实不合法,减去,但判断左 ...

  5. 干货必收藏!墨天轮最受DBA欢迎的250份学习文档合集

    作为一个DBA,必须要精通SQL命令.各种数据库架构.数据库管理和维护.数据库调优,必要的时候,还需要为开发人员搭建一个健壮.结构良好.性能稳定的数据库环境. 技术也是不断进步的,社会的发展要求DBA ...

  6. PostgreSQL 15 新特性解读 | 墨天轮优质文章合集

    5月19日,PostgreSQL 全球开发组宣布 PostgreSQL 15 的第一个 beta 版本,这一新版本在开发者体验.性能表现等方面都有提升.为了帮助大家更快速了解到PostgreSQL 1 ...

  7. iOS使用SourceTree回滚回滚小结

    代码回滚,适用于的场景: 1.提交错代码,想放弃刚刚提交的部分:2.代码发生冲突,处理比较麻烦,为了代码安全,直接回滚到之前干净的代码.我个人理解,可以分为本地回滚和远程回滚: 一.本地回滚,回滚自己 ...

  8. kotlin类与对象——>嵌套类与内部类、枚举类

    1.嵌套类,类可以嵌套在其他类中: class Outer { private val bar: Int = 1 class Nested { fun foo() = 2 } } val demo = ...

  9. golang中使用多线程和channel通道

    package controller import ( "context" "github.com/gogf/gf/v2/os/grpool" "sy ...

  10. KubeKey 2.0.0 发布:让离线部署 K8s 更加便捷

    2022 年 3 月 8 日,KubeKey 2.0.0 正式发布,这是 KubeKey 的第 7 个正式版本,也是非常重要的一个版本.该版本新增了清单(manifest)和制品(artifact)的 ...