Front-end development: How to cross-end correctly?

Cross-terminal

Write once, run everywhere。

We have all heard of this classic propaganda phrase, and then we all know that nothing can really run everywhere, at best it can only do debug everywhere.

And when we talk about writing multiple terminals at once, it is obviously impossible to really refer to all terminals. In most cases, you will not need to develop a function simultaneously on the computer and the bracelet.

  • Cross PC and wireless end.
  • Across multiple Native platforms: For example, across Android and iOS, and even across Windows.
  • Cross-provisioning APP: With the increasing number of super APPs, many businesses need to place the same page in multiple APPs.
  • Cross-Web and APP: In many cases, the Web is still inevitable. Our pages may need to be shared, SEO, or posted on M sites, etc. At this time, they need to be able to run both in the Web and in the APP.
  • Cross-web, multiple applets, QuickApp, etc.: In fact, it is similar to cross-APP, but the applet itself is a closed ecosystem controlled by various companies, so there is a demand for development to adapt to multiple closed ecosystems at one time.
  • Cross-terminal appeals from other ends: such as cross-POS machines, watches, etc.

Corresponding to our diverse cross-terminal demands, there are a hundred flowers blooming cross-terminal solutions.

A hundred flowers blooming cross-end solution

Web-based H5 Hybrid solution

This type of solution is the most straightforward, in simple terms, it uses web pages to cross terminals. Since most of our terminals (even the closed applet ecosystem) support Webview, we only need to develop a webpage and put it on multiple terminals. The corresponding solution on the desktop is Electron.

Why not use the Web directly?

In terms of low development costs, uniform standards, and ecological prosperity, the H5 Hybrid solution is basically the best choice. However, this solution cannot avoid the gap in performance and experience. The ecological prosperity of the Web comes from its good historical compatibility, which also means a heavy historical burden.

  • As an open technical standard, the W3C standard has a lot of historical burden and complicated logic.
  • Web standards are not designed for Design for Performance, which makes it difficult to further improve in many areas. For example, JS execution and Layout and rendering cannot be mutually exclusive. As a result, too long JS execution tasks will perform normal rendering and cause stalls.
  • The standardization of the Web is also slow in advancing, and new capabilities may take a long time to be used.

React-Native/Weex solution

On the mobile platform, especially the early WebView performance experience is very bad. We also mentioned earlier that this gap mainly comes from the heavy historical burden of the Web ecology itself.

Solutions such as React-Native/Weex learn from each other's strengths as much as possible and combine the ecology of the Web with Native components to allow JS to execute code and then use Native components for rendering. As a result of discarding the historical baggage of the Web, this type of solution can make some drastic changes.

For example, in the following figure, RN puts JS execution, layout (Yoga) and rendering (Native component) in three processes to execute separately, avoiding interface freezes when JS performs complex tasks. By abandoning a large number of standards in CSS, only supporting part of the flex layout capabilities to reduce the complexity of layout and rendering.

This scheme also has some shortcomings:

  • The inconsistent components and layout mechanisms of the iOS/Android dual-end system make it difficult to guarantee dual-end consistency.
  • Relying on the Native mechanism also makes it difficult to implement some CSS properties, such as the old and difficult z-index problem.

