# base_flutter_project **Repository Path**: eyesoffish/base_flutter_project ## Basic Information - **Project Name**: base_flutter_project - **Description**: No description available - **Primary Language**: Dart - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2019-11-21 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # flutter 性能调试(16毫秒60帧) [skia调试](https://www.youtube.com/watch?v=OLjhAl7adGE&t=33s) 注意 实际设备调试的话GPU硬件加速的端,在模拟器是用的CPU的后端 - flutter run --profile --trace-skia - 打开调试的界面 - 操作界面 - 有上角refresh - SK开头的函数为skia的函数(可以看到函数被调用了多少次,和调用时间) ---- # 捕捉SKPicture分析每一条绘图指令 flutter screenshot --type=skia --observatory-port=[观测台的端口号] - 将生成的skp文件上传到debugger.skia.org 可以看到 Visible 组件如果组件被挡住了就不要去做重复的渲染。 # 注意Skia函数调用 - saveLayer (没调用一次,我们需要在GPU里面分配一块新的绘图缓冲区,并且告诉我们的GPU切换我们的绘图目标) - clipPath (比savelayer消耗会小一点,但是还是比较耗时,因为一旦调用了他,接下来每一个绘图指令都会被ClipPath影响,尤其是这个ClipPath比较复杂的时候,我们都要和这个很复杂的path做这个相交的操作,把不在这个ClipPath之外的部分给剔除掉) 注意 savelayer 会有一个预处理的时间是非常短的,而skcanvas.flush才是真正消耗时间的地方,这就是把所有的预处理完之后告诉Skia重新打包给GPU渲染。 # 可能出现saveLayer和clipPath的组件 - Opacity - ShaderMask - 如果需要用Clip, 请使用Clip.antiAlias或者Clip.hardEdge - 只有极少数的情况才会使用Clip.antiAliasWithSaveLayer的情况 # RepaintBoundary 隔离跟新 # flutter和react-native相比 UI只需要原生提供一个画布,而react-native需要通过webview来绘制UI - 底层架构为c++,自己绘制UI,不使用原生UI。 # Part,用于代码分割。而且part引用的库的共享的。 ```dart - data.dart part 'data.g.dart'; // //some code // - data.g.dart part of 'data.dart' // // some code // ``` # widget、element、renderObject关系 - widget是对element的配置或者描述。 - widget 创建对应的Element和widget一一对应。并且告诉flutter显示的元素。 - renderObject主要是负责布局和绘制。 - state object 会将元素标脏,然后会在屏幕的下一帧进行重新绘制。 # inherited Widgets 用于访问节点树的数据 - 例如Theme.of() # isolates 拥有自己的内存空间,内存不共享。 - 每个线程都有自己的islate和自己的内存,不可相互访问。他们唯一的交互就是来回传递消息 ```dart // 两这都会创建一个单独的isolate来进行数字运算,然后主isolate进行组件的渲染。 Isolate.spawn( aFunctaionToRun, "data" ); compute( (params){}, "data" ); ``` - 内存不共享的好处不需要线程锁。 - 事件都是一件儿一件儿处理的。事件队列。 # stream 持续的事件监听(订阅) - 默认stream的监听只有一个,如果需要改为多个监听者需要增加一个参数:.asBoradcastStream - cancelOnError = false即使出错误也可以保持订阅 - 订阅者可以暂停、继续、取消 - 创建自己的订阅 ```dart class NumberCreator{ var _count = 1; final _controller = StreamController(); Stream get stream => _controller.stream; NumberCreator(){ Timer.periodic(Duration(second: 1), (t){ _controller.sink.add(_count); _count++; }); } } ``` # 自己的迭代器 - sync*(同步生成器):告诉dart这个函数需要产生多个值。 - yield:类似return,一次生成值,等待调用者请求下一个值。 ```dart Iterable getRange(int start, int finish) sync* { if (start <= finish) { yield start; yield* getRange(start+1, finish); } } // 如果数据有可能是异步的 Future fetchDouble(int val) { // 从网络上下来的数据 } Stream fetchDoubles(int start, int finish) async* { if (start <= finish) { yield await fetchDouble(start); yield* fetchDoubles(start + 1, finish); } } ```