Flutter Initialization Process and Performance Optimization
The article explains that Flutter’s first‑page launch is slower because initialization proceeds through four stages—FlutterMain, FlutterNativeView, FlutterView, and Flutter Bundle—and shows that pre‑initializing the heavy native view, view, and bundle components can cut the initial latency to match later launches.
When optimizing performance, the author noticed that the first launch of a Flutter page takes about twice as long as subsequent launches in a hybrid stack.
The delay is caused by Flutter's initialization, which consists of four stages: FlutterMain initialization, FlutterNativeView initialization, FlutterView initialization, and Flutter Bundle initialization.
FlutterMain.startInitialization performs configuration, AOT compilation, resource loading, and loads the native library. Example code:
public static void startInitialization(Context applicationContext, Settings settings) { ... initConfig(applicationContext); initAot(applicationContext); initResources(applicationContext); System.loadLibrary("flutter"); }FlutterNativeView's constructor ultimately calls a nativeAttach method defined in JNI. Sample JNI registration:
static const JNINativeMethod native_view_methods[] = { { "nativeAttach", "(Lio/flutter/view/FlutterNativeView;)J", (void*)shell::Attach } };The nativeAttach method creates a PlatformViewAndroid and attaches it:
static jlong Attach(JNIEnv* env, jclass clazz, jobject flutterView) { auto view = new PlatformViewAndroid(); view->Attach(); }PlatformViewAndroid::Attach sets up the engine, resource context, and thread priorities.
void PlatformViewAndroid::Attach() { CreateEngine(); SetupResourceContextOnIOThread(); UpdateThreadPriorities(); }FlutterView initialization registers a SurfaceHolder callback and sets up bridge methods for localization, navigation, etc.
Flutter Bundle initialization is triggered by FlutterActivityDelegate.runFlutterBundle, which loads the app bundle path and runs it via FlutterView.runFromBundle.
public void runFlutterBundle() { String appBundlePath = FlutterMain.findAppBundlePath(activity.getApplicationContext()); if (appBundlePath != null) { flutterView.runFromBundle(appBundlePath, null, "main", reuseIsolate); } }RunFromBundle eventually calls PlatformViewAndroid::RunBundleAndSnapshot, which invokes Engine::RunBundleWithAssets and finally DartController::SendStartMessage to start the Dart entrypoint.
By pre‑initializing the three heavy parts—FlutterNativeView, FlutterView, and Flutter Bundle—the first‑launch latency can be reduced to be comparable with subsequent launches.
Xianyu Technology
Official account of the Xianyu technology team
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.