1
头图

Introduction This article mainly focuses on the common cross-end technologies Flutter, ReactNative, Weex, H5, and analyzes from the technical characteristics, basic architecture, compilation principle, basic rendering process, etc.; and how to optimize and solve some common performance problems, and then how to make technical selection or What is the logic of choosing different technology stacks when doing business development.

01
Background In this year's agile team building, I implemented one-click automated unit testing through the Suite executor. What other executors does Juint have in addition to the Suite executor? This is where my Runner exploration journey begins!

With the development of technology, more and more terminals have emerged, such as Android, iOS, Mac, Windows, Web, Fuchsia OS, Hongmeng, etc., and with the development of the company's business, more and more business scenarios have emerged; As an APP developer, it is inevitable to encounter the following problems in daily work, such as: 1. When UI designers are conducting UI reviews, test students are in the process of regression testing, and business parties are using the process, they will find the end and end to some extent. There are differences, which affect the user experience; 2. The same business and the same function are on different terminals, and each terminal needs to invest resources to develop and implement. The development of the mobile Internet is already in the late stage, and leaders are more and more concerned about input and output.

At the same time, some cross-end technical solutions have emerged, which can implement a set of codes to run on multiple ends and solve the pain points of business development, such as Flutter, ReactNative, Weex, H5 (Note: Mini Programs and other DSL-based solutions are temporarily unavailable. the scope of this article). Then, a comparative analysis of some commonly used APPs was carried out. The conclusions were consistent with expectations, and most of them were using cross-end technology; Flutter and ReactNative had high usage rates, Weex usage rates were relatively low, and H5 was basically used, using a variety of cross-end technologies. Technical frameworks are the norm. So, what are their characteristics?

02
Introduction to the characteristics of the four technology stacks

Understand, first of all, MCube will judge whether the latest template needs to be obtained from the network according to the template cache status. When the template is obtained, the template will be loaded. In the loading stage, the product will be converted into the structure of the view tree. After the conversion is completed, the expression will be parsed by the expression engine and Obtain the correct value, parse the user-defined event through the event parsing engine, complete the event binding, complete the parsing assignment and event binding, and then render the view, and finally display the target page on the screen.

图片

Figure 1 - Technology stack features

Through Figure 1, the main features of them are sorted out from the aspects of performance, development language, rendering, package size, community, support platform, etc. Several questions arise: why are native and Flutter better? Why are ReactNative and Weex relatively poor performance? Why are H5 pages slow to load? How to optimize these performance problems is a problem that requires in-depth understanding. The following will analyze the basic architecture, rendering process, and compilation and operation principles.

03
Introduction to Infrastructure

3.1 Introduction to Flutter Infrastructure

ABM is one of the distribution channels for iOS applications provided by Apple. Unlike the App Store platform, ABM is a brand-new application distribution system that was launched in China in October 2019. Some functions are similar to enterprise accounts. Provides enterprises with a fast and efficient way to deploy applications to enterprise-owned Apple devices. The key differences between the two platforms of ABM and the App Store are as follows:

图片

Figure 2 - Flutter infrastructure

Google released Flutter 1.0 in 2018, as shown in Figure 2, which is mainly divided into Framework layer and Engine layer;

Framework layer: Based on Dart implementation, it mainly includes various Widgets such as Text, Image, Button, animation, gesture, etc., core basic class libraries io, async, ui and other packages; App is developed based on Framework, which runs on the Engine layer, Framework and logic The layers are developed based on the Dart language. For development, everything is a Widget, and Widget is the basis of UI implementation; Engine layer: based on C++, C implementation; mainly including Skia rendering engine library, Dart Runtime, Text text rendering library, etc., The Engine layer comes with the Skia rendering engine to achieve unified rendering and display on all sides, and adapt to platform differences and cross-platform support in the Engine layer to achieve a more perfect cross-end effect; Dart code is compiled into the binary code of the running platform through AOT. That is to say, Flutter does not need bridging, and completes all the capabilities from the logic side and the rendering side by itself, which is similar to the native one. This is also the key to its outstanding performance. In addition, Android comes with the Skia engine, so the compiled product on Android is smaller than iOS. In addition to supporting mobile terminals, it also supports Mac OS, Windows and other PC and web terminals, and Dart is also supported in the new Funchsia OS, using Flutter as the UI framework.

