Translator: Goulman Bruce

This article is one of a series of articles on Flutter performance optimization. It documents the practice of the Flutter team to optimize the Flutter Gallery (Gallery. Flutter. Dev /#/). This article focuses on the use of Tree Shaking and lazy loading for performance optimization. Original link: medium.com/flutter/opt…

App loading speed plays an important role in a good user experience. The initial loading time of the Flutter Web App can be improved by minimizing the JS package size. The Dart compiler comes with tree shaking and lazy loading features, both of which minimize JS package size. This article describes how these two features work and how to apply them.

Tree Shaking enabled by default

When compiling the Flutter web app, the JS package is generated by the dart2js compiler. A release build is optimized at the highest level, including tree shaking.

Tree shaking is a process of weeding out useless code by including only code that must be executed. So, you don’t have to worry about the libraries your app references, because classes or functions that aren’t used will be excluded.

Take a look at tree shaking in action:

  1. Create a Dart file greeter. Dart:
abstract class Greeter {
  String greet(String name);
}

class EnglishGreeter implements Greeter {
   String greet(String name) => 'Hello $name';
}

class SwedishGreeter implements Greeter {
   String greet(String name) => 'Hej $name';
}

void main() {
  print(EnglishGreeter().greet('World'));
}
Copy the code
  1. performdart2js -04 greeter.dartCommand, and then take a look at the generated fileout.js.

There are no SwedishGreeter classes in the generated JS code, nor can Hej $name be found because they were removed by the compiler during tree shaking.

With static analysis alone, the compiler can only figure out which code is being executed and which is not. For example, if the definition of greeter depends on the system locale:

Locale locale = Localizations.localeOf(context);
if (locale.languageCode == 'sv') {
  greeter = SwedishGreeter();
} else {
  greeter = EnglishGreeter();
}
Copy the code

The compiler does not know the user’s system locale, so EnglishGreeter and SwedishGreeter are both packed in. In this case, lazy loading can help reduce the volume of initialized packages.

Lazy loading

Lazy loading, also known as lazy loading, allows you to load various libraries as needed. It can be used to load functions that are rarely used in apps. Please note that lazy loading is a dart2js feature, so this feature is not available for mobile Flutter app. In the simplest example, import a package or file as deferred and wait for it to load before using it:

import 'greeter.dart' deferred as greeter;

void main() async {
  await greeter.loadLibrary();
  runApp(App(title: greeter.EnglishGreeter().greet('World')));
}
Copy the code

In Flutter, everything is a widget, so you may need to use FutureBuilder. Because a widget’s build method should be synchronous, you cannot await loadLibrary methods in a build method. However, you can return a FutureBuilder in the build method, or you can use it to display a different UI while waiting for the library to load:

import 'greeter.dart' deferred as greeter;

FutureBuilder(
  future: greeter.loadLibrary(),
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.done) {
      return Text(greeter.greet('World'));
    } else {
      return Text('Loading... '); }},)Copy the code

You can try running the full example from the repository, open Chrome Developer Tools, and click the Web TAB to see web activity. Refresh the page to see when the library was introduced and loaded. In the screenshot below, the loading of the file main.dart.js_1.part.js is delayed:

Localized lazy loading in the Flutter Gallery

Flutter Gallery supports over 70 languages, but most users only use one. Lazy loading of localized strings is a great use of this feature. For example, the app’s initial JS package size was cut in half by implementing lazy loading of localized strings. If you have a lot of localized strings in your Flutter Web app, consider lazily loading these files. The gen_l10N.dart script uses the –use-deferred-loading option to implement this requirement (currently only available on the 1.19 SDK Master Channel).

This article is part of a series we learned about improving the performance of Flutter Gallery. Hopefully this will help you learn something you can use in your Flutter app. The series is as follows:

  • Tree Shaking and Lazy Loading of Flutter Performance Optimization series
  • Image placeholders, precaching, and disable navigation transition animation for the Flutter performance Optimization series
  • Build high performance Widgets for Flutter Performance Optimization series