The most troublesome point is that this solution means very high maintenance and support costs.

  • The ecology of the Web is borrowed, but it is not entirely Web ecology. There are many inconsistencies. The most common complaint is that the usual CSS layout method cannot be used.
  • Compared with a new sensor API in the browser, a complete devtool is required. In most cases, the development experience guarantee for this type of solution can be said to be slash and burn (the following picture is the devtool of Chrome's orientation sensor API).

Today, as the performance gap of WebView is gradually narrowing, whether it is worth maintaining the ROI of this complex solution needs to be considered according to the specific requirements of our scenario.

Flutter

The problem to be solved by Flutter is different from the above solution. It does not intend to continue to leverage on the Web ecology, and it has not taken the Web ecology into consideration from the beginning of the design. Compared to RN's reliance on Native View rendering, Flutter is a self-drawn component that is drawn directly to the screen through Skia.

Since you can fully utilize the GPU's capabilities, you don't need to go to Native to make a circle. Flutter can theoretically achieve better performance and consistency at both ends, which means that theoretically in the future, Flutter-based JS dynamic solutions may support better styles than WEEX.

From a front-end perspective, it is still more like a Native development solution than a cross-end solution (although it is actually cross-Android/iOS). The main problem at present is that Flutter for Web may be far away from production availability in terms of technical principles. In addition, the dynamic ability does make some scenes unsuitable.

R & D framework for applet

Mini programs are created problems. Out of commercial considerations, various mini programs have actively constructed a relatively closed ecology on the basis of the Web ecology. Lead to incompatible with the Web ecology. However, it is difficult to accept and use scenarios where there are multiple small programs, or both small programs and Web terminals.

Since the end of the applet is closed and uncontrolled, the cross-end problem of the applet can only be solved from the research and development framework level.

Compile-time scheme

The more well-known compile-time solution is Taro. The general principle can be explained as compiling JSX to the WXML/WXSS/JS of the applet, and the implementation principle of this kind of framework is not really a React or a React-like framework, but The template that looks like JSX is translated into the template of the applet itself through static compilation.

The limitation of this is very obvious, that is, JSX is an extension language of JavaScript (React Blog writes is a syntax extension to JavaScript), while the WXML used by the applet is a template language with very limited expressive ability. We do not It is possible to complete the compilation from a general programming language to a template language.

In order to achieve this, the statically compiled class framework adopts the method to restrict the writing of developers, which is why taro has made many restrictions on the writing of JSX. This directly led to endless maintenance costs and severely damaged development experience, and then taro/next also turned to the combination of runtime solution + static compilation optimization.

Runtime solution

To put it humbly, the runtime solution for small programs should be the earliest I put forward when I wrote the first issue of remax [1].

Through React Reconciler (similar to Rax Driver), we can let React running in the applet container not directly manipulate the DOM, but transfer the manipulated data to the View layer of the applet through setData and map it to the final interface.

Although several solutions such as Remax, Rax runtime, and Taro Next are not the same, the ideas are the same, that is, to use the dynamic ability of the applet template to a certain extent + the VirtualDOM of the React framework for rendering. Of course, this approach has a certain performance loss compared to the native rendering method of the applet.

Alipay end performance test of remax

In some scenarios, this loss is worthwhile. These runtime frameworks are also gradually improving performance by allowing unused attributes, partial static compilation, and virtual lists in templates generated by compilation to be turned off.

Of course, the final embedded Webview is still a solution.

As a business technical team, what should we do

The above are all solutions for certain specific scenarios, but for the business technical team, the essence of cross-terminal is to improve efficiency. Proposing a new plan for new changes is one aspect, and more importantly, how to make this kind of efficiency improvement really last for a long time, so that our efficiency improvement will not become a jump from one new plan to another.

Let us re-look at the above picture, we can be sure that the cross-terminal appeal and the corresponding solution will still be in frequent changes, and there will not be a solution to all cross-terminal problems. And the relatively constant part is worth investing in for long-term stability.

WebView & H5 Hybrid

WebView may be the most special of many containers. Although it is difficult to meet the extreme performance and experience requirements of some scenarios, it will be the most stable, long-term, and supported solution.

From the perspective of development efficiency and future long-term maintenance evolution, on the premise that it can meet the performance and experience requirements, the Web solution is still the top priority should be considered.

At the same time, we can do more work on the WebView container of the APP, such as providing some internal capabilities through the container, parallel data loading combined with Native capabilities, page keeping alive, and so on.

Infrastructure

No matter which cross-terminal solution is adopted, in which container, performance, stability, and efficiency are inevitable troikas.

performance

There are often different performance schemes for different schemes. We also mentioned above that in the runtime scheme of the applet, there will be optimizations such as reducing the fields produced by the compiled template. However, in fact, in addition to the optimization of this specific solution, most of the optimization methods are similar: offline caching, data prefetching, snapshots, SSR, NSR, and so on.

For different ends and containers, the measurement and discovery of performance problems should also be consistent. We need to have a clear perception and horizontal comparison of the performance of the page on different ends.

The end-to-side construction of performance (end capability, specific performance measurement plan for a certain end, performance management, etc.) may need to be different for different ends and different cross-end schemes. However, the performance infrastructure (first screen standard, data analysis, and basic optimization capabilities) should be relatively stable across terminals.

In terms of end-side capabilities, ICBU introduced the capability of parallel loading in the early WEEX performance optimization, and used the parallel loading capability of the container through the wh_prefetch protocol. Then in the new container (WebView, browser), although the underlying capabilities are different, they still recognize the same protocol.

In terms of data collection and analysis, we unify the cross-terminal basic library so that different technical solutions from different terminals can be analyzed, measured and compared under the same standard.

Stability building

At the wireless end, we often refer to performance & stability as "high availability". The main scope of stability covers grayscale capabilities, business monitoring, alarms, error monitoring, white screen detection, and so on.

These capabilities are less dependent on specific end-to-end and cross-end solutions. Except for the slightly different data collection logic on the end-side, the other construction parts are relatively stable. The group also has some cross-terminal solutions for these scenarios, such as iTrace.

Engineering infrastructure

For cross-terminals in different scenarios, although there are certain differences in the plan, our engineering infrastructure can be maintained uniform

  • The container layer provides unified API and documentation capabilities
  • Unified R&D process
  • R&D tools provide unified packet capture and debug capabilities, etc.
  • Consistent tool library and more

In this way, when new containers or solutions appear, we only need to align them according to the corresponding capabilities, so that our upper-level business code and development experience can maintain a relatively stable state.

Business logic cross-terminal

Relatively speaking, we will find that in the evolution of multiple cross-terminal solutions, the UI level changes such as how to render and how to layout are far greater than the business logic level. Even for small programs and Flutter, their general development paradigm has not changed much. For example, the Flutter development paradigm is very similar to React. It is also a declarative UI, and VirtualDOM also exists.

Considering SEO and performance issues and Flutter's Skia-based rendering mode, Flutter for Web may not be a solution available in a production environment for a long time.

After unifying the organization of the business logic code, we can use the Hooks for ALL solution to allow Flutter and the web side to share a Hooks-based business logic code.

Sometimes you don’t really need to run everywhere, you can achieve your goal if you can improve performance and maintain consistency.

View layer

At present, the cross-end view of the view layer is still full of variables. After our business logic layer is sufficiently atomized across the ends, maybe some of our interactive logic is not particularly heavy in the view layer, which can bind atomic logic + data through DX + The parameter approach covers more cross-end scenarios. So as to meet the demands of performance and efficiency at the same time.

However, there is still no silver bullet for the view cross-end of the general scene.

to sum up

In general, the cross-terminal is and will be in a state where multiple solutions coexist and change continuously for a long time. In addition to selecting or creating suitable solutions for new changes and new scenarios, we must also do a good job in the long-term stability of this dynamic change:

  • H5 Hybrid。
  • The unity and continuity of the performance, stability and efficiency troika.
  • In the scenario that does not force write once, consider cross-terminal business logic that is simpler than UI cross-terminal.

Original link

This article is the original content of Alibaba Cloud and may not be reproduced without permission.

Guess you like

Origin blog.csdn.net/weixin_43970890/article/details/114066565