Performance and App Size

Size is easy to measure. This script splits an APK into compiled code (dex), native libraries (lib), the web app and everything else, using the bytes each entry occupies inside the file:

apk_parts.py: where an APK's bytes goPython
import os, sys, zipfile
def part(name):
    if name.endswith('.dex'):
        return 'dex'
    if name.startswith('lib/'):
        return 'lib'
    if name.startswith(('assets/public/', 'assets/www/')):
        return 'web'
    return 'other'
print(f"{'APK':<22}{'total':>7}{'dex':>7}{'lib':>7}{'web':>7}{'other':>7}  (MB)")
for label, path in zip(sys.argv[1::2], sys.argv[2::2]):
    sizes = dict.fromkeys(['dex', 'lib', 'web', 'other'], 0)
    for entry in zipfile.ZipFile(path).infolist():
        sizes[part(entry.filename)] += entry.compress_size  # bytes stored in the APK
    mb = [os.path.getsize(path)] + list(sizes.values())
    print(f"{label:<22}" + ''.join(f'{n / 1e6:7.2f}' for n in mb))

Run on release builds of the Cordova 129 starter of Gradle, a minimal Capacitor 243,123 app (a Vite 25,978 page plus Preferences, as in Creating an App-Native Projects as Source) and BookNest (Signed App Bundle):

Output of 124
APK                     total    dex    lib    web  other  (MB)
Cordova starter          2.76   2.16   0.00   0.04   0.50
Capacitor starter        3.16   2.48   0.00   0.01   0.63
Capacitor BookNest      18.38   7.17   7.80   0.99   2.11

An empty WebView app costs about 3 MB, almost all of it the AndroidX 234 and bridge code in dex, because the engine is the system's. BookNest's growth comes from its plugins, not from Capacitor: SQLCipher 566,000 's native libraries for four ABIs make up the lib column, and its web app is under 1 MB. React Native 36,878 starts higher, because it ships an engine: in a release build of React Native's BookNest (Expo SDK 57 6,418 ), libreactnative.so (7.1 MB) and libhermesvm.so (2.6 MB) plus the C++ runtime add about 11 MB for each ABI before any app code. A Flutter 16,720 APK likewise carries libflutter.so and your compiled Dart per ABI, and a Tauri 126,184 APK carries your Rust core per ABI. App bundles (Signed App Bundle) shrink what users download to one ABI in every case.

Runtime speed follows the architecture. A WebView app's frames are as smooth as the web page inside it, and each plugin call pays an asynchronous JSON round trip, harmless for a camera but costly in a loop of thousands of calls. React Native's JSI removes the serialization for such calls, and Flutter avoids the platform's view system entirely, which helps heavy animation and custom drawing. For forms, lists and content screens, the pattern of most business apps, users will not tell the three apart; profile before you blame the framework.