Skip to main content
Deferred imports allow a Dart program to load a library lazily at runtime. Instead of linking and loading the library code immediately upon application startup, the runtime system suspends the loading of the specified library until the code explicitly requests it via an asynchronous invocation.

Syntax

To declare a deferred import, use the deferred as keywords followed by a namespace identifier.
import 'package:example/heavy_library.dart' deferred as heavyLib;

Mechanism

The deferred import process involves three distinct technical stages:
  1. Declaration: The deferred as clause creates a placeholder namespace for the library. At this stage, the symbols within the library are not available for execution.
  2. Invocation: The Dart compiler implicitly injects a method named loadLibrary() into the namespace of the deferred import. This method returns a Future<void>.
  3. Resolution: When loadLibrary() is called, the runtime fetches the code (if not already loaded) and resolves the symbols. Once the Future completes, members of the library are accessible via the namespace prefix.

Implementation Example

The following example demonstrates the required pattern: importing with a prefix, awaiting the load future, and accessing members through the prefix.
import 'package:my_package/utils.dart' deferred as utils;

Future<void> invokeLazyFunction() async {
  // 1. Trigger the load and wait for completion
  await utils.loadLibrary();

  // 2. Access members via the prefix
  utils.complexCalculation();
}

Technical Constraints

  • Mandatory Prefix: Deferred imports must specify a prefix using as.
  • Asynchronous Access: The loadLibrary() method is always asynchronous. Even if the library has already been loaded by a previous call, the method returns a Future that completes immediately.
  • Constant Evaluation: Constants defined in a deferred library cannot be used as compile-time constants in the importing file because the values are not available at compile time.
  • Type Usage: Types from a deferred library can be used in type annotations (e.g., utils.MyClass myVar;). However, they cannot be used in the extends, with, or implements clauses of a class declaration, as the class hierarchy must be resolved at startup.
  • Instantiation: While type annotations are permitted, you cannot construct an instance of a class from a deferred library until loadLibrary() has completed.
  • Multiple Imports: If the same library is imported deferred in multiple places or both deferred and non-deferred, the runtime ensures the code is loaded only once.
Master Dart with Deep Grasping Methodology!Learn More