In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces "analyzing Flutter application performance testing and optimization". In daily operation, I believe many people have doubts in analyzing Flutter application performance testing and optimization problems. The editor consulted all kinds of data and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts of "analyzing Flutter application performance testing and optimization". Next, please follow the editor to study!
Layer analysis
Flutter operation mode
1 、 Debug
The Debug mode, which runs on both the real machine and the simulator, opens all assertions, including debugging information, debugger aids (such as observatory), and service extensions. The fast develop/run loop is optimized, but not the execution speed, binary size, and deployment. The command flutter run runs in this mode, building applications through sky/tools/gn-- android or sky/tools/gn-- ios.
2 、 Release
Release mode can only be run on the real machine, not on the simulator: it closes all assertions and debugging messages, and closes all debugger tools. Optimize fast startup, fast execution and reduce packet size. Disable all debugging aids and service extensions. This pattern is designed to be deployed to the end user. The command flutter run-- release runs in this mode, building the application through sky/tools/gn-- android-- runtime-mode=release or sky/tools/gn-- ios-- runtime-mode=release.
3 、 Profile
The Profile mode can only be run on a real machine, not on an emulator, and is basically the same as the Release mode, except that service extensions and tracing are enabled, and something that supports tracing to run at a minimum (such as connecting observatory to a process). The command flutter run-- profile runs in this mode, building the application through sky/tools/gn-- android-- runtime-mode=profile or sky/tools/gn-- ios-- runtime-mode=profile.
4 、 test
Headless test mode can only run on the desktop, basically the same as Debug mode, except that it is headless and you can run it on the desktop. The command flutter test runs in this mode, build through sky/tools/gn.
In the actual development, the four modes mentioned above should be used and divided into two kinds: one is the unoptimized mode for developers to debug, and the other is the optimized mode for the final developer to use. Unoptimized mode is the default, and if you want to turn on optimized mode, add the-- unoptimized parameter after the command line when you want to build.
Whether it is mobile development or front-end development, the idea of performance problem analysis is to analyze and locate the problem first, and Flutter is no exception. With the performance measurement tool provided by Flutter, we can quickly locate the performance problem in the code, and the performance layer is a sharp tool to help us identify the impact scope of the problem, which is similar to Android's layer analysis tool.
In order to use the performance layer, Flutter provides Profile mode. Unlike debugging code, which can find the code logic Bug in debug mode through the simulator, performance problems need to be detected by real machine in release mode. Debug mode adds a lot of additional checks (such as assertions) compared to Release mode, which can be resource-intensive; more importantly, debug mode uses JIT (just-in-time) mode to run applications, resulting in inefficient code execution. This makes the application running in debug mode can not really reflect its performance problems.
On the other hand, the instruction set used by the simulator is x86, while the instruction set used by the real machine is ARM. Because the binary code execution behavior of the two methods is completely different, the performance of the simulator is quite different from that of the real machine. Some x86 instruction sets are good at operating simulators that are faster than real machines, while others are slower than real ones, which makes it impossible for us to use simulators to evaluate performance problems that can occur on real machines.
In order to debug the performance problem, we need to provide a small amount of necessary application tracking information for the analysis tool on the basis of the release mode, which is the analysis pattern. Except for some necessary tracking methods for debugging performance problems, the analysis mode and release mode of Flutter applications compile and run similarly, except that the startup parameters are changed to profile. We can start the application in Android Studio by clicking the [Run]-[Profile] 'main.dart' option in the menu bar, or we can run the Flutter application with the command line parameter flutter run-- profile.
Analysis of rendering problem
After the application is launched, we can use the rendering problem analysis tool provided by Flutter, namely performance layer (Performance Overlay), to analyze the rendering problem. The performance layer will be on the top layer of the current application, showing the execution charts of GPU and UI threads in a self-drawn way by the Flutter engine, and each chart represents the performance of the last 300 frames of the current thread. If UI produces stutters (frame skips), these charts can help us analyze and find the reasons, as shown in the following figure.
The image above illustrates the presentation style of the performance layer. Where the performance of the GPU thread is above, the situation of the UI thread is shown below, the blue vertical line represents the normal frame that has been executed, and the green line represents the current frame.
At the same time, in order to maintain the refresh rate of 60Hz, the time it takes to execute each frame in both the GPU thread and the UI thread should be less than 16ms (1max 60 seconds). One of these frames takes too long to process, which will lead to interface stutters, and a red vertical bar is shown in the chart, as shown in the following figure.
If the red bar appears in the GPU thread chart, it means that the rendered graph is too complex to render quickly, while if it appears in the UI thread chart, the Dart code consumes a lot of resources and the code execution time needs to be optimized.
GPU problem location
The problem of GPU rendering is mainly time-consuming in the underlying rendering. Sometimes although the Widget tree is easy to construct, it is very time-consuming to render under the GPU thread. For example, multi-view overlay rendering such as Widget cropping, masks, or repeated drawing of still images due to lack of cache can significantly slow down the rendering speed of GPU.
Next, check for both cases using the two parameters provided by the performance layer, the view rendering switch checkerboardOffscreenLayers that checks the multi-view overlay and the image switch checkerboardRasterCacheImages that checks the cache.
CheckerboardOffscreenLayers
Multi-view overlay usually uses the savaLayer method in Canvas, which is very useful when implementing certain effects (such as translucency), but its underlying implementation involves repeated rendering of multiple layers in GPU rendering, which will cause big performance problems.
For checking the use of the saveLayer method, we only need to set the checkerboardOffscreenLayers switch to true in the initialization method of MaterialApp, and the analysis tool will automatically help us detect multi-view overlay. Widget that uses saveLayer automatically displays in chessboard format and flashes as the page refreshes. However, saveLayer is a relatively low-level rendering method, so we don't usually use it directly, but indirectly through some functional Widget in scenes that involve clipping or translucent masks. So once we encounter this situation, we need to think about whether it is necessary to do this, and whether it can be achieved in other ways.
For example, in the following example, we use CupertinoPageScaffold and CupertinoNavigationBar to achieve a dynamic blur effect, as follows:
CupertinoPageScaffold (navigationBar: CupertinoNavigationBar (), / / dynamic blur navigation bar child: ListView.builder (itemCount: 100, / / create 100 different colors of RowItem itemBuilder: (context, index) = > TabRowItem (index: index, lastItem: index = = 100-1, color: colorItems [index], / / set different colors colorName: colorNameItems [index] )))
The blurred NavigationBar effect is shown in the following figure.
When we turn on checkerboardOffscreenLayers, we can see that the rendering pressure of the view mask effect on GPU causes the performance view to flash frequently. If we do not have special requirements for dynamic blur effects, we can use Scaffold without blur effects and white AppBar to achieve the same product features to solve this performance problem.
Scaffold (/ / use plain white AppBar appBar: AppBar (title: Text ('Home', style: TextStyle (color:Colors.black),), backgroundColor: Colors.white), body: ListView.builder (itemCount: 100, / / create RowItem itemBuilder: (context, index) = > TabRowItem (index: index, lastItem: index = = 100-1, color: colorItems [index] / / set different colors colorName: colorNameItems [index],),)
After running the code, you can see that after removing the blur effect, the rendering pressure of GPU is relieved, and the checkerboardOffscreenLayers detection layer is no longer flickering frequently.
CheckerboardRasterCacheImages
From a resource point of view, another type of operation that consumes a lot of performance is rendering images, because image rendering involves I GPU storage and data format conversion in different channels, so the construction of the rendering process consumes a lot of resources. To ease the pressure on GPU, Flutter provides multi-level cache snapshots so that there is no need to redraw still images when Widget is rebuilt.
Similar to checking the checkerboardOffscreenLayers parameters of multi-view overlay rendering, Flutter provides a switch checkerboardRasterCacheImages to check cached images to detect images that flicker frequently during interface redrawing.
In order to improve the performance of still image display, we can add images that need static cache to RepaintBoundary. RepaintBoundary can determine the redrawing boundary of the Widget tree. If the image is complex enough, the Flutter engine will cache it automatically to avoid repeated refreshes. Of course, because of limited cache resources, RepaintBoundary may also be ignored if the engine believes that the image is not complex enough. The following code shows the specific use of adding a static composite Widget to the cache through RepaintBoundary, as shown below.
RepaintBoundary (/ / set static cache image child: Center (child: Container (color: Colors.black, height: 10.0, width: 10.0,))
UI thread problem location
If the GPU thread problem locates the underlying rendering exception of the rendering engine, then the UI thread problem finds the performance bottleneck of the application. For example, when building a view, some complex operations are used in the build method, or the synchronous IBANO operation is performed in the main Isolate. All these problems will significantly increase the processing time of CPU and slow down the response speed of the application.
To solve this kind of problem, we can use the Performance tool provided by Flutter to record the execution trajectory of the application. Performance is a powerful performance analysis tool that can display the call stack and execution time of CPU in a timeline to check for suspicious method calls in your code.
After opening the "Open DevTools" button in the toolbar at the bottom of the Android Studio, the system will automatically open the Dart DevTools web page, and after switching the top tab to Performance, we can begin to analyze performance problems in the code.
Next, we demonstrate the specific analysis process of Performance through an example of calculating MD5 in ListView. Considering that it is a common operation to assemble rendering information in the build function, in order to demonstrate the use of Performance, we deliberately magnify the time-consuming calculation of MD5, such as loop iteration for 10,000 times.
Class MyHomePage extends StatelessWidget {MyHomePage ({Key key}): super (key: key); String generateMd5 (String data) {/ / MD5 fixed algorithm var content = new Utf8Encoder (). Convert (data); var digest = md5.convert (content); return hex.encode (digest.bytes) } @ override Widget build (BuildContext context) {return Scaffold (appBar: AppBar (title: Text ('demo')), body: ListView.builder (itemCount: 30 itemBuilder / number of list elements itemBuilder: (context, index) {/ / iterative calculation MD5 String str =' 1234567890abcdefghijklmnopqrstuvwxyzhuang; for (int I = 0pheri
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.