For Flutter Web, the Framework layer is public, which means that the business layer can use the widgets of this layer to achieve logical cross-end; but the Engine layer is different, and requires the ability to align the Engine through Canvas Render or HTML Render. In May 2022, the Google IO conference will release Flutter 3.0. In addition to the mobile terminal, it better supports the Mac OS and Linux platforms, as well as a series of other optimizations and supports. You can pay more attention.

3.2 Introduction to ReactNative Infrastructure

ABM is one of the distribution channels for iOS applications provided by Apple. Unlike the App Store platform, ABM is a brand-new application distribution system that was launched in China in October 2019. Some functions are similar to enterprise accounts. Provides enterprises with a fast and efficient way to deploy applications to enterprise-owned Apple devices. The key differences between the two platforms of ABM and the App Store are as follows:

图片

Figure 3 - ReactNative infrastructure

ReactNative was open sourced by Facebook in 2015. As shown in Figure 3, it mainly serves both Android and iOS. It uses React to develop the logic side code (which can also be applied to the front end), uses Redux to achieve state management, and uses UI rendering in the APP. Network requests, animations, etc. are all implemented by the native side bridge; in the actual operation process, the DOM on the js side will form a virtual DOM, and the DOM structure will be transmitted to the native side through the bridge bridge, and the native side will parse and map to the native side. Controls, after forming the native DOM structure, call the native capabilities for rendering and display.

The new version of ReactNative in 2021 has refactored the bottom layer, you can pay attention to it, such as changing the threading model, introducing asynchronous rendering capabilities, allowing multiple renderings and simplifying asynchronous data processing, simplifying JSBridge, etc.

3.3 Introduction to Weex Infrastructure

图片

Figure 4 - Weex infrastructure

Weex is a cross-end framework released by Alibaba in 2016. As shown in Figure 4, the js bundle compiled by Weex can be deployed on the server, and the APP can be run after loading. It can also be seen that it has the ability to dynamically publish; similar to ReactNative, Weex In the actual operation process, the js side will form a dom, which will be parsed by the native side through the Bridge, mapped to the native controls and then rendered by the native capabilities; Weex is based on the JS V8 engine, based on the Vue design, and supports Android, iOS, and Web. end. 3.4 Introduction to WebView Infrastructure

图片

Figure 5-WebView core infrastructure The WebView core module is more complex, as shown in Figure 5, here are the main parts of the WebView architecture: The bridge protocol is the communication layer between the upper-level logic test and WebView, and is the ability of JS and Native to communicate with each other Floor;

WebCore is the basis for browser loading and layout rendering of pages, mainly including resource loading, HTML parsing, CSS parsing, DOM parsing, layout rendering, etc. JavaScript engine is a JavaScript parser, JavaScriptCore is Webkit's JavaScript engine, and V8 is Google's Blink. The default engine; WebKit Ports is the transplanted part of WebKit, including modules such as network, font, image decoding, audio and video decoding, hardware acceleration, etc.; and then many third-party libraries are used, including 2D graphics library, 3D graphics library, network Libraries, storage libraries, audio and video libraries, etc.; the bottom layer is the operating system, which supports Android, iOS, Windows and other systems.

3.5 Analysis of Compilation Principle

Flutter supports Release, Profile, and Debug compilation modes.

