lottie-flutter icon indicating copy to clipboard operation
lottie-flutter copied to clipboard

Poor performance on web comparing to lottie web

Open nulld opened this issue 4 years ago • 7 comments
trafficstars

Hello, First of all - great library and good api desing, thanks for publish it.

I have react.js project with rich lottie animations and considering porting it to flutter to make it crossplatform. Just made first test with our animations in flutter and got profile measures.

  1. Our current react.js version looks like: image

  2. Flutter with the same animation looks like: image

So I have some questions:

  1. Is it flutter web problem or performance can be tuned inside plugin? (noticed that using this library switching web renderer to  CanvasKit renderer and forcing it to HTML renderer don't work at all)
  2. Which version lottie runtime it wraps in case of web platform?
  3. If it not https://github.com/airbnb/lottie-web, did you considered to use it?

UPDATE: minimal representation example here: https://github.com/nulld/lottie-flutter-issue140 And hosted results with github pages:

build with this plugin is here https://nulld.github.io/#/ (it looks smoth for me only on devices with top cpus like apple m1) https://nulld.github.io/4compare_canvas/ (lottie web with canvas renderer - looks smoth on mobile browsers too) https://nulld.github.io/4compare_svg/ (lottie web with svg renderer) (looks smoth on mobile browsers too, and looks the best in profiler)

Hope it will help investigating performance issue.

nulld avatar Mar 08 '21 09:03 nulld

Which version of flutter are you using? Recently Flutter 2.0 was released and web is now stable, and its performance increased considerably using the new canvas-kit renderer

EDIT: Make sure to run it on release mode for better performance

bdlukaa avatar Mar 08 '21 15:03 bdlukaa

Thanks for fast response - double checked my build options:

Flutter 2.0.1 • channel beta • https://github.com/flutter/flutter.git
Framework • revision c5a4b4029c (4 days ago) • 2021-03-04 09:47:48 -0800
Engine • revision 40441def69
Tools • Dart 2.12.0
igorvasilev@MacBook-Pro-Igor fabula_app % flutter build web --release --verbose
[ +128 ms] executing: [/Users/igorvasilev/devel/flutter/] git -c log.showSignature=false log -n 1 --pretty=format:%H
[  +75 ms] Exit code 0 from: git -c log.showSignature=false log -n 1 --pretty=format:%H
[   +4 ms] c5a4b4029c0798f37c4a39b479d7cb75daa7b05c
[   +1 ms] executing: [/Users/igorvasilev/devel/flutter/] git tag --points-at c5a4b4029c0798f37c4a39b479d7cb75daa7b05c
[ +106 ms] Exit code 0 from: git tag --points-at c5a4b4029c0798f37c4a39b479d7cb75daa7b05c
[   +1 ms] 2.0.1
[  +74 ms] executing: [/Users/igorvasilev/devel/flutter/] git rev-parse --abbrev-ref --symbolic @{u}
[  +39 ms] Exit code 0 from: git rev-parse --abbrev-ref --symbolic @{u}
[        ] origin/beta
[        ] executing: [/Users/igorvasilev/devel/flutter/] git ls-remote --get-url origin
[  +26 ms] Exit code 0 from: git ls-remote --get-url origin
[   +1 ms] https://github.com/flutter/flutter.git
[ +104 ms] executing: [/Users/igorvasilev/devel/flutter/] git rev-parse --abbrev-ref HEAD
[  +30 ms] Exit code 0 from: git rev-parse --abbrev-ref HEAD
[        ] beta
[  +14 ms] executing: sw_vers -productName
[  +34 ms] Exit code 0 from: sw_vers -productName
[        ] macOS
[        ] executing: sw_vers -productVersion
[  +32 ms] Exit code 0 from: sw_vers -productVersion
[   +1 ms] 11.2.1
[        ] executing: sw_vers -buildVersion
[  +34 ms] Exit code 0 from: sw_vers -buildVersion
[   +1 ms] 20D74
[  +21 ms] executing: sysctl hw.optional.arm64
[  +21 ms] Exit code 0 from: sysctl hw.optional.arm64
[        ] hw.optional.arm64: 1
[ +100 ms] Artifact Instance of 'AndroidGenSnapshotArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'AndroidInternalBuildArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'IOSEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterWebSdk' is not required, skipping update.
[   +7 ms] Artifact Instance of 'WindowsEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'MacOSEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'LinuxEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'LinuxFuchsiaSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'MacOSFuchsiaSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterRunnerSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterRunnerDebugSymbols' is not required, skipping update.
[  +76 ms] Artifact Instance of 'MaterialFonts' is not required, skipping update.
[        ] Artifact Instance of 'GradleWrapper' is not required, skipping update.
[        ] Artifact Instance of 'AndroidGenSnapshotArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'AndroidInternalBuildArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'IOSEngineArtifacts' is not required, skipping update.
[   +1 ms] Artifact Instance of 'FlutterSdk' is not required, skipping update.
[        ] Artifact Instance of 'WindowsEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'MacOSEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'LinuxEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'LinuxFuchsiaSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'MacOSFuchsiaSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterRunnerSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterRunnerDebugSymbols' is not required, skipping update.
[        ] Artifact Instance of 'IosUsbArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'IosUsbArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'IosUsbArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'IosUsbArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'IosUsbArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FontSubsetArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'PubDependencies' is not required, skipping update.
[  +89 ms] Skipping pub get: version match.
[ +219 ms] Generating /Users/igorvasilev/devel/fabula/fabula_app/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java
[  +93 ms] Building without sound null safety
[        ] For more information see https://dart.dev/null-safety/unsound-null-safety
[  +74 ms] Compiling lib/main.dart for the Web...
[   +5 ms] Initializing file store
[   +5 ms] Done initializing file store
[  +74 ms] Skipping target: web_entrypoint
[   +3 ms] Skipping target: gen_localizations
[ +398 ms] dart2js: Starting due to {InvalidatedReason.inputChanged}
[+21938 ms] dart2js: Complete
[  +66 ms] invalidated build due to missing files: /Users/igorvasilev/devel/fabula/fabula_app/DOES_NOT_EXIST_RERUN_FOR_WILDCARD956567665
[  +65 ms] web_release_bundle: Starting due to {InvalidatedReason.inputChanged, InvalidatedReason.inputMissing}
[ +171 ms] Manifest contained wildcard assets. Inserting missing file into build graph to force rerun. for more information see #56466.
[  +32 ms] web_release_bundle: Complete
[  +75 ms] web_service_worker: Starting due to {InvalidatedReason.inputChanged}
[  +58 ms] web_service_worker: Complete
[   +2 ms] Persisting file store
[   +7 ms] Done persisting file store
[  +31 ms] Compiling lib/main.dart for the Web... (completed in 22,9s)
[  +12 ms] "flutter web" took 23 563ms.
[  +96 ms] ensureAnalyticsSent: 87ms
[   +2 ms] Running shutdown hooks
[        ] Shutdown hooks complete
[        ] exiting with code 0

Result seems better but worse than lottie-web version:

image

nulld avatar Mar 08 '21 17:03 nulld

Hi

Is it flutter web problem or performance can be tuned inside plugin? (noticed that using this library switching web renderer to CanvasKit renderer and forcing it to HTML renderer don't work at all)

You should definitely use the canvaskit web-renderer if you use this library. Performance and correctness will be better. flutter run -d chrome --web-renderer canvaskit (and --release flag to compare performance)

Which version lottie runtime it wraps in case of web platform?

This package is a Dart port of the Android lottie library. This is the same Dart code that will be used in all platforms (ios, android, web...). We are NOT using the web lottie implementation. When targeting the Web, Flutter will compile your application (and this library) to javascript. Under the hood, Flutter will use Skia in WebGL (canvaskit) to make the actual drawing.

If it not https://github.com/airbnb/lottie-web, did you considered to use it?

There are other packages that use the "official" lottie libraries for each platform and bind it to the flutter canvas using an "external texture". This is a totally different approach that has its pros and cons.

I would love if someone has the time to dig into the timelines to understand the performance differences between the 2 implementations.

xvrh avatar Mar 08 '21 20:03 xvrh

Thanks for the clear explanation. Anyway, gathered minimal representation example here: https://github.com/nulld/lottie-flutter-issue140 And hosted results with github pages:

  • build with this plugin is here https://nulld.github.io/#/ (it looks smoth for me only on devices with top cpus like apple m1)
  • https://nulld.github.io/4compare_canvas/ (lottie web with canvas renderer - looks smoth on mobile browsers too)
  • https://nulld.github.io/4compare_svg/ (lottie web with svg renderer) (looks smoth on mobile browsers too, and looks the best in profiler)

Hope it will help investigating performance issue.

bind it to the flutter canvas using an "external texture"

Please excuse me for newbie question, but just wonders - doesn't flutter have an easy way to embed custom html+js to flutter widget tree for web platform (without using texture)? I've played a little bit with this thing HtmlElementView (looks like the piece of puzzle I seek) but stucked with styling container for it. And if the way for embeding html+js will be found, I can easy change implementation for web (wrapping oficial lottie-web) via conditional import, can I? (something like: import 'package:lottie/lottie.dart' if (dart.library.html) 'lottie/web_lottie.dart' as lottie;)

nulld avatar Mar 08 '21 22:03 nulld

Thanks for the reproductions. That would be great if someone has time to look at it in details to identify where the bottlenecks are.

doesn't flutter have an easy way to embed custom html+js to flutter widget tree for web platform

I think HtmlElementView falls in the same category as "external texture". It is a valid approach but it's a different effort.

xvrh avatar Mar 09 '21 07:03 xvrh

There are other packages that use the "official" lottie libraries for each platform and bind it to the flutter canvas using an "external texture". This is a totally different approach that has its pros and cons.

I think HtmlElementView falls in the same category as "external texture"

Will be grateful if U provide some links to packages or(samples/cookbooks) with this alternative approach (can't find anything..).

nulld avatar Mar 09 '21 10:03 nulld

Thanks for the reproductions.

NP, attached them to issue description.

nulld avatar Mar 09 '21 10:03 nulld