diff --git a/ohos/docs/05_performance/README.md b/ohos/docs/05_performance/README.md index f1cc70fcc4527d2bb844119ecdf268ce8f61f3d4..64431c28a4dc107ec5b76a52d28b9860c78686b7 100644 --- a/ohos/docs/05_performance/README.md +++ b/ohos/docs/05_performance/README.md @@ -6,6 +6,10 @@ flutter鸿蒙化的工程,也可以使用devtools对Dart代码进行调试, [性能分析第一步-梳理线程顺序](./performance-threads-sequence.md) +[性能分析-帧渲染跟踪](./performance-frame-rendering-tracking.md) + +[性能分析-滑动响应时延](./performance-sliding-response-time.md) + ## 环境配置 如果环境变量中设置了代理 http_proxy 和 https_proxy,需要再设置一个环境变量 no_proxy diff --git a/ohos/docs/05_performance/performance-frame-rendering-tracking.md b/ohos/docs/05_performance/performance-frame-rendering-tracking.md new file mode 100644 index 0000000000000000000000000000000000000000..4341063d7b3ef581e46bf02484ceb2ca993f1ae9 --- /dev/null +++ b/ohos/docs/05_performance/performance-frame-rendering-tracking.md @@ -0,0 +1,40 @@ +# 性能分析-帧渲染跟踪 + +Flutter应用进行性能分析时,需利用分析工具捕获应用的trace数据,并对其进行分析。鉴于Flutter应用中可能会出现需要单独追踪某帧渲染的情况,如帧率卡顿或帧丢失,本文特介绍了一种针对单帧追踪的方法。 + + +## 分析工具 +常用的分析工具包括[DevEco Studio Profiler](https://developer.huawei.com/consumer/cn/download/)及[SmartPerf](https://gitee.com/openharmony-sig/smartperf),建议选用DevEco Studio Profiler性能调优工具。性能调优工具DevEco Studio Profiler的使用方法可查看[DevEco Profiler工具简介](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/deep-recording-V5). + + +## 帧标识 +一帧的渲染流程大致如下: + +![](../media/05/image-3-201.png) + + +掌握帧渲染流程非常重要,同时也需要掌握帧渲染流程的每个单元的匹配。为每个单元寻找一个合适的标识符,能正确匹配渲染流程。 + +### 第一个标识 frame_number +1.ui和1.raster之间联系的标识符是frame_number。 +收藏该两个线程,将这两个线程关联起来进行观察,会在trace上找到这个标识符,这是Flutter应用帧渲染的第一个标识符。 + +- 如果frame_number的标识符未在1.ui和1.raster中出现,表明当前帧不是flutter自渲染,需要重新定界性能问题。 + +![](../media/05/image-3-202.png) + +### 第二个标识 ReuseBuffer/acquire buffer + +1.raster和render_service之间联系的标识符是ReuseBuffer。 +在1.raster线程"flutter::SkCanvas::Flush"的trace过程中,会向RS进程申请buffer内存,用于存储渲染的帧内容。点击"binder transaction"的trace可以跳转到另一个线程,查看对应的ReuseBuffer的id。 + +![](../media/05/image-3-203.png) + + +在render_service线程"RSMainThread::DoComposition"的trace过程中,会获取buffer内存里的帧内存。"acquire buffer sequence"的trace里就能看到和1.raster线程申请的ReuseBuffer编号是一样的。 + +![](../media/05/image-3-204.png) + + + +- 通过上面展示的两个标识,就能识别flutter应用到RS进程上的帧渲染。而RS进程上后面的单元是怎么识别的,目前还没有直观的trace可以看到,默认连续的线程trace是同一帧(即render_service到RSUniRenderThread,再到RSHardwareThread是连续的)。 diff --git a/ohos/docs/05_performance/performance-sliding-response-time.md b/ohos/docs/05_performance/performance-sliding-response-time.md new file mode 100644 index 0000000000000000000000000000000000000000..29e92cda592d62eaf50696b63fd0044380cbe4ae --- /dev/null +++ b/ohos/docs/05_performance/performance-sliding-response-time.md @@ -0,0 +1,61 @@ +# 性能分析-滑动响应时延 + +本篇文章针对flutter应用的滑动场景,进行响应时延的trace分析。请务必先看完这篇指南[性能分析第一步-梳理线程顺序](./performance-threads-sequence.md)再继续。 + +## 准备条件 + +- 了解并能使用性能分析工具[DevEco Studio Profiler](https://developer.huawei.com/consumer/cn/download/) +- 了解线程渲染顺序([性能分析第一步-梳理线程顺序](./performance-threads-sequence.md)) + +## 1. 手指按下 +手指按下是所有点击或滑动事件的大前提,可以知道手指坐标的初始位置和触摸哪个控件等重要信息。 + + +mmi_service线程负责触发多模交互事件,由Flutter应用监听和响应触摸事件。 + + +手指按下的触摸事件,会立即转发给Flutter应用。 + + +在mmi_service线程的"package touchEvent"的trace后面的下一个trace,可以看到"service report touchId:编号, type: down"的trace,type为down,说明是手指按下的触摸事件。而在应用主线程,有"DispatchTouchEvent"的trace,上面有详细坐标打印和触摸事件类型,type数值为0,说明是手指按下的触摸事件。这两个线程上的trace是对应的。 + +![](../media/05/image-4-201.png) + + +## 2.手指滑动 +手指滑动的触摸事件,不会立即转发给Flutter应用,而是由vsync-app信号来控制发送。 + + +和手指按下的trace一样,mmi_service线程和应用主线程都有一样的trace可以对应,只是type类型不一样。type为move,数值为2。 + + +手指滑动的触摸事件需通过flutterSyncName的vsync-app信号触发,之后才能传递到flutter应用主线程。因此,时间顺序是,mmi_service到VSyncGennerator,再到DVSync-app,最后到应用主线程。trace顺序如下图: + +![](../media/05/image-4-301.png) + +- 注意:第一个手指滑动的触摸事件的坐标点和手指按下的触摸事件的坐标点是一样的。 + +## 3.滑动阈值 TouchSlop +TouchSlop是系统所能识别的滑动的最小距离,是一个阈值,称为滑动阈值。用户可以自定义设置控件的滑动阈值,系统默认值是18。 + +那么通过查看应用主线程的触摸事件trace的坐标,可以自行计算坐标偏移量是否达到滑动阈值。 + + +## 4.滑动首帧 +当手指滑动的触摸事件的滑动距离超过设定的滑动阈值时,Flutter应用会触发update操作。但是,实际的绘制操作需要等待下一帧的到来才能执行。所以滑动开始的第一帧渲染,会在触摸事件满足滑动条件后,还需等待一帧的延迟。 + +trace如下图: + +![](../media/05/image-4-401.png) + +## 5.首帧渲染 +渲染的大致过程看[性能分析-帧渲染跟踪](./performance-frame-rendering-tracking.md),需要准确找到对应的trace。 + +帧渲染的结束是在RS进程的RSHardwareThread线程上,但是在自动化测试的时候,帧渲染的结束标识是dpu_gfx_primary线程。(dpu_gfx_primary只是一个硬件信号,不详细讲解) + +trace如下图: + +![](../media/05/image-4-501.png) + + +所以从mmi_service线程的手指按下的trace开始,到滑动首帧渲染结束,这花费的时间就是滑动响应时延。 diff --git a/ohos/docs/05_performance/performance-threads-sequence.md b/ohos/docs/05_performance/performance-threads-sequence.md index e825e57f8ce8b311cc6aea5181a050dfb8ab0939..a75eeb04d2f7a717fc381ea03f0eb3c725413a11 100644 --- a/ohos/docs/05_performance/performance-threads-sequence.md +++ b/ohos/docs/05_performance/performance-threads-sequence.md @@ -14,7 +14,7 @@ Flutter应用在性能分析的时候,需要使用分析工具去抓取应用 ![](../media/05/image-2-201.png) -分析工具按顺序收藏线程后,线程收藏列表如下图: +分析工具按顺序收藏线程后,线程收藏列表如下图: ![](../media/05/image-2-202.png) ![](../media/05/image-2-203.png) @@ -37,13 +37,13 @@ Flutter应用在性能分析的时候,需要使用分析工具去抓取应用 平台的主线,插件代码在这里运行 - flutter'PointerEvent' -flutter的应用主线程发送触摸事件,到1.ui线程处理触摸事件的过程 +flutter的应用主线程发送触摸事件,到1.ui线程处理触摸事件的过程。这个线程可能会不存在。 - 1.ui UI线程,命名为< number >.ui UI 线程在 Dart VM 中执行 Dart 代码。该线程包括开发者写下的代码和 Flutter 框架根据应用行为生成的代码。当应用创建和展示场景的时候,UI 线程首先建立一个 图层树(layer tree) ,一个包含设备无关的渲染命令的轻量对象,并将图层树发送到 GPU 线程来渲染到设备上。 不要阻塞这个线程! 在性能图层的最低栏展示该线程。 -- 1.raster +- 1.raster Raster线程,命名为< number >.raster raster 线程拿到 layer tree,并将它交给 GPU(图形处理单元)。你无法直接与 GPU 线程或其数据通信,但如果该线程变慢,一定是开发者 Dart 代码中的某处导致的。图形库 Skia 在该线程运行,并在性能图层的最顶栏显示该线程。请注意,raster 线程为 GPU 进行栅格化,而线程本身则是在 CPU 上运行的。 @@ -53,11 +53,11 @@ raster 线程拿到 layer tree,并将它交给 GPU(图形处理单元)。 - render_service RS进程的主线程,RS送显的第一步 -- RSUniRenderThread +- RSUniRenderThread RS进程的线程,RS送显的第二步 -- RSHardwareThread +- RSHardwareThread RS进程的线程,RS送显的第三步 -- dpu_gfx_primary +- dpu_gfx_primary 硬件dpu信号 diff --git a/ohos/docs/media/05/image-3-201.png b/ohos/docs/media/05/image-3-201.png new file mode 100644 index 0000000000000000000000000000000000000000..75e39e7b5c49a9fa5dd7c8e6fe03f87e2ba2f617 Binary files /dev/null and b/ohos/docs/media/05/image-3-201.png differ diff --git a/ohos/docs/media/05/image-3-202.png b/ohos/docs/media/05/image-3-202.png new file mode 100644 index 0000000000000000000000000000000000000000..27fcfef57aedc4c3b7e3f81a28416a143afea50a Binary files /dev/null and b/ohos/docs/media/05/image-3-202.png differ diff --git a/ohos/docs/media/05/image-3-203.png b/ohos/docs/media/05/image-3-203.png new file mode 100644 index 0000000000000000000000000000000000000000..c3a7f8b435b552729db0a9877178978d6fb58f33 Binary files /dev/null and b/ohos/docs/media/05/image-3-203.png differ diff --git a/ohos/docs/media/05/image-3-204.png b/ohos/docs/media/05/image-3-204.png new file mode 100644 index 0000000000000000000000000000000000000000..8fe7c5d54f0748b433233faead3de7305897adee Binary files /dev/null and b/ohos/docs/media/05/image-3-204.png differ diff --git a/ohos/docs/media/05/image-4-201.png b/ohos/docs/media/05/image-4-201.png new file mode 100644 index 0000000000000000000000000000000000000000..01620ff423fb6e593593770ad11e310acd01efec Binary files /dev/null and b/ohos/docs/media/05/image-4-201.png differ diff --git a/ohos/docs/media/05/image-4-301.png b/ohos/docs/media/05/image-4-301.png new file mode 100644 index 0000000000000000000000000000000000000000..f89c8e779b01a8baf63095e57a2442833b5f8b97 Binary files /dev/null and b/ohos/docs/media/05/image-4-301.png differ diff --git a/ohos/docs/media/05/image-4-401.png b/ohos/docs/media/05/image-4-401.png new file mode 100644 index 0000000000000000000000000000000000000000..e6a257a1f29d3c1f790b8c7445b24abb72196d10 Binary files /dev/null and b/ohos/docs/media/05/image-4-401.png differ diff --git a/ohos/docs/media/05/image-4-501.png b/ohos/docs/media/05/image-4-501.png new file mode 100644 index 0000000000000000000000000000000000000000..febb98eb48988a30df83e84f7212ba033e64b566 Binary files /dev/null and b/ohos/docs/media/05/image-4-501.png differ