Reduce/split size of Flutter generated web-output file "main.dart.js"?

444

I know that I'm late, but for anyone who stumbles across this question: there is currently no official solution to the problem, but if you check this GitHub issue discussion, by the end of it, you will be led to a Medium article. This is merely a workaround based on the idea of deferred loading with the use of qlevar_router package.

For a proof-of-concept project, please check the GitHub repository of the aforementioned Medium article author. A short excerpt, so you get the gist of it:

class DefferedLoader extends QMiddleware {
  final Future<dynamic> Function() loader;

  DefferedLoader(this.loader);
  @override
  Future onEnter() async {
    await loader();
  }
}

class Routes {
  static final routes = <QRoute>[
    QRoute(path: '/', builder: () => const MainPage()),
    QRoute(
      path: '/users',
      builder: () => users.UsersPage(),
      middleware: [
        DefferedLoader(users.loadLibrary),
      ],
    ),
    QRoute(
      path: '/categories',
      builder: () => categories.CategorysPage(),
      middleware: [
        DefferedLoader(categories.loadLibrary),
      ],
    ),
  ];
}
Share:
444
Defarine
Author by

Defarine

Updated on January 01, 2023

Comments

  • Defarine
    Defarine over 1 year

    I just built an example Flutter app and I wanted to deploy it as an web application. Flutter generates a single file called main.dart.js. However, using a few dialogs, animations and so on, this js file is already almost 2MB of size (built using flutter build web).

    Now I have deployed it on an aws-webserver --- but opening it takes about 5sec to appear while the screen is completely blank. This is not a good experience :-(

    So, the question is how to reduce/split the size of the generated main.dart.js, so that the web application starts sooner? I already tried to use Dart deferred loading:

    import 'secondpage.dart' deferred as secondpage;
    <...>
    class MyApp extends StatelessWidget {
      final Future<void> loadedLibrary = secondpage.loadLibrary();
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          title: 'Flutter Admin Panel',
          theme: ThemeData.dark().copyWith(
            scaffoldBackgroundColor: bgColor,
            textTheme: GoogleFonts.poppinsTextTheme(Theme.of(context).textTheme)
                .apply(bodyColor: Colors.white),
            canvasColor: secondaryColor,
          ),
          navigatorObservers: [TransitionRouteObserver()],
          initialRoute: 'login',
          onUnknownRoute: (context) => null,
          routes: {
            'login': (context) => const LoginScreen(),
            'admin': (context) =>FutureBuilder(
                future: loadedLibrary,
                builder: (snapshot, context) {
                  return secondpage.SecondPage();
                })
          },
        );
    

    This approach indeed generates a second js file called main.dart.js_1.part.js. But this file is only 1KB of size while the main.dart.js is still of 2MB size.. So no improvement here.

    Are there any other options or ideas to "improve startup time" of a Flutter web-app? Thanks!