36 the Current State and Application of Cross Platform Development

36 The Current State and Application of Cross-Platform Development #

In 2016, I attended two mobile technology conferences, and at that time, native development seemed to be booming at the GMTC conference.

Fast forward to 2017, HTML5 performance has improved, and cross-platform solutions like Facebook’s React Native and Alibaba’s Weex are being implemented in more and more companies. WeChat mini programs have dealt a heavy blow to native development, and many small companies may no longer need to develop their own applications.

“Write once, run anywhere.” People’s attempts at cross-platform development have never stopped. Especially in this era of fragmented end terminals, the appeal of being able to run code on different system versions of the same platform, or even on different platforms, is becoming greater and greater for developers.

Looking back, the battle between HTML5 and Native development has been going on for nearly ten years. What is their current situation? What are the advantages of React Native and Weex, and what problems do they face? Can mini programs truly dominate the market? How should anxious Native development seek development under this trend?

Current Status of Cross-Platform Development #

Starting from 2017, the “Mobile Technology Conference” (GMTC) has been renamed as the “Front-End Technology Conference”. From the current perspective, front-end development and native development are not replacing each other, but rather merging. The result of this fusion is called the “front-end”. In order to adapt to this trend, many large companies have made corresponding organizational adjustments, merging front-end teams with iOS and Android teams to form front-end teams.

Mobile web technology, React Native and Weex, and mini-programs are currently the most commonly used cross-platform development solutions. Let’s take a look at their current application status. Of course, for the hottest Flutter technology this year, I will dedicate a separate section to introduce it later.

1. Web

Since the desktop era, web technology, which is built on browsers, has the advantages of cross-platform compatibility, dynamic updates, and strong extensibility. With the improvement of mobile device performance, the performance of web pages has gradually become acceptable. More and more embedded web pages are appearing in client applications, and many applications convert certain functional modules into web implementations.

Browser Engines

A web page consists of HTML + CSS + JavaScript, which are executed and rendered by the browser engine to create the user interface expected by the developer.

The browser engine mainly includes two major functions, which are:

  • Browser Rendering Engine. The browser rendering engine is responsible for processing HTML and CSS according to the W3C standards.

  • JavaScript Engine. The JavaScript engine is responsible for processing JavaScript according to the ECMAScript standards.

These two components are independent of each other but closely integrated. Additionally, their implementations in different browser engines may vary. However, with Microsoft announcing the switch of its Edge browser engine to Chromium, the battlefield is now mainly dominated by Apple and Google. Their browser rendering engines are Webkit and Blink (which is actually forked from Webkit), and their JavaScript engines are JavaScriptCore and V8, respectively.

The rendering process of a browser may not be familiar to many Android developers. Generally, HTML, CSS, JavaScript, and other resources used in the webpage (such as images, videos, and fonts) need to be downloaded from the network. HTML is parsed into the DOM, CSS is parsed into the CSSOM, JavaScript is executed by the JavaScript engine, and finally the DOM and CSSOM are combined to form a Render Tree.

Of course, the entire rendering process of a browser cannot be explained in a few words. Here are some good reference materials I found, for those who are interested in diving deeper:

Although Chromium is open source, due to its complexity, there are very few people in China who have in-depth research on it, and even fewer people who have the ability to customize and modify it. Therefore, a large amount of manpower and resources are needed in this area. The most well-known ones in China are the U4 kernel of UC Browser and the X5 kernel of Tencent Browser. Performance Status

The cross-platform solution based on WebView for H5 has obvious advantages. However, performance is currently its biggest issue, mainly manifested in the following two aspects:

  • Startup white screen time. WebView is a very heavyweight control, and both its initialization and rendering process are time-consuming. This leads to a period of white screen time during the interface startup, resulting in a poor user experience.

  • Responsiveness. Due to reasons such as single-threaded nature and historical baggage, the rendering and JavaScript execution efficiency of the pages are not as good as native. In some scenarios with heavy interaction or complex animations, the performance of H5 still cannot meet the demand.

Therefore, on the mobile side, H5 is mainly applied in scenarios with less complex interaction. Generally speaking, even if the frame rate is not as good as native, it still meets the basic requirements. From my personal experience, the biggest problem with H5 currently lies in the startup white screen time.

