This article is some of my feelings after learning the UI framework of multiple platforms. Limited by energy and technical level, there must be some shortcomings in this article. Please give me more advice

If you think my article is helpful to you, in the process of collecting, be sure to remember to like and click on oh, thank you, this is really important to me 🌟!

First, the front end three plate axe

Before we discuss the concept of “cross-end development,” let’s start with a question: What does the front-end do for most of the front-end work?

My personal view is that no matter how the environment changes, the front end basically does three things:

  • Fetch data
  • Manage State
  • Render page

Didn’t.

Some people may think what I say is too one-sided, in fact, we can figure it out. More recently, knowledge now pay to do in full swing, always make a “XXX source code analysis”, analysis of the subject and directory of these courses, you will find that the basic are around the three directions to speak; Going further, we can analyze the history of the Web front end:

  • Around 1995, data was pulled with HTTP/1.0, several front-end states were managed with the first version of JavaScript, and pages were presented with bare HTML tags

  • Around 2005, I used HTTP/1.1 and AJAX to pull data, used JavaScript to draw forms, and used CSS to beautify pages

  • Around 2010, using HTTP/1.1 and AJAX to pull data, using jQuery to manipulate DOM to handle front-end logic, and using CSS to beautify the page

  • Around 2015, with the spread of the HTML5 standard and the improvement of browser performance, the front end began to be “unlearned” :

    • At the Fetch Data level, in addition to HTTP/1.1 and AJAX, HTTPS is coming, HTTP/2 is coming, and WebSocket is coming
    • At the Manage State level, Angular, React, and Vue emerged, and the React state-driven view concept has directly influenced the design of Flutter and SwiftUI for now
    • In the render page level, in addition to the traditional HTML + CSS, but also added CSS3, Canvas and other concepts, audio and video functions have also been strengthened
  • In recent years, network protocols have stabilized and will not change much in the next few years. React and Vue are basically stable, a bunch of front end is staring at GitHub progress bar and other version updates; Render emerged a lot of unorthodox, finally get rid of IE6, and came to a variety of small programs, the same business logic to write several times is not economic nor realistic, at this time a variety of cross-end programs will come out

After some analysis, this three plate axe theory seems to have some truth, we follow this direction to the bottom of the thinking: how are these three functions realized?

  • Fetch data direction, finally rely on the network protocol stack to send data, but it is very unrealistic for a front-end to directly engage in socket programming, so we need to encapsulate the network operation as a library, let the application layer call
  • Render the page, the last is to put the related information through a variety of graphic primitives API (OpenGL/Metal/Vulkan/DirectX) sent to the GPU to render, a lot of front end graphics journey finally ended with a triangle, with the technology stack is also unrealistic to draw the UI, Not to mention the huge engineering work of the typesetting system, so the relevant rendering engine does all the work
  • You can manage state by using global variables, which will definitely end up in a mess. Most of the current solutions are to use various frameworks and runtime for state management, and the runtime is usually hosted by a virtual machine in a particular language. The starting point of fetch Data is also the same virtual machine

From the above analysis, we can see that the main technical core of the front-end is the virtual machine and the rendering engine, which means that if we want to do cross-side development, we have to unify the virtual machine and the rendering engine.

Virtual machines and rendering engines

1. Web: JS Engine + WebKit

Because Google’s Blink engine is fork from Apple’s WebKit, the following article uses WebKit to replace the browser rendering engine for convenience

The web is the cheapest and fastest cross-end solution. Thanks to the open concept of the Internet, the web is inherently cross-terminal, no matter what the rendering framework, WebView is an essential core component.

The cost of access for developers is also extremely low. The main technology is Web development, and the main headache of the front end is the adaptation and performance of each rendering engine.

At present, the mainstream JS Engine is Apple’s JavaScriptCore and Google’s V8, while the mainstream rendering Engine is Apple’s Webkit and Google’s Blink. Although the W3C specification is there, browser vendors implement browsers according to the specification, which is the foundation of cross-end web pages. The problem is that the browser kernel implementation is always slightly different, some of the implementation is not standard, some of the implementation itself is buggy, which is the essence of the front-end can not get away from the adaptation requirements.

Another is performance. In fact, The rendering speed of WebKit itself is still very fast, but limited by some browser features, such as extremely complex and dynamic CSS properties, DOM tree and CSSOM merge, the main thread must be suspended to wait for JS execution, these will greatly reduce performance, front-end performance optimization, In general, we need to reduce the pruning process according to these browser features, but no matter how to optimize the page performance and interactive experience, there is still a big gap between Native and page performance.

