Analysis of Cross‑Platform Mobile Development Frameworks: From Cordova to uni‑app x
This article examines the evolution, architecture, performance and trade‑offs of major cross‑platform mobile frameworks—including Cordova, React Native, Flutter, and the newly released uni‑app x—by comparing their logic and rendering layers, communication overhead, package size, memory usage and real‑world testing results.
Cross‑platform mobile development has a long history, starting with cordova , react native , and flutter , and most recently evolving to uni‑app x . Each framework attempts to replace native development, but most have struggled to fully match native performance.
1. Technical Landscape
The table below summarizes the logical and rendering layers of the major frameworks, their typing model, and representative products.
Logic Layer
Render Layer
Type
Representative
webview
webview
Weakly typed
5+App, cordova
js engine
webview
Weakly typed
uni‑app
app‑vue, mini‑programs (dount)
js engine
native render
Weakly typed
react native, uni‑app
app‑nvue, weex
dart engine
flutter render engine
Strongly typed
flutter
js engine
flutter render engine
Weakly typed
WeChat Skyline, webF, ArkUI‑x
kotlin
native render
Strongly typed
uni‑app x
kotlin
native render
Strongly typed
Native apps
Except for the native row, all cross‑platform frameworks are ordered by release date, showing the evolution from webview‑based to native‑render‑based solutions.
1.1 js + native render (e.g., React Native, Weex)
Two main drawbacks:
Performance limits of the JavaScript engine.
Latency of JS‑to‑native communication.
Even with optimisations such as Hermes (React Native) or ArkUI, JavaScript remains slower than compiled native code, especially for numeric operations ( number vs int ).
1.2 JS‑native communication overhead
Each language runs in its own memory space; crossing the language boundary costs tens to hundreds of milliseconds. Frequent calls cause noticeable jank, whether accessing UI elements or native APIs like storage.
1.2.1 UI updates from JS
Examples include scrolling‑driven height adjustments. Frameworks that keep UI inside a webview (e.g., uni‑app app‑vue ) perform better than pure JS‑native bridges, but still incur a bridge cost.
1.2.2 Native API calls from JS
Batch APIs such as wx.batchGetStorageSync mitigate the cost, but large data transfers still suffer from serialization and deserialization overhead.
2. Flutter Solution
Flutter (released 2018) unifies logic and rendering using the Dart language and its own rendering engine, eliminating JS‑native latency. Dart’s strong typing enables aggressive compile‑time optimisation, giving faster start‑up and runtime performance.
Open‑source test projects (e.g., flutter slider‑100 ) demonstrate smooth handling of 100 simultaneous sliders, something that would cripple JS‑based frameworks.
2.1 Dart‑to‑native API communication
When Dart calls native APIs, a serialization layer is still required (e.g., converting Dart objects to Kotlin classes). This adds a baseline latency that does not shrink proportionally with data size.
<template>
</template>
<script lang="uts">
import Build from 'android.os.Build';
export default {
onLoad() {
console.log(Build.MODEL); // Direct native object access, no bridge
}
}
</script>2.2 Mixed rendering issues
Flutter’s self‑rendered UI collides with native UI components (ads, maps, input methods). Problems include input‑method overlay, inconsistent fonts, theme mismatches, and higher memory consumption. Flutter offers two integration modes (hybrid and virtual display), each with its own trade‑offs.
3. JS + Flutter Rendering
Some vendors replace Dart with a JavaScript engine (e.g., WeChat Skyline, webF, ArkUI‑x) to address Dart’s ecosystem gaps. This re‑introduces the JS‑native bridge, negating Flutter’s primary advantage while adding another communication layer.
4. uni‑app x
Released in 2023, uni‑app x is built on the strong‑typed UTS language (a TypeScript‑derived language). UTS compiles to:
JS for web.
Kotlin for Android.
Swift for iOS.
Consequently, an Android build is a pure Kotlin app with no JavaScript or Flutter engine, eliminating all cross‑language communication overhead.
<template>
<view class="content">
<button @click="buttonClick">{{title}}</button>
</view>
</template>
<script> // UTS only
export default {
data() { return { title: "Hello world" } },
onLoad() { console.log('onLoad') },
methods: {
buttonClick() {
uni.showModal({"showCancel": false, "content": "Button clicked"})
}
}
}
</script>
<style>
.content { width: 750rpx; background-color: white; }
</style>Performance tests (slider‑100) show zero frame drops, package size of only 8.5 MB and memory usage around 105 MB, comparable to native apps.
Package size & memory comparison
Framework
Package Size (MB)
Memory Usage (KB)
flutter
18
141324.8
ArtUI‑x
45.7
133091.2
uni‑app x
8.5
105451.2
compose ui
4.5
97683.2
Framework comparison matrix
Framework
Type
Logic‑UI Communication Loss
Logic‑OS API Communication Loss
Mixed Rendering
react native, nvue, weex
Weak
Yes
Yes
No
flutter
Strong
No
Yes
Yes
WeChat Skyline, webF, ArkUI‑x
Weak
Yes
Yes
Yes
uni‑app x
Strong
No
No
No
Native app
Strong
No
No
No
5. Conclusion
Weak typing, cross‑language communication, mixed rendering, large package size and high memory consumption are the main reasons why many cross‑platform frameworks fall short of native performance. uni‑app x eliminates these issues by compiling UTS directly to the platform’s native language, offering native‑level performance while retaining a single, Vue‑style codebase.
Although uni‑app x is still young and lacks features such as dark‑mode support on iOS, it demonstrates a promising direction for future cross‑platform development.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.