For the process of Android interface startup, in most cases, the page rendering has already been completed before the window animation ends. When starting an Activity interface, we generally require it to be completed within 300 milliseconds.

Startup Process

Let’s review the rendering process of the browser kernel. We can actually divide the whole process into three parts:

  • Native time. This mainly includes the time for Activity creation, WebView creation, and WebView initialization. Although the time for the initial creation of WebView may be longer, the overall native time is controllable.

  • Network time. This includes the time for DNS resolution, TCP connection establishment, SSL establishment, and downloading the main document. When parsing the main document, synchronous downloading of the CSS and JS resources that the main document depends on, as well as necessary data, is also required.

  • Rendering time. The time for the browser kernel to build the Render Tree, perform layout, and render to the screen.

Rendering Process

As shown in the above diagram, we are more concerned about the time T2 when the user sees the complete page. Here, the T2 second-rate can be used as a measure of the startup speed.

Optimization Methods

Achieving a T2 second-rate of over 90% for native interfaces is not difficult. In comparison, for most non-optimized web pages, the T2 second-rate may be below 40%, and the difference is quite significant.

So how should we optimize? From the perspective of frontend, common optimization methods include:

  • Speed up request speed. Among the entire startup process, network time is the most uncontrollable. There are many optimization methods in this area, such as pre-resolving DNS, reducing the number of domain names, reducing the number of HTTP requests, CDN distribution, request reuse, lazy loading, Gzip compression, and image format compression.

  • Code optimization. The smaller the size of the main document, the better (requiring less than 15KB). This requires us to optimize HTML, CSS, and JS code. Taking JS as an example, there are really too many frontend libraries and frameworks, and we may accidentally introduce various dependent frameworks. For core pages, we require the use of only native JS or very lightweight JS frameworks, such as using Preact with only a few KB instead of a large React framework.

  • SSR. Regarding the rendering process of the browser, I described the CSR rendering mode above, where the server only returns the basic framework of the web page. In fact, there is another very popular SSR (Server-Side Rendering) rendering mode, where the server can generate HTML that can be rendered directly all at once. In this way, before T2, we can achieve only one network request. However, the cost is an increase in server computing resources. Generally, we solve the issue of access volume by placing a CDN in front of the server.

With the above optimizations, especially the “ultimate trick” SSR (Server-Side Rendering), achieving a 70% T2 (Time to Interactive) rate is not very difficult.

The front-end team has done everything they can. So what else can we do? This is where client-side development comes in.

  • WebView pre-creation: Pre-create and initialize WebViews, and implement WebView reuse. This can save around 100-200 milliseconds.

  • Caching: H5 has multiple levels of caching. For example, Memory Cache stores data in memory, and resources are added when they arrive and released when the page is closed. Client Cache refers to client-side caching, such as the commonly used offline package solution. The data that needs to be requested from the network is sent to the client in advance, and it is loaded by intercepting the browser’s resource requests. HTTP Cache is a caching mechanism that we are familiar with, while Net Cache refers to caching of DNS resolution results or preconnection results.

In terms of performance, the hierarchy of caching is Memory Cache > Client Cache >= HTTP Cache > Net Cache. Caching means that before the user actually clicks to open a page, the data and resources are downloaded to local memory or disk in advance, and they are placed in the corresponding cache of the kernel. For example, even if we use SSR, we can still download the pre-rendered HTML before the user clicks, so that when the user actually opens the page, there is no network request at all.

With the optimization of pre-fetching, even for complex pages, the T2 rate can reach over 80%. However, since it is a pre-fetching mechanism, we may encounter cache miss issues, and the server will have additional unfulfilled requests. Therefore, we need to find a balance between client performance and server load.

Is there any further room for optimization? At this point, we need to go deeper into the underlying layers and have the ability to customize, modify, and optimize the kernel. For example, many official browser kernels may not expose certain APIs, but Tencent and UC kernels may have many special interfaces.

  • Managing all network requests: We can not only manage GET requests from the browser, but also take over all POST requests, allowing us to make many customized optimizations.

  • Private interfaces: We can expose many non-public interfaces of the browser. Take pre-rendering as an example, I can specify that a certain page is rendered directly in memory. When the user actually opens it, we only need to perform a refresh, achieving a true “instantaneous” experience.

  • Compatibility and security: Android’s fragmentation causes compatibility issues with browser kernels, and old versions of kernels still have many security vulnerabilities. Having an application’s own browser kernel can solve these problems, and higher versions of kernels will also have more complete features, such as supporting TLS 1.3, QUIC, etc. However, the cost is an increase in the size of the installation package by about 20MB, but we can also use dynamic downloading methods.

