[Flutter翻译]利用剪枝和延迟加载优化Flutter Web应用程序的性能

1,568 阅读3分钟

原文地址:medium.com/flutter/opt…

原文作者:medium.com/@perclasson

发布时间:2020年5月19日 - 4分钟阅读

为了获得最佳的用户体验,应用程序快速加载是很重要的。Flutter Web应用程序的初始加载时间可以通过最小化其JavaScript程序包来改善。Dart编译器包括剪枝和延迟加载等功能,这两种功能都能使JavaScript程序包最小化。这篇文章解释了它们是如何工作的,以及你如何在你的应用程序中使用它们。

默认的剪枝

当编译Flutter Web应用程序时,JavaScript程序包是由dart2js编译器生成的。发布编译有最高级别的优化,其中包括给你的代码剪枝。

剪枝是消除死代码的过程,只包括保证被执行的代码。这意味着你不需要担心你的应用程序所包含的库的大小,因为未使用的类或函数会被排除在编译的JavaScript程序包中。

要查看剪枝的操作:

  1. 创建一个Dart文件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'))。
}
  1. 在终端运行dart2js -O4 greeter.dart,看看生成的输出out.js。

在生成的JavaScript代码中,没有任何对SwedishGreeter类的引用,也没有任何对字符串Hej $name的包含,因为它在编译器摇树时被删除了。

编译器只能通过静态分析来弄清楚哪些代码是可以到达的,哪些是死代码。以下面的例子为例,根据系统的locale来定义greeter:

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

编译器不知道用户的系统语言,因此在JavaScript程序包中包含EnglishGreeterSwedishGreeter。对于这样的用例,延迟加载可以帮助最小化初始程序包的大小。

只有在需要的时候才加载代码,采用延迟加载的方式

延迟加载,也称为懒惰加载,允许你在需要时加载库。它可以用来加载应用程序中很少使用的功能。请注意,延迟加载是dart2js的一个功能,所以这个功能不适用于Flutter移动应用。在最简单的情况下,将一个导入的包或文件标记为延迟,并在使用它之前等待其加载:

import 'greeter.dart' deferred as greeter;

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

编译这段代码会生成两个JavaScript文件。当loadLibrary在延迟导入上被调用时,它会加载greeter库。

在Flutter中,所有的东西都是widget,你可能想利用FutureBuilder。一个widget的构建方法被期望是同步的,因此你不能在构建方法里面调用 awaitloadLibrary。然而,你可以在构建方法中返回一个FutureBuilder,你也可以在库加载时使用它来显示不同的UI:

import 'greeter.dart' deferred as greeter;

FutureBuilder(
  未来:greeter.loadLibrary()。
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState. done) {
      return Text(greeter.greet('World'))。
    } else {
      return Text('Loading...');
    }
  },
)

要自己尝试(在GitHub上查看完整的示例),打开Chrome DevTools并单击网络选项卡以检查网络活动。重新加载页面,查看何时加载并导入库。在下面的截图中,加载main.dart.js_1.part.js文件被推迟:

延迟加载Flutter Gallery中的本地化内容。

Flutter Gallery支持超过70种语言,但大多数用户只使用一种语言。推迟加载本地化字符串是这个功能的一大用途。例如,在Flutter Gallery中实现了本地化字符串的延迟加载后,应用程序的初始JavaScript程序包大小减少了一半。如果你的Flutter Web应用中有很多本地化字符串,可以考虑推迟加载这些文件。gen_l10n.dart脚本中包含了标志--use-deferred-loading来达到这个目的(目前只有1.19 SDK主通道上有)。

这篇文章是一个系列的一部分,讲述了我们在提高Flutter Gallery的性能时学到的东西。我希望你发现它是有用的,你学到了一些东西,你可以应用到你的Flutter web应用中!


通过www.DeepL.com/Translator(免费版)翻译