2. Web PLUS: JS Engine + WebKit + Native ability

It is the easiest to throw a URL directly into the WebView. In fact, this can solve most of the problems. After all, 90% of the front-end work is to draw UI and write business logic, but there are still 10% functions that cannot be done, such as synchronizing state with Native and calling some system functions.

If you want to achieve two-way communication between the client and the web page, JSBridge is generally used for communication, “The principle of JSBridge” this article summarizes good, interested students can take a look.

JSBridge only solves the problem of Native and Web calling each other. What if I want to enhance the Web with Native? At this point, there are some explorations:

  • Warm-up: Create and initialize webViews ahead of time, and even implement WebView container pools to reduce WebView startup time

  • Cache: Stores commonly used Web resources in a Native place in advance, and then intercepts browser network requests and redirects them to the local place, thus speeding up the loading speed of Web resources (also called “offline package” scheme).

  • Hijacking: For example, Web has a weak control over network loading. Some competent manufacturers will hijack all network requests and hand them over to Native to manage Web requests more flexibly

  • Replace: Replace generally refers to replace the Img tag and Video tag on the Web, this is the most common place is the major news client. Due to the dynamic and real-time nature of news, news is delivered by various editors/we media through background editing. At this time, the powerful typesetting function of Web should be used to display text content. But for speed and viewing experience, images and videos are replaced with Native components

After the above steps, the speed of the web page can reach the level of seconds, which is the most typical of several big news client, we can get started to experience.

3. Small program: JS Engine + WebKit

Small program, the characteristics of the domestic architecture, is essentially wechat after becoming a black hole in traffic, want to become a traffic distribution market management and distribution of their own traffic, so this is a very heavy framework of business flavor.

Small program nothing special innovations in technology, essentially castration version of the web, so after WeChat applet out each traffic oligarchs have launched their own small program, as some, the small program implementation way of nine, the underlying implementation diversification, the factory has no unified standard, the last is to feed the developer shit, I also do not have what good introduction, That’s it.

4.React Native: JS Engine + Native RenderPipeLine

React Native was released in 2013 and two years later. The first few cross-segment solutions were based on browser technology. RN’s cross-segment solution was innovative in that it retained the JS Engine. Instead, the existing Native rendering pipeline is reused.

The advantage of this is that keeping the JS Engine allows for maximum reuse of the Web ecosystem, since JavaScript is the most popular language on GitHub. The advantage of using Native RenderPipeLine is that it is free from the historical burden of WebKit. Relatively, the rendering pipeline is shorter, and the performance is naturally improved.

So the question is, how does RN cross? This all depends on the React VDOM.

vdom

There are articles in the front-end community that talk about VDOM in terms of performance and ease of development. From a pure Web front-end perspective, these are vDOM’s characteristics, but that’s not why VDOM has really taken off. The greater value of VDOM is that people see the promise of cross-end development in VDOM, so it was natural for React Native to come on the heels of React. Why do you say so? This starts with a trace to the UI development paradigm.

There are two main paradigms for UI development: Immediate Mode GUI and Retained Mode GUI.

To put it simply, IMGUI is a full refresh of every frame, which is mainly used in areas with high real-time performance (game CAD, etc.); RMGUI is the most extensive UI paradigm, where each component is packaged into an object for easy state management and complex nested layouts. Whether it’s web, iOS, Android, or desktop development like Qt, it’s all based on RMGUI. For details of the differences between the two, see this zhihu answer and this Youtube video.

Back to React Native, since iOS and Android’s Native rendering pipeline is RMGUI, there are always similarities. For example, uIs are tree-nested layouts, event callbacks, etc. This is where vDOM comes in:

As a pure object, VDOM can clearly extract the nested structure of the layout, and this abstract description is platform-independent, so we can use JS to generate VDOM, and then map VDOM to Native layout structure, and finally let Native render the view. In order to achieve the purpose of cross-platform development.

If you have some knowledge of compiler principles, you will find that VDOM and IR are similar. They are both abstracted from the intermediate state of the platform. Vdom is connected to React and Native RenderPipeLine, IR is connected to the compiler front end and the compiler back end. As long as we care about the logic of the first half, let the second half do all the dirty work.

Hermes

In 2019, In order to optimize the performance of React Native, Facebook directly launched a new JS Engine — Hermes. FB’s official blog introduces many advantages. Personally, I think the biggest highlight is the addition of AOT.

Babel syntax conversion → Minify code compression → install download code → Parse to AST → Compile Compile → Execute

