Flutter apps are too big in size
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Flutter, an open-source UI toolkit by Google, has gained significant popularity for building natively compiled applications for mobile, web, and desktop from a single codebase. Despite its numerous benefits, one of the criticisms it faces is the large size of the apps it produces. This article delves into the reasons behind the large size of Flutter apps and provides technical insights and examples.
The Anatomy of a Flutter App
Before understanding the reasons for the larger app sizes, it's important to understand how a Flutter app is constructed:
- Framework and Engine: At the core of a Flutter app are the framework and engine. The framework is written in Dart, which includes an extensive set of libraries like widgets, rendering, and animation. The engine, primarily written in C++, handles rendering, input, and compiling the Dart code into native platform code.
- Assets: Flutter allows developers to include various assets such as images, fonts, and other resources that contribute to the app size.
- Compiler and Build System: Flutter relies on a Just-In-Time (JIT) compiler during the development phase and an Ahead-Of-Time (AOT) compiler when building release versions. While AOT compilation is efficient at runtime, it can increase app size due to the inclusion of the Dart Virtual Machine and framework libraries.
Reasons for Large App Sizes
1. Inclusion of Flutter Engine
Flutter apps include the entire Flutter engine as part of the compiled binary. This inclusion ensures that apps function independently of platform-specific runtime environments, but it inevitably increases the baseline size of the application.
2. Full Platform Support
Flutter apps need to support a wide range of devices and operating system versions, which requires bundling numerous libraries and codes to ensure compatibility. This support leads to larger binaries since redundant and fallback implementations might be part of the package.
3. Resource and Asset Bundling
Flutter allows for the seamless inclusion of multimedia resources that can inflate the app size. As applications grow richer in graphic and media content, the resource payload increases.
4. Lack of Tree Shaking for All Dependencies
Tree shaking is a process that removes unused code, but the efficacy depends on the dependencies used in the app. Optimally shaking the trees for certain dynamic and reflective libraries can be challenging, sometimes leading to additional code being packaged with the app.
5. Debugging Information and Symbols
During the development phase, debugging information and symbols are included within the build. Although not part of the production release, these contribute to large app sizes during testing.
Technical Example
Consider a Flutter app that uses a simple image carousel widget with heavy library dependencies for animations and gestures. While the widget could be lightweight in implementation:
- The inclusion of animation libraries for smooth transitions can add tens of megabytes.
- Gesture libraries for multi-touch and advanced interactions increase the codebase further.
- Every image or media file adds to the app's asset payload.
To alleviate this, developers would need to carefully manage dependencies, use optimized formats for images and resources, and employ Flutter tools for asset compression.
Reducing Flutter App Sizes
Developers can take several steps to minimize app sizes:
- Code Splitting and Deferring: Splitting the application code into smaller parts and only loading what is necessary can reduce the initial app size.
- Efficient Asset Management: Use tools that compress and optimize image and asset files.
- Dependency Pruning: Regular audits of dependencies and removal of unused packages help keep the app leaner.
- Using `flutter build apk` with Different Flags: Adjusting flags like `--split-per-abi` splits the binary for architecture-specific builds, minimizing the payload for each installation.
- Minifying Libraries: Employ Dart's library minification techniques to remove unnecessary parts of libraries.
Summary Table
| Aspect | Description | Impact on Size |
| Inclusion of Flutter Engine | Entire engine included in every app | High |
| Full Platform Support | Bundling libraries for widespread compatibility | Medium |
| Resource and Asset Bundling | Heavy media can significantly inflate app size | High |
| Tree Shaking Limitations | Ineffective on certain dynamic dependencies | Medium |
| Debugging Symbols | Included in debug builds for development | Low (for release builds) |
Conclusion
While the ease and efficiency of Flutter offer numerous advantages, developers must be vigilant about best practices to manage app size. By employing diligent coding strategies, efficient asset management, and appropriate compilation options, Flutter apps can be optimized to reduce size while maintaining their rich functionality and user experience. However, the inherent structure and design of Flutter apps will always maintain a certain baseline size due to the embedded engine and comprehensive library support.

