Cross-end technology comparison

Technical types UI rendering performance Development efficiency dynamic Framework on behalf of
H5 + native The WebView rendering general high ✔ ️ Cordova, Ionic
JavaScript+ native rendering Native control rendering good high ✔ ️ RN, Weex
Self-painted UI+ native Call system API render good Flutter is high, QT is low Not supported by default QT, Flutter

H5 + native

The original development mode of H5 + is called Hybrid development. The APP developed in the Hybrid mode is called Hybrid application or Hybrid APP. If most of the functions of an application are realized by H5, it is called Web APP.

  • H5: Normal front-end Web page development, which generates a DOM tree and invokes system functions through apis provided by JsBridge.
  • JsBridge: Hybrid frameworks typically pre-implement apis to access system capabilities in native code, which are then exposed to the WebView for JavaScript calls.
  • WebView: container for H5 pages, and can connect native functions to JsBridge.

JavaScript+ native rendering

The biggest difference from mixed development is that mixed development JS still generates the DOM, just give it a container; JS native rendering produces a native component tree.

  • JS: It is mainly represented by RN and Weex, but the difference lies in the grammatical style. The JS part generates the virtual DOM, which is passed to JSCore.
  • JSCore: Compiles the virtual DOM into a native component tree

Self-painted UI+ native

The UI+ native is closer to the native development style, except that the development language is unified and two sets of native machine code are generated by a compilation engine.

Flutter/Dart characteristics

  • Cross-platform rendering engine: Skia as its 2D rendering engine
  • High performance: Advantages over JS
    • Dart is almost as fast as JavaScript in JUST-in-time (JIT) mode. But Dart supports AOT, and when running in AOT mode, JavaScript can’t catch up.
    • Flutter uses its own rendering engine to draw the UI. Layout data is directly controlled by the Dart language, so it does not need to communicate between JavaScript and Native as RN does during the layout process. This has obvious advantages in some sliding and dragging scenarios. Since layout changes are often caused by sliding and dragging, JavaScript needs to constantly synchronize layout information with Native, which is the same problem as frequent DOM manipulation by JavaScript in the browser, which will bring considerable performance overhead.
  • The runtime and compiler support two modes
    • JIT development: Flutter is adopted during development in JIT mode to avoid compilation for every change
    • Publish AOT: When Flutter is released, it uses AOT to generate efficient ARM code to ensure application performance
  • Type safe, supports static type detection

Flutter architecture

Flutter Framework

The SDK base library for the pure Dart implementation:

  • Fondation, Animation, Painting, Gestures: the underlying UI library, namely DART: UI package. It can be interpreted as a Window object on the Web, providing basic apis for animation, drawing and gesture.
  • React, the core of Flutter, is the layout layer implemented based on the underlying UI.
    • Maintain a UI tree (similar to the React virtual DOM)
    • When the UI tree changes, calculate the changes and update the UI tree (like React Diff).
    • Call the underlying UI drawing element (similar to the React DOM) in response to the definition and transformation of element positions and sizes.
  • Widgets: Define some basic components that are equivalent to HTML elements, applets tags, and React JSX. This is basically what we write Flutter about.
  • Material, Cupertino: Library of visual components on top of widgets, equivalent to Antd and ElementUI.

Flutter Engine

Pure C++ SDK, including Skia engine, Dart runtime, text typesetting engine, etc. When code calls the DART: UI library, the call eventually makes its way to the Engine layer, where the actual drawing logic is implemented.

Dart Key Syntax

variable

var t; // Unchangeable type dynamic t; // Change the type const str1 ="Hi world"; // Compile constant final STR ="Hi world "; // Constant: initialized for the first timeCopy the code

function

Bool isNoble(int atomicNumber) {} // Band type bool isNoble(int atomicNumber) => _nobleGases [atomicNumber]! = null ; String say(String from, String MSG, [String device]) {} // [] This parameter is optionalCopy the code

asynchronous

The Future:

(equivalent to a Promise)

New Promise future.delayed (new Duration(seconds: 2),(){throw AssertionError()"Error"); }). Then ((data){// equivalentthen
   print(data); }).catcherror ((e){//print(e); }). WhenComplete ((){// finally}); All future. wait([future.delayed (new Duration(seconds: 2), () {return "hello";
  }),
  Future.delayed(new Duration(seconds: 4), () {
    return " world";
  })
]).then((results){
  print(results[0]+results[1]);
}).catchError((e){
  print(e);
});
Copy the code

Async/await:

It’s the same as JS

Stream:

A Promise’s decision is irreversible, and once Resolve or Reject is made, the state does not change. Even promise. all or promise. race is decided only once.

A Stream can wrap multiple Futrue like all/ Race, except that the Stream state is triggered each time the Future returns, more like an event dispatcher/collector.

Stream.fromFutures([
  Future.delayed(new Duration(seconds: 1), () {
    return "hello 1";
  }),
  Future.delayed(new Duration(seconds: 2),(){
    throw AssertionError("Error");
  }),
  Future.delayed(new Duration(seconds: 3), () {
    return "hello 3";
  })
]).listen((data){
   print(data);
}, onError: (e){
   print(e.message);
},onDone: (){
});
Copy the code