When Hermes joined AOT, the Babel, Minify, Parse and Compile processes were all done on the developer’s computer, just sending bytecode to Hermes to run.

The advantage of this is that it can greatly shorten the COMPILATION time of JS. If you don’t believe it, you can use Chrome to analyze several large websites. JS parsing load time is more than 50% of the time, and some heavy websites may account for 90% of the time. These are fine performance killers for mobile platforms that have less power and CPU than the upper tier, and the addition of Hermes could make a big difference.

React Native 0.64 also supports Hermes. If you have RN business, you can play it and see how much performance improvement it has on iOS.

5.Flutter: Dart VM + Flutter RnderPipeLine

Flutter is one of the most popular cross-platform solutions recently, and many people believe that it is the ultimate cross-platform solution. After all, Qt is the ultimate cross-platform solution in the era of desktop software. Their common feature is a rendering engine that can smooth out terminal differences.

The creation of Flutter is quite interesting. Here’s an interview with Eric, who has been working on Web rendering for over a decade. He says that once inside Chrome they did an experiment where they got rid of some of the messy Web specifications. Some benchmarks were 20 times faster, so Google started building a project internally, and Flutter came into being. As for the reason why Flutter chose Dart, it has long been said that Flutter development team is next door to Dart development team. Being close to Dart is good for PY trading. Dart is not used anyway, and has no historical baggage, which can be well adapted to the needs of Flutter.

The architecture of Flutter is also clear:

  • Dart VM for VMS. Dart supports both JIT and AOT, ensuring both development efficiency and operation efficiency
  • The rendering engine first transmits the view data constructed by Dart to Skia, and then the Skia processing data to OpenGL/Metal graphics apis, and finally to GPU rendering. As a whole, it is much clearer than WebKit’s rendering pipeline

From pure degree, Flutter is one of the most radical, the virtual machine and rendering engine to use mature industry solutions, but since built a set of, advantage is that no adaptation pressure, bad is too new, business development will often meet embarrassing state without wheels available, if Google heavily promoted, domestic companies continue to follow up, prospect is very bright.

JS Engine + Flutter RnderPipeLine?

There is a feeling in the community that Flutter’s biggest failure is that it cannot be developed in JavaScript. At this time, some people will think, if we combine Web technology with Flutter technology, use JS Engine to connect with the largest and most active JS community in the world, and use Flutter rendering Engine to connect with high-performance rendering experience, guoan Folk music, isn’t it beautiful?

So far, some big manufacturers have made some exploration. I have seen some analysis and project architecture, and I feel that they have made a low-spec version of React Native. The existing architecture of React Native has a performance bottleneck, which is the high cost of cross-language call, and these big manufacturers have up to four call links: JS -> C++ -> Dart -> C++ -> Dart -> C++ -> JS -> C++ -> Dart -> C++

Three, the shortcomings of the cross-end scheme

Cross-end solutions cannot only have advantages, and the disadvantages of each solution are also obvious. I will simply list them below:

  • Web: Performance is a past problem, and Apple clearly points out that WebView shell apps are not welcome, there is a risk of rejection
  • Web PLUS: the technology input is very high, the basic can only be used by large factories
  • Applets: not developer friendly, with a very short technology half-life
  • React Native: Basically, you can only draw UI, but once you make it deep, you can only draw JS, which can’t solve the problem. You have to learn Java and OC, which requires a lot of developers
  • Flutter: Android supports Flutter well, but iOS has a strong sense of fragmentation. Just like RN, once you get into Flutter, you have to learn about client development, which has high requirements on developers

In general, on the premise of sacrificing certain user experience, cross-end solutions can improve the development efficiency of developers and the operating efficiency of companies. In my opinion, as long as the ROI of a certain solution is relatively high, it can be put into production.

Four,

This concludes the article by distilling the cross-side technologies into virtual machine and rendering engine technologies, and then disintegrating the cross-side solutions from the perspective of these two core technologies. Once the concept is clear, in the face of technical scenes such as performance tuning, we can grasp the main contradiction, find problems faster and better, and solve problems.


If you think my article is helpful to you, in the process of collecting, be sure to remember to like and click on oh, thank you, this is really important to me 🌟!

Finally, I would like to recommend my wechat official account: Lu Egg Lab and my personal blog: SupercodePower.com. Currently, I focus on front-end technology, and I also have some micro research on graphics

5. Recommended reading

Q: Why did your Charles fail to catch the bag?

The 5 most confusing points in webpack

React Native Performance Optimization Guide

React Native Update Guide