Customized proprietary pages + customized browser kernels + extreme optimizations can achieve a T2 rate of over 90% even for complex pages, and the average T2 time can be less than 400 milliseconds.

2. React Native and Weex

H5 cross-platform solutions based on WebView have achieved good performance through almost crazy optimizations. However, in some scenarios with complex interactions and animations (such as horizontal swiping and gestures), the performance is still not sufficient.

Facebook open-sourced React Native in 2015. It abandons WebView and uses JavaScriptCore for bridging, converting JavaScript calls into native calls. In other words, React Native will eventually generate corresponding customized native controls and follow the system’s native rendering process.

In 2016, Alibaba also open-sourced Weex. Its approach is similar to React Native, but it uses Vue as the upper-level DSL. There are many articles online about the architecture of Weex and React Native, such as “Where to Go Next for Front-End Development?” and “Weex Technical Evolution”.

But is there a perfect solution in the world? In order to achieve performance and interactive experiences similar to native development, React Native/Weex inevitably sacrifice cross-platform and dynamic aspects.

React Native and Weex connect to the front-end ecosystem and native rendering, making it seem like a perfect solution. However, it’s not easy to eliminate the differences between front-end and client-side, especially between Android and iOS in the client-side. Forcing integration will encounter various pitfalls.

“From Learning React Native to Giving Up” is the voice of many developers. Last year, both Airbnb and Udacity announced their abandonment of React Native. React Native/Weex did not completely solve the cross-platform problem, and considering the need for external sharing and downgrading disaster recovery, we still need to develop an H5 version of the page.

To solve this problem, React Native users need to introduce a layer of heavy middleware to help iron out these differences. Examples include JDReact from JD.com and Ctrip React Native from Ctrip.

Since React Native and Weex sacrifice cross-platform, can their performance and interaction align with native development? Unfortunately, currently, I think their performance mainly has two bottlenecks:

  • JS execution time. React Native and Weex use the JavaScriptCore engine. Although it makes progress every year, JS is an interpretive dynamic language, and its execution efficiency is still several times worse than AOT-compiled Java.

  • Cost of cross-language communication. Since it needs to connect the front-end and native ecosystems, it is unavoidable to have frequent communication and conversion between JS -> C++ -> Java/Objective-C. Therefore, various serialization will be involved here, which has a greater impact on performance.

Although React Native and Weex have made great strides in performance compared to H5, they still face issues such as slow startup time and inferior frame rate compared to native development. They belong to a relatively moderate solution and also have their own use cases. For example, some secondary pages (such as Taobao’s sub-venue) have important business functions but don’t require complex interactions while still hoping to maintain some dynamism.

Of course, Facebook has already recognized React Native’s various performance issues and is currently in the process of crazy refactoring. They hope to make React Native lighter and more suitable for hybrid development, approaching or even achieving the native experience. There isn’t much information disclosed by Facebook at the moment, but those interested can refer to “In-depth Analysis of React Native’s Next-Generation Architectural Refactoring”.

3. Mini Programs

In early 2017, Zhang Xiaolong announced the birth of WeChat Mini Programs. Now, two years have passed, and the ecosystem of mini programs has been developing healthily.

Every application dreams of becoming a super app, so all major companies have launched their own mini program frameworks: WeChat, device manufacturers, Alipay, Toutiao, Baidu, Taobao, Google Play, making the battlefield of mini programs into a “Seven Kingdoms War.”

But mini programs do not belong to a unified cross-platform development solution. People value their channel advantages and consider how to gain more traffic and users through WeChat, Alipay, and other popular apps. From a technical perspective, the framework technology of mini programs is also open, and we can use H5 solutions, React Native, Weex, or even Flutter.

In practice, let’s take a look at the differences of WeChat Mini Programs, Quick Apps, Alipay Mini Programs, and Baidu Mini Programs that have already officially launched (there is not much public information about the technical aspects, but you can refer to “Alipay Mini Program Framework”).