The Release mode uses the AOT precompiled mode, precompiles it into machine code, generates the code of the corresponding architecture by compiling, and directly runs the corresponding machine code on the user device, with fast running speed and good execution performance; this mode closes all debugging tools, Only real devices are supported. For the compiled products, the iOS side mainly generates App.framework and Flutter.framework; App.framework is the dart code compilation product, and Flutter.framework is the engine compilation product; the Android side mainly adds libapp.so and libflutter.so, libapp under lib .so is the dart code compilation product, and libflutter.so is the engine compilation product. The difference is that flutter_assets is added under assets to store reference resource files.

The Profile mode is similar to the Release mode. The most important role of this mode is that you can use DevTools to detect the performance of the application and perform performance debugging and analysis.

Debug mode uses JIT instant compilation technology, supports the common development and debugging function hot reload, and is used during development and debugging, including supported debugging information, service extensions, Observatory, DevTools and other debugging tools, and supports simulators and real machines. The iOS side mainly generates App.framework and Flutter.framework. There are more isolate_snapshot_data, kernel_blob.bin, and vm_snapshot_data in the App.framework folder. The Android side also has more of the above files, but the libapp.so file is missing from the lib.

ReactNative is divided into a logic side and a rendering side. The logic side is based on the js engine, which compiles the code written based on React into JavaScript native code, and then compiles and generates a jsbundle file, which is built in or sent to the APP side to run; the rendering side depends on Android Or iOS native rendering, the corresponding compiled products need to be compiled on different platforms, and then published to the server or built into the APP.

Weex is similar to ReactNative. Weex will compile the source code into js bundles. These js bundles can be deployed on the server. After the APP downloads the js bundles, it builds a virtual dom through the js engine and maps it to the native dom through the bridge, which is rendered by the native rendering engine. .

H5: Taking React and Vue as an example, the code developed with the framework will be compiled into JavaScript native code, that is, and then executed in the browser or WebView; the kernel will first establish a connection, load resources, and then parse, layout, draw, render and present to users. 3.6 Comparison of Basic Rendering Processes

图片

Figure 6 - Basic rendering process comparison

Simply analyze the rendering process, develop APPs based on Android and iOS natively, call the Framework framework layer to implement the upper-level logic, and directly call the system rendering engine for rendering and display after layout drawing; develop APPs based on Flutter, will directly call the Skia rendering engine for rendering and display; no Depends on native rendering.

The development of APP based on ReactNative or Weex is different. First, the business logic is developed based on React or Weex, and then the js bundle is preset or downloaded to the APP, and then the virtual dom is mapped to the native control through the bridge, and then the native rendering engine is called for rendering. exhibit.

The development of APP based on the Hybrid solution needs to be implemented through front-end frameworks such as React and Vue. The home page should be compiled into JavaScript native language, and then the page should be loaded in the WebView or browser through the link. The key process is connection loading, parsing, typesetting, drawing, and finally Adjust the rendering engine for display.

With all of the above analysis, the questions posed earlier can be answered:

Why native and Flutter perform better? The main thing is to directly adjust the system or bring its own rendering engine to display after layout drawing.

Why ReactNative and Weex performance is relatively slow? The main thing is to download the js bundle and map the js dom structure analysis to the native one. Downloading and presetting are time-consuming and relying on native rendering (the new version of ReactNative has upgraded the infrastructure, which is said to have a great performance improvement. Everyone also follow).

Why are H5 pages slow to load? Mainly because the connection and loading are time-consuming, which takes up most of the time here. After the connection and loading are completed, it is basically the work that can be done locally by the WebView or the browser, and post-optimization can also be used as an entry point.

04 Optimization of common main performance problems

In the actual development process, we also encountered some performance problems, which will be briefly introduced next.

4.1 How to optimize Flutter performance?

Key optimization indicators: page exception rate, page FPS frame rate, page loading time.

Page exception rate (number of exceptions/number of PVs on the entire page): Through the two methods of runZoned and FlutterError, count the number of exceptions and stack data in the exception interception method.

