# Load sequence, performance, and memory

> What are the steps involved when showing a Flutter UI.



This page describes the breakdown of the steps involved
to show a Flutter UI. Knowing this, you can make better,
more informed decisions about when to pre-warm the Flutter engine,
which operations are possible at which stage,
and the latency and memory costs of those operations.

## Loading Flutter

Android and iOS apps (the two supported platforms for
integrating into existing apps), full Flutter apps,
and add-to-app patterns have a similar sequence of
conceptual loading steps when displaying the Flutter UI.

### Finding the Flutter resources

Flutter's engine runtime and your application's compiled
Dart code are both bundled as shared libraries on Android
and iOS. The first step of loading Flutter is to find those
resources in your .apk/.ipa/.app (along with other Flutter
assets such as images, fonts, and JIT code, if applicable).

This happens when you construct a `FlutterEngine` for the
first time on both **[Android][android-engine]**
and **[iOS][ios-engine]** APIs.

### Loading the Flutter library

After it's found, the engine's shared libraries are memory loaded
once per process.

On **Android**, this also happens when the
[`FlutterEngine`][android-engine] is constructed because the
JNI connectors need to reference the Flutter C++ library.
On **iOS**, this happens when the
[`FlutterEngine`][ios-engine] is first run,
such as by running [`runWithEntrypoint:`][].

### Starting the Dart VM

The Dart runtime is responsible for managing Dart memory and
concurrency for your Dart code. In JIT mode,
it's additionally responsible for compiling
the Dart source code into machine code during runtime.

A single Dart runtime exists per application session on
Android and iOS.

A one-time Dart VM start is done when constructing the
[`FlutterEngine`][android-engine] for the first time on
**Android** and when [running a Dart entrypoint][ios-engine]
for the first time on **iOS**.

At this point, your Dart code's [snapshot][]
is also loaded into memory from your application's files.

This is a generic process that also occurs if you used the
[Dart SDK][] directly, without the Flutter engine.

The Dart VM never shuts down after it's started.

### Creating and running a Dart Isolate

After the Dart runtime is initialized,
the Flutter engine's usage of the Dart
runtime is the next step.

This is done by starting a [Dart `Isolate`][] in the Dart runtime.
The isolate is Dart's container for memory and threads.
A number of [auxiliary threads][] on the host platform are
also created at this point to support the isolate, such
as a thread for offloading GPU handling and another for image decoding.

One isolate exists per `FlutterEngine` instance, and multiple isolates
can be hosted by the same Dart VM.

On **Android**, this happens when you call
[`DartExecutor.executeDartEntrypoint()`][]
on a `FlutterEngine` instance.

On **iOS**, this happens when you call [`runWithEntrypoint:`][]
on a `FlutterEngine`.

At this point, your Dart code's selected entrypoint
(the `main()` function of your Dart library's `main.dart` file,
by default) is executed. If you called the
Flutter function [`runApp()`][] in your `main()` function,
then your Flutter app or your library's widget tree is also created
and built. If you need to prevent certain functionalities from executing
in your Flutter code, then the `AppLifecycleState.detached`
enum value indicates that the `FlutterEngine` isn't attached
to any UI components such as a `FlutterViewController`
on iOS or a `FlutterActivity` on Android.

### Attaching a UI to the Flutter engine

A standard, full Flutter app moves to reach this state as
soon as the app is launched.

In an add-to-app scenario,
this happens when you attach a `FlutterEngine`
to a UI component such as by calling [`startActivity()`][]
with an [`Intent`][] built using [`FlutterActivity.withCachedEngine()`][]
on **Android**. Or, by presenting a [`FlutterViewController`][]
initialized by using [`initWithEngine: nibName: bundle:`][]
on **iOS**.

This is also the case if a Flutter UI component was launched without
pre-warming a `FlutterEngine` such as with
[`FlutterActivity.createDefaultIntent()`][] on **Android**,
or with [`FlutterViewController initWithProject: nibName: bundle:`][]
on **iOS**. An implicit `FlutterEngine` is created in these cases.

Behind the scene, both platform's UI components provide the
`FlutterEngine` with a rendering surface such as a
[`Surface`][] on **Android** or a [CAEAGLLayer][] or [CAMetalLayer][]
on **iOS**.

At this point, the [`Layer`][] tree generated by your Flutter
program, per frame, is converted into
OpenGL (or Vulkan or Metal) GPU instructions.

[android-engine]: https://api.flutter.dev/javadoc/io/flutter/embedding/engine/FlutterEngine.html
[auxiliary threads]: https://github.com/flutter/flutter/blob/main/docs/about/The-Engine-architecture.md#threading
[CAEAGLLayer]: https://developer.apple.com/documentation/quartzcore/caeagllayer
[CAMetalLayer]: https://developer.apple.com/documentation/quartzcore/cametallayer
[Dart `Isolate`]: https://api.dart.dev/dart-isolate/Isolate-class.html
[Dart SDK]: https://dart.dev/tools/sdk
[`DartExecutor.executeDartEntrypoint()`]: https://api.flutter.dev/javadoc/io/flutter/embedding/engine/dart/DartExecutor.html#executeDartEntrypoint-io.flutter.embedding.engine.dart.DartExecutor.DartEntrypoint-
[`FlutterActivity.createDefaultIntent()`]: https://api.flutter.dev/javadoc/io/flutter/embedding/android/FlutterActivity.html#createDefaultIntent-android.content.Context-
[`FlutterActivity.withCachedEngine()`]: https://api.flutter.dev/javadoc/io/flutter/embedding/android/FlutterActivity.html#withCachedEngine-java.lang.String-
[`FlutterViewController`]: https://api.flutter.dev/ios-embedder/interface_flutter_view_controller.html
[`FlutterViewController initWithProject: nibName: bundle:`]: https://api.flutter.dev/ios-embedder/interface_flutter_view_controller.html#aa3aabfb89e958602ce6a6690c919f655
[`initWithEngine: nibName: bundle:`]: https://api.flutter.dev/ios-embedder/interface_flutter_view_controller.html#a0aeea9525c569d5efbd359e2d95a7b31
[`Intent`]: https://developer.android.com/reference/android/content/Intent.html
[ios-engine]: https://api.flutter.dev/ios-embedder/interface_flutter_engine.html
[`Layer`]: https://api.flutter.dev/flutter/rendering/Layer-class.html
[multiple Flutters]: /add-to-app/multiple-flutters
[`runApp()`]: https://api.flutter.dev/flutter/widgets/runApp.html
[`runWithEntrypoint:`]: https://api.flutter.dev/ios-embedder/interface_flutter_engine.html#a019d6b3037eff6cfd584fb2eb8e9035e
[snapshot]: https://github.com/dart-lang/sdk/wiki/Snapshots
[`startActivity()`]: https://developer.android.com/reference/android/content/Context#startActivity(android.content.Intent)
[`Surface`]: https://developer.android.com/reference/android/view/Surface

