flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
166.13k stars 27.43k forks source link

dependencies cost indicator #35957

Open amreniouinnovent opened 5 years ago

amreniouinnovent commented 5 years ago

Use case

When I add a dependency I don't know how much of size it will add to my project

Proposal

When I run flutter packages get I want to get these packages cost For example Flutter web it will show to me js cost 14kb For Flutter Android it will show to me 100kb the total of the package aar, jar, images, java files, and the total size after compiling.

I think it could be by some simple scripts to each platform

dnfield commented 5 years ago

I don't think there's a way to do this short of producing your release artifacts and then measuring the size yourself.

Dart uses tree shaking - so a given package might be very large in Dart code, but very small for what you use from it. On top of that, each release artifact type has different characteristics - if you end up producing a .aab, for example, that's now how large things will be on the device. Similarly for an .ipa.

It may help to have a look at our own benchmarks for this for some of our example apps:

https://github.com/flutter/flutter/blob/master/dev/devicelab/bin/tasks/web_size__compile_test.dart https://github.com/flutter/flutter/blob/master/dev/devicelab/bin/tasks/basic_material_app_android__compile.dart

There are several others as well. If you trace through those, you'll see they basically boil down to flutter build <command> --release and then getting the output file size.

amreniouinnovent commented 5 years ago

@dnfield I started to use your SVG library. It really helped me. When I added it I figure out that it would be helpful to get a better understanding of the cost of every dependency we add to the project.

Later when flutter projects became bigger we will have more than 10 libraries or 15 per project.

For Flutter to work on the web, mobile, desktop we will have a variety of libraries to support each platform unique feature like "add an app shortcut to taskbar library on the desktop".

For sure to get the dependency cost we need to compile each plugin we add but it will not take that much time and it will cache for the next build like what Gradle do for caching.

At least this feature could be implemented to Flutter web same as npm dependency cost then we could port to the other platforms

Sample of reactjs cost https://bundlephobia.com/result?p=react@16.8.6 image

dnfield commented 5 years ago

I don't think this is a bad idea, and I don't think it's impossible, but it seems difficult.

For Web it's probably more doable.

For Android or iOS, we'd have to track down all the dependencies in Dart, Gradle, Cocoapods, etc. It gets a little harder, and it seems like we'd really just be interested in what happens when you build a release bundle with that code.

jonahwilliams commented 5 years ago

dart2js supports a --dump-info option which contains the retained classes from each library (and even has a visualizer: https://github.com/dart-lang/dump-info-visualizer). dart aot has similar functionality to dump a heapmap which can be processed by chrome devtools.

amreniouinnovent commented 5 years ago

I think this would help for Android but I don't know where I should add task depsize

task depsize  {
    doLast {
        final formatStr = "%,10.2f"
        final conf = configurations.default
        final size = conf.collect { it.length() / (1024 * 1024) }.sum()
        final out = new StringBuffer()
        out << 'Total dependencies size:'.padRight(45)
        out << "${String.format(formatStr, size)} Mb\n\n"
        conf.sort { -it.length() }
            .each {
                out << "${it.name}".padRight(45)
                out << "${String.format(formatStr, (it.length() / 1024))} kb\n"
            }
        println(out)
    }
}

https://stackoverflow.com/questions/36897343/how-to-calculate-the-size-of-libraries-that-is-added-as-a-dependency-in-the-andr https://gist.github.com/medvedev/968119d7786966d9ed4442ae17aca279

zanderso commented 4 years ago

@zoeyfan Could you give a little background either here or offline about why this is customer critical? Thanks!

talisk commented 4 years ago

Hi @zanderso We found our App.framework is very large on iOS platform. As the business grows, the size grows quickly. Now we use flutter build aot with --print_instructions_sizes_to to analysis the cause. We found that one of the packages we used referenced many other packages.

But this is a problem that was discovered at the end of the development phase. If we can find out at the outset how much other packages it depends on. We may not use it, we may choose to develop it ourselves and use the least dependencies on other packages.

Although I know Dart uses tree shaking. Can you provide an estimated value, showing the size of the package dependent part.

amreniouinnovent commented 4 years ago

@zanderso I want to use "font-awesome " icons instead of Material Icons but I don't know if it will add just 500kb or 1 MB to my project

The more flutter projects get more complex will end with 50 libraries for just 1 project

One of my projects I have 40 libraries..it is for bus tracking like Uber

`dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter

cupertino_icons: ^0.1.2 flutter_statusbarcolor: ^0.2.1 http: ^0.12.0+2 json_annotation: ^2.4.0 connectivity: ^0.4.3+2 shared_preferences: ^0.5.3+4 equatable: ^0.6.1 flutter_bloc: ^2.0.0 flutter_svg: ^0.13.1 dio: 2.1.16 package_info: ^0.4.0+6 intl: ^0.15.8 pull_to_refresh: ^1.5.2 url_launcher: ^5.1.1 camera: ^0.5.4+1 path_provider: ^1.2.0 path: ^1.6.2 image_picker: ^0.6.1 image_cropper: ^1.0.2 acs_nfc: ^1.0.2 zk_finger: ^1.0.10 flutter_stetho: ^0.3.0 serial_number: ^0.1.0 flutter_advanced_networkimage: ^0.5.0 location: ^2.3.5 google_maps_flutter: ^0.5.20+6 launch_review: ^2.0.0 permission_handler: '^3.2.0' percent_indicator: ^2.1.1+1 firebase_crashlytics: ^0.1.0+3 wakelock: ^0.1.2+8 flutter_background_location: ^0.0.4 moor_flutter: ^1.7.0 firebase_performance: ^0.3.0+5 battery: ^0.3.0+5 unicorndial: ^1.1.5 device_info: ^0.4.0+3 mei_plugin: ^1.1.4 flutter_nfc_reader: ^0.1.0 mqtt_client: ^5.6.0

dev_dependencies: flutter_test: sdk: flutter build_runner: ^1.0.0 json_serializable: ^3.0.0 intl_translation: ^0.17.5 moor_generator: ^1.7.1`

zanderso commented 4 years ago

It sounds like there's more than one feature request here. When pulling in a new package:

  1. Give some notification about new transitive dependencies.
  2. Give the contribution of the new package to release binary size (or an estimate).

For (1), I see that there is a "pubviz" package on pub maintained by @kevmoo. It would be interesting if it could highlight diffs before/after a pubspec.yaml update.

For (2), because of the tree-shaking, I'm skeptical that we can give a reliable estimate of the contribution of a package to binary size before actually doing a release build. It will be different for every app, and will even change over time for the same app. We can certainly try to make gen_snapshot flags like --print_instructions_sizes_to and some others more useful, though. We may also be able to gather statistics if a package has many users, and report them back in some way, but this idea is more speculative.

amorenew commented 4 years ago

New Flutter 1.22 added --analyze-size flag which does the required result but on build only

amorenew commented 4 years ago

While --analyze-size works fine it still requires release and building https://flutter.dev/docs/development/tools/devtools/app-size#generating-size-files

@dnfield New tool is doing the trick but in release build If you think I should keep the issue open or you can close it.

MrHBS commented 3 years ago

@dnfield I suppose this can be closed