Page FPS frame rate: How to collect FPS is the key. By registering the onReportTimings callback through the window object, you can get the time-consuming of the entire construction and rendering process, and then you can calculate the FPS of the page.

Page loading time (page visible time - page creation time): The page visible time is obtained through the addPostFrameCallback callback of WidgetsBinding, and the page creation time is obtained through the page initialization method initState.

Upload the above data to the monitoring and performance analysis platforms (mPaaS and Candle Dragon) as reference data for later performance analysis and optimization. During the development process, you can use the DevToos performance analysis tool and Flutter Inspector to analyze and optimize performance. On-demand loading and partial refresh are also commonly used optimization methods. Other performance optimizations such as layout loading optimization, state management optimization, startup optimization-engine preloading, memory optimization, package size optimization, etc. will not be introduced in detail. You can pay more attention to the Flutter community and regularly upgrade the Flutter version, which will bring good harvest.

4.2 How to optimize the slow loading of ReactNative?

First, the bundle package can be pre-downloaded to reduce the loading time of the package, and the page can be directly mapped and rendered, so as to achieve the purpose of opening the page faster. Of course, the package can also be preset, and it is necessary to balance the package size and performance;

The second is to try to upgrade the latest version of ReactNative. The new version upgrades the infrastructure, mainly including the thread model, the introduction of asynchronous rendering capabilities, and the optimization of JSBridge, which has significantly improved performance (the author consulted the Jingdong mPaaS team and is also following up).

4.3 How to optimize the slow loading of H5 in APP

图片

Figure 7 - Introduction to the process of loading H5

Figure 7 describes the entire process from the initialization of WebView to the final rendering of the H5 page, and analyzes the basic rendering process of the previous H5. There are two main points in the time-consuming link, one is the initialization of WebView, which can be optimized by initializing WebView in advance; the other is the request connection and loading of resources (html, js, css\images, etc.), which can be solved with the H5 offline package solution The problem, through the preloading of resources, solves the loading problem of html, js, css and resource images, thereby greatly reducing the loading time of resources, improving page loading performance, and even achieving the effect of opening in seconds.

05Summary

So how to choose technology? It should be considered on the premise of improving development efficiency and user experience, and then analyze the key factors:
1. What is the infrastructure of the technology stack, whether the original architecture is excellent, and whether it is more future-oriented;
2. The maturity of the team's technology stack, the cost of learning, and the maturity of the community;
3. R&D efficiency, realize multi-terminal code reuse, reduce multi-terminal differences, reduce development costs, and focus more on business development; and efficiency improvement is a continuous revenue process, which is reflected in the entire life cycle of business development. Of course, there will be some costs for new technologies in the early stage of practice, but the total benefits after familiarity are long-term;
4. Whether it is better to solve the multi-end consistency, better solve the problems of end and end found by UI designers during UI review, test students during the testing process, and business parties during the use process, and the unified style is also a good user experience. important manifestation;
5. Supporting the degree of dynamism and solving the problem that new requirements must be released are also the pain points and key factors of the business;
6. The user experience is the most critical, and the user's usage environment (network environment, mobile phone configuration), etc. must also be considered; for a formal C-side project, in the face of tens of millions or even hundreds of millions of users, the technology selection strategy must be in To achieve cost reduction and efficiency improvement on the basis of ensuring user experience, users first, maximizing user interests ensures the interests of the company; for non-C-side projects, it may be necessary to consider improving user experience on the basis of cost reduction and efficiency improvement.

Author of this article: Jingdong International Technology R&D Department - Lu Xu, Zhang Gong, Yao Feng, Gao Xinpeng, Li Chengfeng, Chen Haijiao, Gao Ming, Fan Weilian, Shan Yuqin, Mu Xinjian


京东云开发者
3.4k 声望5.4k 粉丝

京东云开发者(Developer of JD Technology)是京东云旗下为AI、云计算、IoT等相关领域开发者提供技术分享交流的平台。