Apart from the distinctive Quick Apps, the technical solution for other mini programs has basically followed WeChat’s lead. But considering the performance issues of H5 in some scenarios, they utilize the same-layer rendering ability provided by the browser kernel to support some native controls on top of WebView. If one day WeChat Mini Programs support all native controls, it will become another set of React Native/Weex solutions.

“Disaster befalls the commoners when immortals fight.” If we want to gain traffic from all mini program vendors, we will have to develop seven different mini programs. However, fortunately, both Alipay Mini Programs and Quick Apps hope that the existing WeChat Mini Programs can be quickly migrated to their platforms. Therefore, their DSL designs have also followed WeChat’s syntax, and it can be said that WeChat’s DSL has become the de facto standard.

As shown in the above figure, we hope to have a solution that can integrate all mini program frameworks, allowing us to develop once and generate different mini programs. Chameleon from Didi and Taro from JD.com are dedicated to solving this problem, and they have already been open-sourced on GitHub.

Cross-Platform Development Applications #

Since the birth of mobile development, cross-platform development has been a goal pursued by many. We can take a look at an article written by nwind in 2015, titled “Various Technologies for Cross-Platform Development on Mobile Platforms” (http://fex.baidu.com/blog/2015/05/cross-mobile/). Now, four years have passed, and most of the points raised in the article still hold true, and even from the introduction of Dart at the end, we can see the embryonic form of Flutter today.

1. Scenarios for Cross-Platform Development

Android, iOS, PC – people have different operating habits and preferences across different platforms. For large companies, fully implementing cross-platform development may be a pseudo proposition, as the UI and interaction of applications on different platforms are not the same.

So after pursuing cross-platform development for so many years, what are we hoping to achieve? Based on my experience, the main applications for cross-platform development are:

  • Partial Business. Sharing a certain business or page across platforms, and sometimes even across applications. For example, during the “Millionaire Quiz”, this feature can be seen running within various applications in the Toutiao system. It is highly significant for a company to use the same cross-platform solution, as business can be tried out in different applications.

  • Core Functionality. C++ is the most tenacious cross-platform solution, and large companies are increasingly migrating more core modules to the bottom layer, such as network libraries, data reporting, encryption and decryption, and audio and video.

2. Cross-Platform Development Comparison

H5’s cross-platform solution allows for the development of applications with decent performance and functionality with relatively low development costs. However, if we want to achieve optimal optimization, it is easy to find that there are relatively few things that developers can control, and both performance and functionality rely on the support of the browser.

At this point, if we want to go further, we not only need to understand the internal mechanism of the browser but may also need the ability to customize and modify the browser kernel. This is also why Alibaba, Tencent, Toutiao, and Baidu have all formed kernel teams.

Native development, on the other hand, initially requires a high investment in development costs, but once there is output, developers will have more room for creativity. The React Native and Weex solutions aim to create comprehensive solutions that balance cross-platform development, development costs, and performance.

Based on the current situation, each solution has its own usage scenarios. Whether it is React Native or H5, none can completely replace native development. Of course, there is one exception here, that is, if we are no longer developing applications and instead fully focus on mini-programs. The competition between mini-programs and native development is more focused on the channel level.

Summary #

There seems to be a viewpoint now that “no one wants Android developers” and everyone wants to switch to working on front-end development. Is this really true? In fact, regardless of which cross-platform solution we use, they ultimately need to run on the Android platform. Issues such as crashing, memory usage, sluggishness, and battery consumption still exist and may even become more complex. Furthermore, looking at examples of optimizing H5 for the ultimate user experience, many optimizations require in-depth research into platform characteristics and system-level mechanisms. The knowledge we acquire in “high-quality development” regarding underlying and system-related aspects remains important.

For developers, the only constant is their ability to learn. By mastering the ability to learn and having a spirit of exploration, one can adapt to these changing trends. No matter how mobile development changes in the future, even if one day AI can truly write code automatically, those who possess adaptability will not be afraid in the slightest.

Homework #

Cross-platform development is also a very big topic. Today, I can only be considered as scratching the surface. What are your thoughts on cross-platform development? Which cross-platform development approach did you use in your application? Feel free to leave a comment and discuss with me and other classmates.

Feel free to click “Share with Friends” to share today’s content with your friends and invite them to learn together. I have also prepared generous “Learning Boost Packages” for students who think and share actively. Looking forward to learning and improving together with you!