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

2

9

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!

Insurmountable answered 28/9, 2021 at 7:37 Comment(0)
K
3

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),
      ],
    ),
  ];
}

Update September 2022: qlevar_router is not the only package that supports deferred loading, you can also use auto_route.

Kassandra answered 22/2, 2022 at 9:57 Comment(0)
F
0

I agree with previous answer and the shared links there are on spot.

However, as a partial solution to the overall problem, it is important to check the imported libraries and consider if their weight is justified on your app. If you need 2MB more just to load a font, maybe you can find a workaround for that.

It can help to have a look at the main.js itself (both minified and unminified version, as in the web release in debug if it helps). In some cases there is a huge amount of repeated functions that may just define wrappers for similar params.

In my case avoiding google-fonts and use a simpler almost equal font reduced the size of 40% (24% faster load after compression).

Feudatory answered 28/8, 2022 at 10:12 Comment(3)
What is your recommendation for simpler, equivalent font for Google fonts?Sportswear
use flaticon fontTallia
The deferred concept is not helping me. the main.js file size only reduced from 3.5MB to 3.1MB. is there no other way to reduce the size of main.js file.Highlands

© 2022 - 2024 — McMap. All rights reserved.