Investigate wiring up Metal Binary Archives on iOS.

Introduced at WWDC 2020, Metal Binary Archives speed up creation of pipeline state objects. In Flutter, these objects are created as necessary within a frame workload on the raster thread. This can cause jank. Investigate persisting these archives (shipping them if possible in the application bundle) and loading them (possibly via the Skia persistent cache interface) at runtime to reduce jank during startup.
Tracking issue in Skia: https://bugs.chromium.org/p/skia/issues/detail?id=10804

Issue containing phrase "This can cause jank," in case of Flutter, should have highest possible priority by default, IMHO,

We've noticed new sources of jank after Flutter switched to Metal. I agree that these should be high priority tasks.

Please investigate to possibly add this to flutter, I am experiencing terrible jank animations on iOS on startup.

What could the timing be for a fix to these startup jank issues? We're completely invested in Flutter at this point, and it's frustrating to say the least that it's currently not possible for us to have smooth non-janky animations at startup, especially considering how important the startup experience is for onboarding and engaging new users.

Elevated the priority of this issue with the Skia team. Adjusting here. Will elevate the priority here further once a milestone can be set.

In case anyone comes here looking for a workaround to startup jank issues, there are OpenGL compiled frameworks available here: https://github.com/acoutts/flutter-engines-no-metal
A more detailed report on our experience with these OpenGL frameworks: https://github.com/flutter/flutter/issues/61045#issuecomment-700263745

Thank you @kbokarius! That does significantly improve performance of first-time animations. Unfortunately, disabling Metal seems to result in several visual regressions in other areas of my app, but maybe it's worth the tradeoff. Thankfully this article drastically improved performance on Android without sacrificing visual quality.
It's really a shame, since Flutter is supposed to support 60 FPS out of the box, but there doesn't seem to be any way to run reasonably simple animations on iOS without significant performance hitches on the first run. My app's onboarding animations are currently an awful first impression on iOS, far from the smooth experience the framework promises. :(

@doppio we're going to test and launch on Android after we launch iOS next month, so we haven't gotten to Android yet. All of our testing was done on iOS so far. Reading your message, it isn't clear if you've tried to disable Metal on iOS? I assume you did, and you ran into other visual regressions? In our case, simplifying our animations and reducing their overall visual attractiveness was well worth alleviating the startup animation jank. First time impressions are absolutely critical for consumer applications, so honestly I'm not sure what we're going to do if our comprehensive QA testing tonight with the OpenGL iOS build doesn't prove successful. I just can't imagine having to launch with that startup jank. I'd almost consider removing those animations altogether, as bad as that sounds.

@kbokarius Yes, I tried disabling Metal on iOS and ran into other visual regressions.  I definitely cannot launch with the startup jank either, so I'll either need to wait for a fix or find a workaround for my visual regression issues as you suggest.
Even with workarounds for the regressions, it will add a non-trivial amount of wasted dev time to build/download new "no-Metal" versions of the framework, get it set up with our CI/CD system etc. I think for now, I'll keep my fingers crossed and hope for a fix, since I'm still several months from a possible release candidate.

@kbokarius i tried the method with the compiled frameworks you supplied, also doing the "SkSL warm up". I think i experienced some performance improvment, but there is still some yank when i open the first page (push a fullscreen MaterialPageRoute), which has simple UI and no animations. I experience the yank on iOS (iPhone 7), Android seem fine.

That sounds like a different issue, @erf. Try exploring the Flutter DevTools to see if you can pin down what's causing the jank in your case.

Quick update on our situation: unfortunately, despite the improvement to startup jank, QA testing did show that our app has OOM crashes intermittently on both 12.X and 13.X devices with the OpenGL frameworks. It looks like we'll have to launch on iOS next month with startup jank. Hopefully we'll have a solution available for Metal soon.

Quick update on our situation: unfortunately, despite the improvement to startup jank, QA testing did show that our app has OOM crashes intermittently on both 12.X and 13.X devices with the OpenGL frameworks. It looks like we'll have to launch on iOS next month with startup jank. Hopefully we'll have a solution available for Metal soon.

I recently found the same issue in my app. I think once you have more than a few basic screens / animations it quickly becomes unstable. I'm no longer recommending anyone runs OpenGL because of the potential for stability issues. I understand OpenGL is no longer supported either, so fingers crossed this will be resolved soon.

Quick update on our situation: unfortunately, despite the improvement to startup jank, QA testing did show that our app has OOM crashes intermittently on both 12.X and 13.X devices with the OpenGL frameworks. It looks like we'll have to launch on iOS next month with startup jank. Hopefully we'll have a solution available for Metal soon.

I recently found the same issue in my app. I think once you have more than a few basic screens / animations it quickly becomes unstable. I'm no longer recommending anyone runs OpenGL because of the potential for stability issues. I understand OpenGL is no longer supported either, so fingers crossed this will be resolved soon.

That is a pity. I released my app with OpenGL, there are much fewer janks, but users complain that the app is unstable.
We really hope that the Flutter team will solve all the problems with metal soon 🤞🤞🤞

We had same issue for iOS devices =( If I understand right, no way to fix this problem right now ?

Could anyone from Flutter team say something about probable terms of solution for ios? As far as I know the issue became critical on ios after release of flutter 1.17.0 on stable channel 6 months ago. I think almost all of flutter developers who know about the cause of their app's lags need this information to choose 1 of 4 available options:

Downgrade to flutter 1.12
I don't know much about consequences of this option because I didn't try it yet. I can't remember critical issues for me from that time, probably firebase_crashlytics won't work, may be obfuscation. If there wasn't a problem with OOM crashes it's the best of the worst I think.
Release with no-metal flutter engine
I don't know about others, but I don't have testing team or variety of iPhones. I would test on couple iPhones I have and it seems to me I can possibly face OOM crashes on production and won't do anything about it.
Release with metal flutter engine
As for me the janks are so terrible and app is so unusable that the only result I would achieve is 1-star rating, angry users and ruined launch.
Wait for fix and add new features while issue is resolving. The question is how long?

I think it is pretty serious problem in Flutter. And they need write about it in the TITLE of main page http://flutter.dev.
If I knew about this problem, I would think twice about using flutter.

As one of the Flutter team said test-based shader warmup wasn't going to release in 2020 when the priority of this issue was P5 https://github.com/flutter/flutter/issues/53609#issuecomment-665180648. Now it's P3, may be it changes something.

I hope, I won't have rewritten my app to native code by the time when they fix it with P3 priority ))))

I agree with the sentiments here. Fortunately we were able to somewhat mitigate jank by simplifying our animations, but frankly the fact that we don't yet have an ETA and that there isn't a prominent warning about this issue is shameful. While we all appreciate Flutter as a great technology and the hard work the Google team puts into it, it's simply not fair to the community that 1) there is currently no ETA for a fix, and 2) that developers invest weeks or months into development before discovering this issue and being forced to either rewrite their app or delay release altogether.
@chinmaygarde and others: please consider increasing the priority of this issue further, and please give us an idea of how soon we can expect a solution.

An update from the Skia side: I started looking into adding MTLBinaryArchive support last week, and at this point it doesn't look like it will be difficult to drop it in as a side cache to our already existing persistent shader cache. I don't want to make a hard promise on completion as I have a lot of demands on my time, but I expect I should be able to get it done in the next few weeks, conservatively before the December break.

@jvanverth thank you for update, we all waiting for solution, since currently Flutter is not actually usable on iOS. Flutter 1.12.13-x still in production because of the iOS Metal janks.
But could you please clarify solution planned? Is that "something" we have to precache and include to the app build?
What about if some deep-in-app animation cannot be easily precached, it will be janky as any animation right now?
@meowofficial firebase_crashlytics has false Dart sdk version limit, you can easily fork it, fix Dard sdk version and use on old Flutter.

@meowofficial firebase_crashlytics has false Dart sdk version limit, you can easily fork it, fix Dard sdk version and use on old Flutter.

Thanks for idea!

@meowofficial firebase_crashlytics has false Dart sdk version limit, you can easily fork it, fix Dard sdk version and use on old Flutter.

@totalerex Unfortunately, there are way more packages that have to be downgraded (some of them can be with important bug fixes).
It is really really bad that the flutter team busy with the implementation of any other features while there is such an obvious problem with performance.

new Google Pay app released with this problem

@jvanverth @liyuqian I have a similar question as @totalrex, that is: even if the framework is able to cache shaders to file and bundle them, do developers still have to generate or «warm-up» these shaders manually similar to described [here](https://flutter.dev/docs/perf/rendering/shader#how-to-use-sksl-warmup  by testing out all the app features / widgets, or is this automated? Having to do this manually makes Flutter less attractive to me. I understand you guys are working hard on this issue and i wish you best of luck as many developers are very invested in this. Thanks!

@erf : the Metal binary shader archives/cache don't need any extra work from the developer. So no manual generations or tests are needed. The tradeoff is that it won't help the first animation after a fresh installation. All subsequent runs, even if the iOS app is completely closed, should be smooth. (Without it, the jank will reoccur after each iOS app close.)

@liyuqian ok, so the first run will always be yanky, before shaders are stored to disk?

First run after a fresh installation, yes. It's indeed not optimal. But it's a big step to let iOS Metal to catch up with our current state on Android.

Do you have any plans to reduce yank for a fresh install also?

While an inconvenience, it's certainly a huge step in the right direction. Unless you're constantly changing UI and animations, the overhead of generating the shader files isn't a big deal and will certainly more than suffice for us.

.. if you still are able to generate shaders for the inital fresh install.
I wonder how SwiftUI does this? I image there is no yank there, but that is a native compiled language with less overhead / layers so..

Do you have any plans to reduce yank for a fresh install also?

@erf : yes, its work and plan are tracked by https://github.com/flutter/flutter/issues/32170. We'll release more details there once available.

.. if you still are able to generate shaders for the inital fresh install.
I wonder how SwiftUI does this? I image there is no yank there, but that is a native compiled language with less overhead / layers so..

SwiftUI uses standard components. It has no need to precompile shaders.
We better be asking how Unity does this. Unity and Flutter have very similar approach

@alexandrius I think Unity literally stores the cache in the binary file.

@alexandrius I think Unity literally stores the cache in the binary file.

So why not do the same? Just curious

@alexandrius If they've done that the app would be too big.

Why not just compile or warm up all possible shaders?
If there are only a limited number of possible shaders, then Flutter could do a warm-up and compile all of them before-hand to avoid such jank. However, for the best overall performance, the Skia GPU backend used by Flutter can dynamically generate shaders based on a lot of parameters at runtime (for example, draws, device models, and driver versions). Due to all possible combinations of those parameters, the number of possible shaders is exponential. In short, Flutter uses programs (app, Flutter, and Skia code) to generate some other programs (shaders). The number of possible shader programs that Flutter can generate is simply too large.

@alexandrius If they've done that the app would be too big.

Why not just compile or warm up all possible shaders?
If there are only a limited number of possible shaders, then Flutter could do a warm-up and compile all of them before-hand to avoid such jank. However, for the best overall performance, the Skia GPU backend used by Flutter can dynamically generate shaders based on a lot of parameters at runtime (for example, draws, device models, and driver versions). Due to all possible combinations of those parameters, the number of possible shaders is exponential. In short, Flutter uses programs (app, Flutter, and Skia code) to generate some other programs (shaders). The number of possible shader programs that Flutter can generate is simply too large.

Just checked Google Pay app on iPad it is almost unusable on first run. It works like apps on Windows Mobile

Why apps builded with flutter 1.12 weren't janky without warmup? I tested it on iPhone 6s and one weak android device. As I understand, flutter 1.12 has the same problem with shaders.

I miss OpenGL

I just got the new iPhone SE and it seem the yank is almost gone there. Previously I tested on a iPhone 7 where the lag was more apparent. Maybe this is primarily an issue on "older" iPhones? I know iPhone 7 is not that old but still..

Newer phones have less jank in general. It all depends on how animation heavy your app is. Heavier animations will result in more startup jank on older devices, less on new devices. I suppose if your animations are light enough, you may not see startup jank at all on the newest devices. Our animations are fairly heavy and the startup jank will be there until we can bundle shader files.

I tried using SkSL warmup to pre-cache my apps shader files. There is definitely a difference as opposed to a built version with Metal enabled, but it's just not eliminating the startup/restarting jank completely.

For testing purposes, I have a basic ListView.builder that builds stateless const widgets and I run it on iPhone 8 with release mode.
It is janky as that my eyes can catch. Flutter wasn't like that before.
I continue to develop my app but this new Metal thing(!) just upsets me.
Btw, I believe it will be resolved.

Ok, guys, here's an update. Previously I didn't use OpenGL for my Flutter app in production because of crashes with plugins such as image_picker, but I just tried Flutter 1.22.4 with OpenGL which was compiled 2 days ago, and there was not crashes! Most importantly, animations was buttery smooth! No jank. I DID NOT even do the SkSL warmup thing. I did a fresh install and there was no startup jank. Previously there was jank even when launching animations such as a bottom action sheet. Animations like these were severely janky upon first launch, but now they are smooth as heck.
Why did Flutter even switch to Metal lol

@theniceboy what about UI degradation? Do u feel any difficulties with svg pictures, for example?

@alectogeek no, not with svg. We used the flutter_svg package pretty extensively (like for almost all icons in our app) and everything is running smoothly.
Surprisingly, I found scrolling became smoother. Idk why.

@theniceboy That's interesting. I will give it a spin as well. Our app has quite a number of animations using Flare library. Wonder if that will regress when switching back to OpenGL; will update here.
Seems like the regression at 99 percentile was observed accepted as happening only once on launch, and resolved by shaders. https://github.com/flutter/flutter/issues/53768 It's interesting how average performance improved with Metal but those are barely noticeable I guess.

We all understand this is a really frustrating issue. OpenGL has been deprecated by Apple, was running into some serious performance and jank issues, as well as some memory usage issues that the team was not able to make adequate progress on. We are committed to making the experience with Metal better than the experience with OpenGL. There is active work being done to implement metal binary archives in Skia.
Speaking plainly, two factors slowing this down right now are that we're in a time of year where many engineers take holiday, and that there's a global pandemic going on that both directly and indirectly impacts people working on this issue (or people who could potentially work on it).  These are, at best, frustrating times for all of us. Let's support each other and do our best.
And while we do have people working on this, don't forget that Flutter and Skia are both open source projects. Anyone concerned with this should feel empowered to checkout the source code and make improvements themselves.

@theniceboy Just switched engines to 1.22.4 Open GL and can't seem too notice a difference. Is there something I am missing ? Even though the animations in our applications are different, the average result should not be so far off.
It its worth noting that this is without using the SkSl warmup.

@dnfield , I think you are not too precise in suggestions:

Flutter 1.12.13 (OpenGL) is running on iOS smoothly until now. OpenGL was deprecated by Apple long time ago and nothing was preventing Google-Flutter team to postpone Metal-Flutter a little big more to time janks are resolved.
No excuses for not resolving janks issues since 1.17 was releases. Flutter just not usable on iOS now.
It is funny that you think we can find someone experienced in C++ (f.e. switched from C++ to Flutter) can help us with Skia :) . But I personaly think that you personally could help investigate why janks are much heavier in case using flutter_svg (published by you, right?), may be there is something special we could find workaround, my be there is nothing to do with shaders, may be there is bug in something related to drawPath or what ever used a lot in flutter_svg?

Our app is running on Flutter 1.12.13 and we have almost 40% dependencies forked in order to support old flutter and have dependencies updated. You can imagine how much work we do, all because our QA, and developers actually too, prefer to be fired than let users see such janks/lags. Don't Flutter team has manual testers? Than it is big gap :)
@csells @filiph, may be I'm too naive to hope you see this, but I and all people in trouble kindly ask you to investigate not this particular issue but the general problem we have with janks/lags on iOS after Flutter switched to Metal. This problem has big history and many bugs closed by formal reasons.

I downgraded to flutter 1.12.13 and janks are almost gone. I used a lot of non metal engines and every time faced animation stops in the middle of animation. For me it's the only way to release app on ios.

Looks like a good update from @jvanverth on the linked issue yesterday:

Basic binary cache support has been added. However, in MTLBinaryCache.h Apple mentions some issues with the usage pattern we have planned -- that is, updating the cache on the fly. Namely, it's possible to grow the cache without bound (especially with our dynamically generated shaders), and there's the possibility of cache corruption. For the former we may need a flag to indicate whether to write to the cache or not, or support multiple caches with size constraints. I'm not sure what the issue with the latter is -- possibly we need to track which pipeline have already been cached and skip trying to write those again.

Can someone please summarize the issue for those of us who aren't familiar with the Skia/Graphics side of things? Why does the Metal implementation require use to pre-cache items when OpenGL just ran everything fine first time & every time?

Can someone please summarize the issue for those of us who aren't familiar with the Skia/Graphics side of things? Why does the Metal implementation require us to pre-cache items when OpenGL just ran everything fine first time & every time? Is this something that can be wired up quickly or does this need extensive work with in-depth knowledge?
Also, the suggestion that I can help fix this problem is a little bewildering when I don't even understand what the issue is, and I have been working full time with Flutter for ~2 years now. It's an area that I've never had to deal with. I think the suggestion that the community can help out on this issue is... a little disheartening.
I assumed, perhaps wrongly, that Flutter team had made a commitment to handling all the low level jank for us at priority much higher than P5 or P3. For some reason I thought I saw @Hixie in another post/article say that jank was automatically P0 but I could be remembering that incorrectly.

With OpenGL, we had support for caching of binary shaders that were compiled; these are small programs that tell the GPU how to draw your application, and part of Skia's job is to create them from the code that the rest of Flutter feeds it. Caching them allows for reuse over the run of the application (and on some platforms, over subsequent runs), which reduces the load of compiling new ones as time went by and old ones could be reused.
On Metal, this functionality works slightly differently and is currently being implemented.
Secondly - for some applications, using OpenGL was not causing significant jank or memory pressure, but for others it was causing very severe jank and memory pressure that we lacked the ability to fix because Apple doesn't support OpenGL and all of the tooling/bug reporting resources are geared towards Metal at this point. If your application was working fine with OpenGL and you can't tolerate Metal, you could still use an older version of Flutter. This certainly isn't ideal, but the team made a decision to not temporarilly continue support for OpenGL since we had some pretty clear benchmarks and customer needs showing that the OpenGL backend was not cutting it and was hitting a wall. There are also only so many resources available to maintain the backend(s), and it's better to throw what we have at improving the way forward (Metal) rather than trying to maintain OpenGL and update Metal. In fact, a number of users who continued to make custom builds using OpenGL have run into such problems (unacceptable memory usage increases, incorrect rendering, etc.).
And thirdly - jank can come from many places. This is likely the source of at least some jank on iOS. It's being actively worked on.
And fourthly - my suggestion is not to say that you should start working on this even if you have no idea where to start, or that some random individual needs to start working on this because no one else is. But if you're passionate about this issue and interested, it might be a good place to start poking at things :) If not, for this specific issue, @jvanverth's work is going to resolve it before much longer.

@dnfield For this particular feature/issue, I just want to confirm that flutter app developers don't have anything to do to benefit from this, right?
Thanks!

Correct. This will roll in from Skia and just automatically take effect in Flutter.

Thank you for taking the time to explain it to me!

@dnfield  If Skia resolves cache for compiled shaders(jvanverth) on iOS, would it be possible to provide us a manual solution that would allow us to manually go through the app and after that include all the shaders in final ipa file that Skia could recompile on app start the way it is doing now on Android and iOS(where Open GL is used)?

(Side note - I was wrong, Flutter may have a little bit of work to do to make sure the cache gets saved at the right times, but it should be a relatively trivial amount of effort since we already do things like this - it will still not require any updates for app developers.)
The problem with shipping pre-built shaders is that shaders can have GPU specific features, and may not work on devices with even slightly different physical hardware compared to the hardware they were built for. However, there are "warmup" routines you can add - see https://flutter.dev/docs/perf/rendering/shader. Once persistent cache for Metal is wired up it should make it possible to do those using Metal (the docs currently say it's not possible on Metal, which is true today).

Ok, so this solution from jvanvarth is going to help with caching of shaders during runtime, but for shipping pre-build shaders we have to wait for persistent cache, do you have some deadlines for this?

Once the work in Skia is done, we can add the persistent cache changes to the engine side. I don't have an estimate of that right now, but it should be fairly trivial since we already have relevant code for it in place that just will need to be turned on.

@dnfield are you saying we need to do manual "warmup" on all the devices we'd like to support to avoid yank?

The problem with shipping pre-built shaders is that shaders can have GPU specific features, and may not work on devices with even slightly different physical hardware compared to the hardware they were built for. However, there are "warmup" routines you can add - see https://flutter.dev/docs/perf/rendering/shader. Once persistent cache for Metal is wired up it should make it possible to do those using Metal (the docs currently say it's not possible on Metal, which is true today).

An update from the Skia side: I started looking into adding MTLBinaryArchive support last week, and at this point it doesn't look like it will be difficult to drop it in as a side cache to our already existing persistent shader cache. I don't want to make a hard promise on completion as I have a lot of demands on my time, but I expect I should be able to get it done in the next few weeks, conservatively before the December break.

Sounds great!

I hope the update about this issue will come before December break

Take a look every day

@qingweiSun I think all of us are waiting for a fix.

I think we'd all appreciate this from the Flutter team as a holiday gift haha

I hope Google celebrates Chrismahanukwanzikastice.

Ok, I came from this reddit page about the poor performance of the new Google pay app written in Flutter . and now I'm just trying not to freak out. I have customers that has been promised great performance from Flutter

Suffice it to say, it is certainly troubling that Google itself is unable to release a performant app. Nevertheless, since we have neither the time nor the resources to completely rewrite our app, we'll continue to be cautiously optimistic about the solution to startup jank, general UI performance improvements, and the overall long-term viability of Flutter.

I still cannot understand why did they move to Metal? Yes, OpenGL is deprecated by Apple, but it was deprecated for a long time. Did not they see these awful janks? Did not the community start complaining about performance when the framework moved to Metal? I'm asking because I do not understand is there any valuable reason why we had to tolerate these changes and disadvantages of Metal?

@alectogeek This migration would be made one way or another. Obviously the process could not handled perfectly but I believe we will get a warm metal app soon.

My only complaint here is that it feels like metal was released against a deadline, not against a reasonable quality standard.

@furkansarihan Yeah, you're right. I know that it is a complicated process and I really appreciate the Flutter team's work, but let us be honest at the same time and say that it was the wrong decision to migrate the stable branch to Metal. Also, It was awful management of the project because the migration to Metal was in Spring, but we still do not have the solution. The applications written on Flutter are unusable on iOS. Our company loses (and still losing) money because of that. My reputation is damaged because it was my decision to invest in Flutter. I have no reason to be understanding now.
P.S. My offer to provide additional information about the current progress and problems on the Flutter.dev page was also rejected. (#70571) It could help to avoid the same problems as I did for new users.

Hello @arturfornal, such a sad story, but did you try flutter engine without Metal support? I solved the same problem with this repo, on most of iOS devices it is stable solution. Tried on iPhone 7, XS, 11 and iPad pro. https://github.com/acoutts/flutter-engines-no-metal

@Renesanse make sure you do a lot of testing across a number of devices to see if your app is truly stable. It appeared stable to us when we first tested with those OpenGL frameworks, but after our QA team repeatedly used features that had animations (especially on older 12.X devices), it became clear that the build was not as stable as it first appeared to be. We eventually saw intermittent crashes on even the newest iOS devices.

We have an enterprise-level app that we are building in flutter, and the first launch performance is horrible on iOS. This is especially bad due to onboarding -- new users will get a very bad impression, even though we use correct coding practices on our end. New users aren't going to manually warm up the animations by pressing them several times until they smooth out, they will simply go to the app store and leave a 1 star review for poor performance (which is exactly what other flutter devs reported happening to their production apps).
Furthermore, the flutter landing page falsely advertises "native performance", when due to the shader compilation issues, it is worse than react native and even web-view tools. This issue has been active for over a year now, and the flutter team inadequately addresses it with low priority, when it should be imperative.
We have invested a lot of time and money into this project, and we hope that this issue will be fixed by the time we release (1-2 months from now). This is not a hobby project, while many of these indie/hobby devs don't mind and pretend this is a minor issue, this is extremely important to us and our stakeholders (we have a responsibility to them and to our users as well).
I see the moderation team here loves closing similar threads that are straightforward and don't shower flutter with praise. Pretending it's tolerable and whatnot. This should not be a P3 issue, this should be P1.
Our investors are not happy with the current situation at all, and I will proceed with legal action if I have to, because I have a fiduciary duty to them in regards to their invested capital. Flutter made a misleading, deceptive statement about its performance, and if this is not fixed, it will cost my company time, money, and reputation.
Fix this issue immediately.

Totally agree, to be honest, big company where I work is making decision to use flutter or not. The situation right now is that budget xiaomi device for 50 bucks has better performance then iPhone 11.

@dnfield @Hixie I think bumping the priority on this would go a long way...

Totally agree, to be honest, big company where I work is making decision to use flutter or not. The situation right now is that budget xiaomi device for 50 bucks has better performance then iPhone 11.

Event the

Even the iPhone 12 Pro Max has a very poor performance on first launch.

Right now I'm negotiating on a project that has a great design with lots of animations. should I accept the project and hope this issue will be resolved by the next 2 month or that is a false hope? ANYONE?

We have a fully-animated (as in using full-screen animations during literally 100% of the app runtime) paid subscription app with thousands of users and not a single complaint about performance has been registered on iOS or Android.

We have a fully-animated (as in using full-screen animations during literally 100% of the app runtime) paid subscription app with thousands of users and not a single complaint about performance has been registered on iOS or Android.

I hope it is sarcasm, just create an app and call Cupertino dialog. You will notice huge FPS drop on any iOS device at first time. Can you provide a link to your application?

We have a fully-animated (as in using full-screen animations during literally 100% of the app runtime) paid subscription app with thousands of users and not a single complaint about performance has been registered on iOS or Android.

I hope it is sarcasm, just create an app and call Cupertino dialog. You will notice huge FPS drop on any iOS device at first time. Can you provide a link to your application?

I never said there weren't noticeable FPS drops. I said no customers have registered a complaint. Are you able to consciously recognize that these are two different things?

I think it's important to not make an assumption about how critical this is to different teams. For some projects it may be more critical than others. And of course being civil even in a thread that has emotional consequences is of utmost importance.

Although i do agree with some of the critique here, this is an issue tracker for solving a specific problem and not a discussion forum AFAIK. Try keep it relevant guys.

We have a fully-animated (as in using full-screen animations during literally 100% of the app runtime) paid subscription app with thousands of users and not a single complaint about performance has been registered on iOS or Android.

I hope it is sarcasm, just create an app and call Cupertino dialog. You will notice huge FPS drop on any iOS device at first time. Can you provide a link to your application?

I never said there weren't noticeable FPS drops. I said no customers have registered a complaint. Are you able to consciously recognize that these are two different things?

I can't believe in it. How iOS users didn't notice junks and animation lags. How is it possible that users didn't hit 1 star at review and didn't write something like "laggy app, don't like it".  Btw, sorry for misunderstanding.

I think it's important to not make an assumption about how critical this is to different teams. For some projects it may be more critical than others. And of course being civil, especially in a thread that is emotionally charged, is of utmost importance.

Truly enough, but not even you losing money and reputation as a developer. I understand people who disappointed about flutter right now. And I am ok if some one will write something like a "what the hack are you guys did with my great app during your updates" =)

I haven't seen this strategy mentioned anywhere on GitHub, Reddit or Medium yet, so I'll post it in case it helps other companies or individuals in a similar situation.
An important thing to recognize is that, at least on the many iOS devices we've tested, across many different apps, is that the the first-run jank is not on every animation, it's on every "unique" animation - the threshold of what makes an animation/shader unique isn't clear, but for example, it isn't on every popup, or every screen transition, but usually only on the first instance of it.
As a result, the perceptual issue varies dramatically based on how often new "unique" shaders are introduced in the UX flow. I've found that a good temporary workaround is to reduce the variation in animations, and reuse existing ones as often as possible.
Some specific examples of what we've implemented to help with this issue:
1. Use the same routing transition as often as possible.
In our experience, if you're able to use just one routing animation, the jank will only occur on the first route, even if the route contents change. Perhaps a user sees a routing jank once before signing in, and that's it. This one change alone can make a big perceptual difference, as opposed to seeing jank at minute 0, minute 3, minute 5, minute 6 and so on.
2. Reduce the number of unique modal elements.
It's ideal to have many different types of modals in different parts of the UI, based on context, like alerts, confirmation dialogs, tooltips, toasts, bottom sheets, and so on. But each of these will have first-run jank and it can look particularly bad. However, if you're able to temporarily consolidate those at all, and move the differences to the content itself, rather than the screen animation or container, you've reduced jank from possibly 6-7 times, spread out throughout the UX flow, to a single time, early on and more forgettable.
For example, instead of having a confirmation dialog, and an alert popup, and a tooltip, you use the same container and animation, and just change the content.
3. Reuse the same animation effects where possible, rather than making subtly different ones based on context.
Again, ideally you use context-specific animations and effects, but that comes at a performance cost right now. Moving to more generic animations and effects that can be used on many screens and many elements can help.
4. Change fluid animations to be short or instant.
Each "fluid" animation is more likely to need a shader warmup. This is hard to describe, so here are visual examples.
Animations like this will incur jank much more often:

Animations like this won't incur jank nearly as often and often perceptibly not at all:

Little things like this can add up to a noticeable real-world difference while this is being resolved, and have a real impact on end-user perception of the app.
Your mileage and ability to do this will vary dramatically, of course, but I hope this helps someone.

First let me say that the whole team is also concerned about our performance on Metal, and we completely agree that it is unacceptable as is; our architecture very much assumes that shaders will be cached. We empathize deeply with anyone whose application on iOS is suffering from jank because of this issue.
We have marked this P3 because that is the appropriate priority level in Flutter's priority scheme for something that we are actively working on which is of high priority. You can read more about our prioritization scheme on the wiki (https://github.com/flutter/flutter/wiki/Issue-hygiene#priorities). In short, however, P0-P2 levels are reserved for critical issues that are even more dire than this bug, and P3 is what we use for this kind of issue.
This issue is non-trivial and work is actively happening to address it. It is our intent to have this addressed by our next stable release, but we make no promises, because that's not how engineering works.

@Hixie when is the next stable release planned?

@Renesanse Hi, I played with both flutter versions, the worst situation I (or my boss) saw, was on his iPhone Xr on build with Metal support, on OpenGL it's a little better but only a little. When I started using cached shaders then on e.g. iPhone 6s (the slowest device I have) app works well and on iPhone 7, iPhone 12 Max Pro there are lags. After few reinstals (without changes in code!) app looks ok on random devices, or on all - strange and funny.
@stx I agree with your steps to improve iOS performance, but they're not fixing lags, only reducing them.
I decided to investigate Flutter as a replacement for native app development for some projects in my company but I after around 3 months I have Android version of app, QA and customers will not accept that performance on iOS. It's not big problem because as I said it was investigation but now, I'm not sure if I should propose Flutter as stable framework for some serious development.
When some guy said that Flutter documentation should inform potential new devs about that problem AT THE BEGINNING where they mention about NATIVE performance - I totally agree with him.

@Hixie Thanks for the explanation. Looking at the priority rules, it sounds like this would be a P1 issue if it was blocking someone with representation ("top-tier customer"), but if it's blocking someone without representation (small project or large project that does not have a relationship with Google) it's P3. I would suggest that there should be situations where P3 can be bumped to P2 or P1 that doesn't hinge solely on their "relationship status" with Google.

@Hixie Thanks for the explanation. Looking at the priority rules, it sounds like this would be a P1 issue if it was blocking someone with representation ("top-tier customer"), but if it's blocking someone without representation (small project or large project that does not have a formal relationship with Google) it's P3.
I would suggest that there should be situations where P3 can be bumped to P2 or P1 that doesn't hinge solely on their "relationship status" with Google, as a sum effect of a blocker, especially one that appears to be reputation threatening, would arguably exceed the negative impact of blocking one top-tier customer.
As a slightly humorous indicator of the seriousness of this issue, it has been reported that this is spawning conspiracy theory videos saying Apple has hamstrung Flutter intentionally by forcing migration to Metal. Maybe P1 could also be for issues that are breeding conspiracy theories. 😅

I do agree, perhaps you could create a separate issue for this suggestion and the discussion for that can continue there.

I hope the update about this issue will come before December break

The discussion continued day after day, and I don't expect that there will be a warm Christmas holiday, no update, no planing for this issue, I've always thought user experience was what helped me choose Flutter, lol.

The discussion continued day after day, and I don't expect that there will be a warm Christmas holiday, no update, no planing for this issue, I've always thought user experience was what helped me choose Flutter, lol.

@vukhacbiet While I am upset at the effects this issue causes, it's not fair saying this.

First let me say that the whole team is also concerned about our performance on Metal, and we completely agree that it is unacceptable as is; our architecture very much assumes that shaders will be cached. We empathize deeply with anyone whose application on iOS is suffering from jank because of this issue.
We have marked this P3 because that is the appropriate priority level in Flutter's priority scheme for something that we are actively working on which is of high priority. You can read more about our prioritization scheme on the wiki (https://github.com/flutter/flutter/wiki/Issue-hygiene#priorities). In short, however, P0-P2 levels are reserved for critical issues that are even more dire than this bug, and P3 is what we use for this kind of issue.
This issue is non-trivial and work is actively happening to address it. It is our intent to have this addressed by our next stable release, but we make no promises, because that's not how engineering works.

You can literally see a partial update and/or plan addressing this issue.

Does anybody know when is the new stable release planned, is that information available? @Hixie, @dnfield ??

As I said above, I downgraded to flutter 1.12.13 and it's way better on ios. I think this is the best option if you need to release right now.

As I said above, I downgraded to flutter 1.12.13 and it's way better on ios. I think this is the best option if you need to release right now.

Do you have any problems with iOS 14?

@Renesanse Nothing critical for me: status bar brightness is always as in system scroll to top by status bar tap doesn't work. I had to fork some packages, recreate project ios folder. Someone mentioned font issue on iOS 14.

Since this seems to be a very critical issue, is there anything that we, the open source community, can do? Or maybe start looking at? I would love to help but don't know where to start or what to look at to familiarize myself with the cause of this issues

Is there any way to detect if a shader compilation just happened? I know I can watch the spike in frame loss but tht could also happen for other reasons, so it would be nice to just print in the console when a shader is being compiled.
I am experimentibg with a custom shader warmup loading screen that goes through some transitions in the beginning of the app to warm them up. Perhaps its possible to trigger these compilations but use a very short duration and keep them hidden behind a loading screen.
What exactly determines if an animation needs a new shader?
I tried some but cant be certain that its working, but if it does, it could be a viable temporary solution.
Any feedback is welcome!

For those asking about when the release schedule, please see: https://github.com/flutter/flutter/wiki/Flutter-build-release-channels
@tapizquent Contributions are certainly welcome. I would encourage you to see our contributor guide, join our chat channels, see if folks on the engine team have any advice for how you can participate in resolving this issue. Unfortunately, since this is a period where much of the team (including me) is on vacation, it may not be easy to get immediate replies.

As I understand there is no solution soon. I think it will take at least 4 months to release the first solutions.

As I understand there is no solution soon. I think it will take at least 4 months to release the first solutions.

That's not what was suggested in this thread I believe. I think all things point towards a solution in the next stable release, which should be due by end-Jan.

As I understand there is no solution soon. I think it will take at least 4 months to release the first solutions.

based on what reason you believe that?

We have an enterprise-level app that we are building in flutter, and the first launch performance is horrible on iOS. This is especially bad due to onboarding -- new users will get a very bad impression, even though we use correct coding practices on our end. New users aren't going to manually warm up the animations by pressing them several times until they smooth out, they will simply go to the app store and leave a 1 star review for poor performance (which is exactly what other flutter devs reported happening to their production apps).
Furthermore, the flutter landing page falsely advertises "native performance", when due to the shader compilation issues, it is worse than react native and even web-view tools. This issue has been active for over a year now, and the flutter team inadequately addresses it with low priority, when it should be imperative.
We have invested a lot of time and money into this project, and we hope that this issue will be fixed by the time we release (1-2 months from now). This is not a hobby project, while many of these indie/hobby devs don't mind and pretend this is a minor issue, this is extremely important to us and our stakeholders (we have a responsibility to them and to our users as well).
I see the moderation team here loves closing similar threads that are straightforward and don't shower flutter with praise. Pretending it's tolerable and whatnot. This should not be a P3 issue, this should be P1.
Our investors are not happy with the current situation at all, and I will proceed with legal action if I have to, because I have a fiduciary duty to them in regards to their invested capital. Flutter made a misleading, deceptive statement about its performance, and if this is not fixed, it will cost my company time, money, and reputation.
Fix this issue immediately.

Лох

As I understand there is no solution soon. I think it will take at least 4 months to release the first solutions.

and based on what reason you believe that?

Is there any progress in dev or beta before next stable release?

Hello everyone!
Is there a way to run animations on stack behind the splash screen or smth like that?
I would like to run my onboarding screen transition animations while the user sees some mock splash screen. Would it work?

@wfinf nope, but that is to be expected, I guess they'll fast-track the fix once it's ready.

Hello everyone!
Is there a way to run animations on stack behind the splash screen or smth like that?
I would like to run my onboarding screen transition animations while the user sees some mock splash screen. Would it work?

I tried this and it had no effect on the first run jank. I think it needs to be visible to work.

Hello everyone!
Is there a way to run animations on stack behind the splash screen or smth like that?
I would like to run my onboarding screen transition animations while the user sees some mock splash screen. Would it work?

I tried this and it had no effect on the first run jank. I think it needs to be visible to work.

Opacity 0.00001 😅

Hello everyone!
Is there a way to run animations on stack behind the splash screen or smth like that?
I would like to run my onboarding screen transition animations while the user sees some mock splash screen. Would it work?

How do we know if it's warm enough?

@wfinf it is definitely better than nothing.
I'm trying to find ANY solutions that would save my project from disaster.
Any hack/trick that would decrease the janks is useful.

Hello everyone!
Is there a way to run animations on stack behind the splash screen or smth like that?
I would like to run my onboarding screen transition animations while the user sees some mock splash screen. Would it work?

I used this trick in a couple of widgets (ExpansionTile, and other) just to check, and it works.
I just have to put the laggy widget on a Stack (behind the scenes) and trigger the animation.

Hello everyone!
Is there a way to run animations on stack behind the splash screen or smth like that?
I would like to run my onboarding screen transition animations while the user sees some mock splash screen. Would it work?

I used this trick in a couple of widgets (ExpansionTile, and other) just to check, and it works.
I just have to put the laggy widget on a Stack (behind the scenes) and trigger the animation.

@Pilaba thanks for sharing your experience!
Haven't you tried to do the same with page transitions? Idn if it possible

Hello everyone!
Is there a way to run animations on stack behind the splash screen or smth like that?
I would like to run my onboarding screen transition animations while the user sees some mock splash screen. Would it work?

I used this trick in a couple of widgets (ExpansionTile, and other) just to check, and it works.
I just have to put the laggy widget on a Stack (behind the scenes) and trigger the animation.

@Pilaba thanks for sharing your experience!
Haven't you tried to do the same with page transitions? Idn if it possible

if this trick works. can we like put a different instance of bunch of our app's lagy animations behind the scene like in splash screen and run them together for warmup? or does the warmup has to happen for all any different instance?

Folks, this is not a support forum, please keep comments specifically to the topic of helping with the shader compilation caching with Metal on iOS. Thanks.

Since when is it unacceptable to talk about patches and shims that alleviate the issue at hand?

May I recommend opening a separate issue to discuss posible pataches/workarounds so that this issue can stay focused on its topic?

It might be better to start a Google doc people can collaborate on. Github issues have a way of getting tough to navigate as more comments are added, and it becomes unclear who you're responding to.

TBH it's not even really clear what this issue is supposed to be tracking. Is it tracking "investigating" wiring up metal binary archives? Either way, maybe it's time to turn on GitHub discussions on this repo. I don't think a Google Doc is going to get anywhere good in a public context.

int deplay = flutterTeamDelayToFixIssue;
await Future.delayed(Duration(months:  deplay));
myCompany.release(ourapp);

//result: delayed for a month;

:( Have any update for this issue ?

int delayTime= flutterTeamDelayToFixIssue;
await Future.delayed(Duration(months:  delayTime));
myCompany.release(ourapp);

//result: delayed for a month;

:( Have any update for this issue ?
Man, just try old flutter or no metal engine, pushing people in solving problems do nothing well, just be tolerant.

I've created https://stackoverflow.com/q/65485696/3293914 - please feel free to add new answers there or comments/edits as appropriate. That is a better area for collaboration on community support for this issue, since here good comments will likely just get burried (this issue already has about 100 comments, most of which get hidden when first coming to this page).
In the interest of not spamming the many subscribers of this issue, and keeping things on topic, I'm locking this issue to collaborators. I started hiding some of the off-topic conversation, but there's just a lot of it and I'm going to mainly leave it as is :)
If you'd like to discuss this further, please feel free to hop on the Discord.

Do I understand this correct, that so far we aren't using compiled shaders?

Do I understand this correct, that so far we aren't using compiled shaders?

It's that the binary output of compilation is not getting cached and reused

It's that the binary output of compilation is not getting cached and reused

But it would be possible to link the binary versions of into the executable, right?
What does SwiftUI make different to not get into this problems? And why isn't it a problem on Android?

But it would be possible to link the binary versions of into the executable, right?
What does SwiftUI make different to not get into this problems? And why isn't it a problem on Android?

These are not the kind of binary you would link together with your program, since they can be highly device/gpu/driver specific.
On Android you only get this problem on the very first time a new shader is compiled, after which they get cached.
SwiftUI benefits from boiling down to UIKit, which doesn't need shaders in the same way that Metal/OpenGL based applications do.

These are not the kind of binary you would link together with your program, since they can be highly device/gpu/driver specific.
On Android you only get this problem on the very first time a new shader is compiled, after which they get cached.
SwiftUI benefits from boiling down to UIKit, which doesn't need shaders in the same way that Metal/OpenGL based applications do.

While investigating how to realize a WebGPU plugin for Flutter I met two of the developers of Google's WebGPU implementation  @senorblanco and  @kainino0x  and they told me that the topic of Shader problems with Metal is one that they are very familiar with.
Maybe  it could make sense to discuss this with them to see if they have some additional ideas.
They also told me that there is an experimental WebGPU backend for Skia. Could that possibly be another approach to Flutter Web rendering?
cc: @timsneath I hope its ok that I encourage this communucation here.

While investigating how to realize a WebGPU plugin for Flutter I met two of the developers of Google's WebGPU implementation  @senorblanco and  @kainino0x  and they told me that the topic of Shader problems with Metal is one that they are very familiar with.
Maybe  it could make sense to discuss this with them to see if they have some additional ideas.
They also told me that there is an experimental WebGPU backend for Skia. Could that possibly be another approach to Flutter Web rendering?
cc: @timsneath I hope its ok that I encourage this communucation here.

Promoting to P2 and marking 'customer:product' to help ensure adequate progress is tracked ahead of the next release.

Promoting to P2 and marking 'customer:product' to help ensure adequate progress is tracked ahead of the next release.

Update: A prototype with the caches in place should be out for review this week.

Update: A prototype with the caches in place should be out for review this week.

Awesome!

Awesome!

Findings From The Prototype
Some concerns were raised in the original Skia issue regarding the way in which the archives will be wired up. I haven't been able to successfully address all these concerns. Specifically, the concerns are mentioned in the header for MTLBinaryArchive instead of the documentation on Apple's developer portal (which is rather sparse). I am pasting the relevant lines from the header here so its easier to reference:
Updating a MTLBinaryArchive at runtime in a shipping app configuration is not
recommended; such a scenario requires corruption resiliency, careful storage
space management and may cache hard-to-reproduce errors. These kind of issues
are handled transparently by the Metal maintained cache, therefore we recommend
that MTLBinaryArchive is populated during development time and shipped as an
asset.

This recommendation does not work for Flutter. Flutter cannot recommend developers generate an archive at development time and ship as an asset. It requires platform (iOS/Mac) and device (per GPU family) specific training runs, increases binary size, and is of limited use unless the entire set of pipeline state objects used in the application at runtime are captured in the training run (not to mention the archive becomes stale as soon as the application code is updated). In that regard, the answer to my original call to "Investigate persisting these archives ... shipping them if possible in the application bundle" is a definite no. Apple's actual recommendation in the same header is as follows:
Once all desired pipeline state descriptors have been added, use
serializeToURL:error: to write the contents for the current device to disk.
MTLBinaryArchive files generated for multiple different devices can be combined
using the "lipo" tool into a single archive, which can then be shipped with the
application. It is possible to maintain different archive files for different
contexts; for example each level in a game may use a different cache object.

This cache will automatically accelerate pipeline state creation after a
pipeline is created for the first time. Use MTLBinaryArchive to augment that
cache by accelerating pipeline state creation even on the first run of an app.

Instead of that, the use-case addressed in the prototype is to maintain an archive of the last run of the application. This will not affect first run performance but will help with subsequent launches. Since this use-case is different from the Apple's recommendations, I have been trying to reason about the aforementioned "corruption resiliency, careful storage space management and possibility of caching hard-to-reproduce errors".

On corruption resiliency related to disk I/O: I believe we are fine on this front with careful error handling. We already have the GrPersistentCache in place and the issues related to disk I/O are already well understood and handled.
On corruption resiliency related to thread safety: Flutter does work with Metal on multiple threads. Neither the docs nor the header mentions threading at all. Assuming the worst, I only gave the onscreen GrContext an archive since we only access that on the raster thread. The IO thread does no rendering and should not have any render pipeline functions to cache. In the case of multiple engines, where there will be multiple raster threads, my approach was to give each engine its own separate archive. In the case of multiple engine having previous runs, give an array of these archives to each engine instance. This API does not exist in Skia today but we can request the team to add such an affordance. In the meantime, secondary engine launches will get just the one archive.
On storage space management: Disk usage should not grow indefinitely as archives for runs other than the last run will be collected.
On caching hard-to-reproduce errors: I suppose this is still a concern theoretically but it is not something I have explored in detail as pipeline state object management is internal to Skia. I can followup.

Clarifications on OpenGL
In my original call to investigate binary archives, I did not mention OpenGL at all. Metal binary archives are unrelated to any feature of the OpenGL backend on iOS. The same causes of jank I described in this issue exist in the OpenGL backend as well. For developers using training runs already to cache SKPs and seed them at runtime, it is likely that the increase in the number of unique pipeline state objects in the Metal backend gives more benefit to an OpenGL application than to one using Metal (the SKP cache is wired up for both OpenGL and Metal). But, just switching to OpenGL without SKP training runs is not expected to change much. However, I do realize that the discussions in this thread reference multiple real issues we need to make progress on and my attempt to deconflate the various potential issues is as follows:

Without training runs, the Metal backend is alleged to be constructing more pipelines state objects than OpenGL.
Without training runs, the Metal backend is alleged to be taking more time to construct a pipeline state object than OpenGL.
After training runs, the Metal backend is alleged to demonstrate less benefits over the OpenGL backend.
Pipeline state objects are constructed in a frame workload.

Besides the last point, which I believe is the long term solution to jank due to shader compilation, we can work in parallel to answer the other narrowly scoped questions and deploy improvements as necessary. However, unlike as suggested by some in this thread, I highly recommend against switching to the OpenGL backend via custom engine builds. There are stability, performance and correctness issues in that backend that the team can no longer fix.
Next Steps

Specific issues are filed for the investigating work items I described in the last section and we go chase each one down.
Given the more qualified scope of the prototype, I get guidance from release management on how to prioritize this issue and the timelines. If we do decide to productionize the archive usage as described, the limitations must be made clear upfront.
As a team, we need to figure out how to better communicate with the community on these sorts of performance issues. I know I was really overwhelmed with the numerous threads that (to me) were tangential to the original issue describing the need to investigate wiring up the binary archives. And I am pretty sure most folks here in centithread were dissatisfied with the answers they got (or didn't).
We fast track the design work to move creation of pipeline state objects outside the frame workload. That is the only way to fix jank of this sort without resorting to training runs and such.

Findings From The Prototype
Some concerns were raised in the original Skia issue regarding the way in which the archives will be wired up. I haven't been able to successfully address all these concerns. Specifically, the concerns are mentioned in the header for MTLBinaryArchive instead of the documentation on Apple's developer portal (which is rather sparse). I am pasting the relevant lines from the header here so its easier to reference:
Updating a MTLBinaryArchive at runtime in a shipping app configuration is not
recommended; such a scenario requires corruption resiliency, careful storage
space management and may cache hard-to-reproduce errors. These kind of issues
are handled transparently by the Metal maintained cache, therefore we recommend
that MTLBinaryArchive is populated during development time and shipped as an
asset.

This recommendation does not work for Flutter. Flutter cannot recommend developers generate an archive at development time and ship as an asset. It requires platform (iOS/Mac) and device (per GPU family) specific training runs, increases binary size, and is of limited use unless the entire set of pipeline state objects used in the application at runtime are captured in the training run (not to mention the archive becomes stale as soon as the application code is updated). In that regard, the answer to my original call to "Investigate persisting these archives ... shipping them if possible in the application bundle" is a definite no. Apple's actual recommendation in the same header is as follows:
Once all desired pipeline state descriptors have been added, use
serializeToURL:error: to write the contents for the current device to disk.
MTLBinaryArchive files generated for multiple different devices can be combined
using the "lipo" tool into a single archive, which can then be shipped with the
application. It is possible to maintain different archive files for different
contexts; for example each level in a game may use a different cache object.

This cache will automatically accelerate pipeline state creation after a
pipeline is created for the first time. Use MTLBinaryArchive to augment that
cache by accelerating pipeline state creation even on the first run of an app.

Instead of that, the use-case addressed in the prototype is to maintain an archive of the last run of the application. This will not affect first run performance but will help with subsequent launches. Since this use-case is different from the Apple's recommendations, I have been trying to reason about the aforementioned "corruption resiliency, careful storage space management and possibility of caching hard-to-reproduce errors".

On corruption resiliency related to disk I/O: I believe we are fine on this front with careful error handling. We already have the GrPersistentCache in place and the issues related to disk I/O are already well understood and handled.
On corruption resiliency related to thread safety: Flutter does work with Metal on multiple threads. Neither the docs nor the header mentions threading at all. Assuming the worst, I only gave the onscreen GrContext an archive since we only access that on the raster thread. The IO thread does no rendering and should not have any render pipeline functions to cache. In the case of multiple engines, where there will be multiple raster threads, my approach was to give each engine its own separate archive. In the case of multiple engine having previous runs, give an array of these archives to each engine instance. This API does not exist in Skia today but we can request the team to add such an affordance. In the meantime, secondary engine launches will get just the one archive.
On storage space management: Disk usage should not grow indefinitely as archives for runs other than the last run will be collected.
On caching hard-to-reproduce errors: I suppose this is still a concern theoretically but it is not something I have explored in detail as pipeline state object management is internal to Skia. I can followup.

Clarifications on OpenGL
In my original call to investigate binary archives, I did not mention OpenGL at all. Metal binary archives are unrelated to any feature of the OpenGL backend on iOS. The same causes of jank I described in this issue exist in the OpenGL backend as well. For developers using training runs already to cache SKPs and seed them at runtime, it is likely that the increase in the number of unique pipeline state objects in the Metal backend gives more benefit to an OpenGL application than to one using Metal (the SKP cache is wired up for both OpenGL and Metal). But, just switching to OpenGL without SKP training runs is not expected to change much. However, I do realize that the discussions in this thread reference multiple real issues we need to make progress on and my attempt to deconflate the various potential issues is as follows:

Without training runs, the Metal backend is alleged to be constructing more pipelines state objects than OpenGL.
Without training runs, the Metal backend is alleged to be taking more time to construct a pipeline state object than OpenGL.
After training runs, the Metal backend is alleged to demonstrate less benefits over the OpenGL backend.
Pipeline state objects are constructed in a frame workload.

Besides the last point, which I believe is the long term solution to jank due to shader compilation, we can work in parallel to answer the other narrowly scoped questions and deploy improvements as necessary. However, unlike as suggested by some in this thread, I highly recommend against switching to the OpenGL backend via custom engine builds. There are stability, performance and correctness issues in that backend that the team can no longer fix.
Next Steps

Specific issues are filed for the investigating work items I described in the last section and we go chase each one down.
Given the more qualified scope of the prototype, I get guidance from release management on how to prioritize this issue and the timelines. If we do decide to productionize the archive usage as described, the limitations must be made clear upfront.
As a team, we need to figure out how to better communicate with the community on these sorts of performance issues. I know I was really overwhelmed with the numerous threads that (to me) were tangential to the original issue describing the need to investigate wiring up the binary archives. And I am pretty sure most folks here in centithread were dissatisfied with the answers they got (or didn't).
We fast track the design work to move creation of pipeline state objects outside the frame workload. That is the only way to fix jank of this sort without resorting to training runs and such.

Following @chinmaygarde’s detailed analysis above, I’d like to close the loop on this issue. The issue as stated was to “Investigate wiring up Metal Binary Archives on iOS”, and that work has been completed. Unfortunately, the results of that investigation were not what we had hoped for.
As described above, we encountered two main problems. First, integrating this feature of Metal into the Flutter Engine entails off-label uses of Apple’s APIs, with no guarantees that the off-label uses will continue to work going forward. Second, the performance improvements were extremely modest as Metal shader library construction and not pipeline state object creation was found to be the bottleneck. Taken together, these two problems would mean accepting a large risk in exchange for a limited benefit. For that reason, we have decided not to do this.
However, though it covered several different topics, the discussion in this thread has shed light on a few different areas for improvement being tracked here. We will continue to be hard at work on solving first-run shader compilation jank on both iOS and Android, as we currently view it as one of the most serious performance issues facing Flutter. We are focusing our efforts on a long-term, maintainable solution to this problem outlined by the linked issues.
Jank has many causes outside of shader compilation and pipeline setup, so in the meantime, please see the good general advice from @stx above about optimizing animations here, stackoverflow for queries about other strategies for working around this issue, starting with @dnfield’s thread here, as well as other documents, videos, and tools for performance optimization generally. Thanks!

Following @chinmaygarde’s detailed analysis above, I’d like to close the loop on this issue. The issue as stated was to “Investigate wiring up Metal Binary Archives on iOS”, and that work has been completed. Unfortunately, the results of that investigation were not what we had hoped for.
As described above, we encountered two main problems. First, integrating this feature of Metal into the Flutter Engine entails off-label uses of Apple’s APIs, with no guarantees that the off-label uses will continue to work going forward. Second, the performance improvements were extremely modest as Metal shader library construction and not pipeline state object creation was found to be the bottleneck. Taken together, these two problems would mean accepting a large risk in exchange for a limited benefit. For that reason, we have decided not to do this.
However, though it covered several different topics, the discussion in this thread has shed light on a few different areas for improvement being tracked here. We will continue to be hard at work on solving first-run shader compilation jank on both iOS and Android, as we currently view it as one of the most serious performance issues facing Flutter. We are focusing our efforts on a long-term, maintainable solution to this problem outlined by the linked issues.
Jank has many causes outside of shader compilation and pipeline setup, so in the meantime, please see the good general advice from @stx above about optimizing animations here, stackoverflow for queries about other strategies for working around this issue, starting with @dnfield’s thread here, as well as other documents, videos, and tools for performance optimization generally. Thanks!

@zanderso I read die analysis in the PR and added this question https://github.com/flutter/engine/pull/23914#issuecomment-767452135

@zanderso I read die analysis in the PR and added this question https://github.com/flutter/engine/pull/23914#issuecomment-767452135


Add check for invalid year

What's the deal?
Ran into an issue where UCPD entered the date as 2025 instead of 2024, so the scraper was never updating. There should be some sort of check to make sure that the last two digits of the year match the current year.

cc: @Nik4002


Automate documentation

Bindgen no longer generates documentation for elements. However, Rust doc comments are more friendly than reading the C capstone headers.
We should add a script (or Rust code) that can add documentation to the pre-generated bindings.

This is based on discussion from pull-request #3.

Can you just cherry pick the doc commit for now for the release ? And then add more robust solution later.
I say this cause I think need to release in a day or two because I'm leaving for a bit and won't be able to release for a bit, so somewhat in a rush :)

Handled with scripts/add_doc_comments.py


npm install wascally does not work

Hi,
Installing 0.2.7 or 0.2.6 do not work, whereas installing 0.2.5 will work.
The errors I get when installing are:
Command failed: git clone --template=/Users/admin/.npm/_git_remotes/_templates --mirror git://github.com/ifandelse/riveter.git /Users/admin/.npm/_git-remotes/git-github-com-ifandelse-riveter-git-c54a5909
Thanks

@ryandac are you still having this issue with 0.2.9?


Missing setSplicer() on ArrayColumn

Coming from https://github.com/Caleydo/lineup_app/issues/44
After merging the most recent develop branch the split matrix feature does not work anymore.
It seems that the setSplicer() function was removed during a refactoring in
https://github.com/lineupjs/lineupjs/commit/2881a6a01460ee0f18186d26178cfc9f17dc65e7#diff-3f7d377ba0c45462eaf80c0e646c52b4L53.
@sgratzl Did you move the setSplicer() somewhere else? Or is there another way to repair the splice matrix feature?

yes it was removed since there was no way to trigger this function via the user interface. As an alternative one could create different Column Descriptions each having a different accessor method implementing the slicing of the underlying array


Using React implementation along with MetaMask

Describe the bug
So I'm already using MetaMask inside my Dapp and I want to integrate WalletConnect but the React implementation because of it's easiness to implement but I have the following issue:
When I have the MetaMask extension and any other wallet extension (like CoinBase, TokenPocket, etc.), in the WalletConnect modal when I click on MetaMask the extension is not recognized as installed.
As a solution to the above I added the MetaMask connector manually in the wagmi client config, but then:

When I have only MetaMask installed, MetaMask appears twice in the WalletConnect modal.
If I have MetaMask and another wallet extension, all appears good (the wallet extension and MetaMask appear as Installed in the WalletConnect modal) but when I click on MetaMask it still opens the other wallet extension.

Are there any solutions for this on my side? Or will there be a version soon that will take care of situations like this?
SDK Version
"@web3modal/ethereum": "^2.1.1",
"@web3modal/react": "^2.1.1",
"wagmi": "^0.11.4",
Expected behavior
I'd expect to see all the wallet extensions I've added to my browser in WalletConnect separately by default.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):

OS: macOS
Browser Chrome
Version Latest

Same problem happening to me, exactly the same environment scenario, the only work around I found is using the coinbase wallet and on the first pop up you can actually choose metamask and then use metamask through the coinbase wallet

In essence you want custom connectors, so will need to remove modalConnectors and replace it with array of connectors that you need. Make sure to include WalletConnectConnector, this is the only one that is required.

That still doesn't work correctly.

I have the MetaMask and Coinbase wallet extensions installed and I've replaced modalConnectors with
    connectors: [      new WalletConnectConnector({          chains,          options: { qrcode: false, version: '2', projectId: Config.WALLET_CONNECT_KEY },      }),      new InjectedConnector({          chains,          options: { shimDisconnect: true, shimChainChangedDisconnect: true },      }),      new MetaMaskConnector({ chains }),  ],
and now when I open the WalletConnect modal and I click on MetaMask the active connector returned by useAccount from wagmi shows that the active connector is id: "injected", name: "Coinbase Wallet". It should be MetaMask.

Removing the InjectedConnector from the connectors array resolves in the error from the image when I click MetaMask in the WalletConnect modal.

Hmm, looks like internally it tries to treat metamask connector as injected, causing the error. Will reopen this issue to dive deeper and see if it is resolvable 👍


Unable to build React Native 0.65-rc4 from source

Please provide all the information requested. Issues that do not follow this format are likely to stall.
Description
I got an error when tried to build React-native 0.65-rc4 from sources
React Native version:
System:
OS: macOS 11.4
CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
Memory: 3.30 GB / 32.00 GB
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 16.1.0 - /usr/local/bin/node
Yarn: 1.22.10 - /usr/local/bin/yarn
npm: 7.11.2 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
Managers:
CocoaPods: 1.10.1 - /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms: iOS 14.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4
Android SDK:
API Levels: 29, 30
Build Tools: 28.0.3, 29.0.2, 30.0.1, 30.0.2, 30.0.3
System Images: android-23 | Google APIs Intel x86 Atom_64, android-25 | Google Play Intel x86 Atom, android-26 | Google Play Intel x86 Atom, android-27 | Google Play Intel x86 Atom, android-28 | Google Play Intel x86 Atom, android-29 | Google Play Intel x86 Atom, android-30 | Google APIs Intel x86 Atom, android-S | Google APIs ARM 64 v8a, android-S | Google APIs Intel x86 Atom_64
Android NDK: 21.4.7075529
IDEs:
Android Studio: 2020.3 AI-203.7717.56.2031.7583922
Xcode: 12.5.1/12E507 - /usr/bin/xcodebuild
Languages:
Java: 1.8.0_292 - /usr/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 17.0.2 => 17.0.2
react-native: 0.65.0-rc.3 => 0.65.0-rc.3
react-native-macos: Not Found
npmGlobalPackages:
react-native: Not Found
Steps To Reproduce
Provide a detailed list of steps that reproduce the issue.

Created empty RN project using command
npx react-native init AwesomeProject

Upgraded project to 065-rc4 using upgrade helper

https://react-native-community.github.io/upgrade-helper/?from=0.64.2&to=0.65.0-rc.4

Prepared project for building from source as described here
https://github.com/facebook/react-native/wiki/Building-from-source

Got react native sources

git clone -b 0.65-stable https://github.com/facebook/react-native.git

From react native sources folder copy packages/react-native-codegen to node_modules/react-native/packages

Tried to build and start app

$npx react-native run-android
Expected Results
app should build and run on phone
Got error
info Running jetifier to migrate libraries to AndroidX. You can disable it using "--no-jetifier" flag.
Jetifier found 936 file(s) to forward-jetify. Using 16 workers...
info JS server already running.
info Installing the app...
FAILURE: Build failed with an exception.

What went wrong:
A problem occurred configuring project ':ReactAndroid'.

Could not resolve all artifacts for configuration ':ReactAndroid:classpath'.
Could not find com.android.tools.build:gradle:4.2.1.
Searched in the following locations:
- https://plugins.gradle.org/m2/com/android/tools/build/gradle/4.2.1/gradle-4.2.1.pom
If the artifact you are trying to retrieve can be found in the repository but without metadata in 'Maven POM' format, you need to adjust the 'metadataSources { ... }' of the repository declaration.
Required by:
project :ReactAndroid > project :gradlePlugin-build:gradlePlugin

Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

Get more help at https://help.gradle.org

BUILD FAILED in 5s
error Failed to install the app. Make sure you have the Android development environment set up: https://reactnative.dev/docs/environment-setup.
Error: Command failed: ./gradlew app:installDebug -PreactNativeDevServerPort=8081
FAILURE: Build failed with an exception.

What went wrong:
A problem occurred configuring project ':ReactAndroid'.

Could not resolve all artifacts for configuration ':ReactAndroid:classpath'.
Could not find com.android.tools.build:gradle:4.2.1.
Searched in the following locations:
- https://plugins.gradle.org/m2/com/android/tools/build/gradle/4.2.1/gradle-4.2.1.pom
If the artifact you are trying to retrieve can be found in the repository but without metadata in 'Maven POM' format, you need to adjust the 'metadataSources { ... }' of the repository declaration.
Required by:
project :ReactAndroid > project :gradlePlugin-build:gradlePlugin

Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

Get more help at https://help.gradle.org

BUILD FAILED in 5s
at makeError (/Users/sergey/kamino/AwesomeProject/node_modules/execa/index.js:174:9)
at /Users/sergey/kamino/AwesomeProject/node_modules/execa/index.js:278:16
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async runOnAllDevices (/Users/sergey/kamino/AwesomeProject/node_modules/@react-native-community/cli-platform-android/build/commands/runAndroid/runOnAllDevices.js:106:5)
at async Command.handleAction (/Users/sergey/kamino/AwesomeProject/node_modules/@react-native-community/cli/build/index.js:186:9)

info Run CLI with --verbose flag for more details
Tried to cleanup Gradle cache (.gradle) in both android and user home folder without success
Tried to open https://plugins.gradle.org/m2/com/android/tools/build/gradle/4.2.1/gradle-4.2.1.pom and it leads to broken Jcenter repo
Project doesn't have any Jcenter repo added at all
It seems ReactAndroid have hardcoded Jcenter reference somewhere but search in Github repo for ReactAndroid doesn't return any Jcenter references
Now I stuck on this error and have no ideas how to fix it.

Fixed this issue by adding
pluginManagement {
repositories {
gradlePluginPortal()
mavenLocal()
google()
}
}
to settings.gradle at top of file


Add test for appending with cftime

This is probably a bad choice of unit
"units": "seconds since 1970-01-01T00:00:00"

because that's also the standard UNIX definition, so having no units would have the same effect.
A nice concise error:
numpy.core._exceptions._UFuncNoLoopError: ufunc 'less' did not contain a loop with signature matching types (<class 'numpy.dtypes.Int64DType'>, <class 'numpy.dtypes.DateTime64DType'>) -> None

I'll look into the error, though, I would have expected this to work.

OK, so of course xarray converts times automatically unless told otherwise.

Thanks for the fix @martindurant! Did you not like the drop_vars option in the xarray backend?
Also, a bit unrelated but do you mind sharing with me what ... passed to __getitem__ does for zarr (referencing the following)?
o = z[selector.split(":", 1)[1]][...]

Did you not like the drop_vars option in the xarray backend?

It was not being applied after the dataset was already loaded. This does the right thing for a normal load, but if some array fails to load (as I found with some time conversion), the options needs to be in the first open_dataset call. So you can use the argument as before, but it should work better now :)

what ... passed to getitem does

It would be the same as [:] (i.e., grab the actual values as an array) but it also works for zero-dimension arrays.

The kerchunk tests take a long time to run in the CI, and it looks like most of the time is spent on the setup-micromamba step. Would you be open to enabling caching in setup-micromamba to speed up the workflows?

Certainly would be happy to have caching. Actually, conda now uses the mamba solver, so it might be faster again - I don't mind, so long as it works!

@maxrjones , env building on py39 seems stuck, any idea why?

@maxrjones , env building on py39 seems stuck, any idea why?

I pushed a couple fixes for the env errors


Rename docker-compose.yml to compose.yml

What are these changes?
Rename docker-compose.yml to compose.yml.
Why are these changes being made?

The default path for a Compose file is compose.yaml (preferred) or compose.yml that is placed in the working directory. Compose also supports docker-compose.yaml and docker-compose.yml for backwards compatibility of earlier versions. If both files exist, Compose prefers the canonical compose.yaml.
https://docs.docker.com/compose/intro/compose-application-model/#the-compose-file

coverage: 91.033%. remained the same
when pulling 9e1c52e504e4386093900a342e0c1fe79840d3fd on rename-docker-compose
into 83053e37f694f59c2ccccbf0418c6a6190f128cd on mainline.


Added WF Update: Record audio and video with MediaRecorder

@jpmedley PTAL
@miguelao, @niklasenbom,  FYI
@PaulKinlan I've left in the link to the screen recording Chrome App, but can remove if necessary.

@samdutton merging, but please remove anything that is not open web. i.e, Chrome App.  We shouldn't be pointing to things that will never work in Firefox.

Fair point — removed and did another PR.


Can

Operating system or device, Godot version, GPU Model and driver (if graphics related):
Issue description:

Steps to reproduce:
Link to minimal example project:

Sorry for this. :D It seems I accidentally hit enter on my new keyboard and didn't notice it posted. :D
Here is the issue I wanted to post: https://github.com/godotengine/godot/issues/12357


feat: support two-way binding

Fixes #4
BREAKING CHANGE: support two-way binding by following the pattern @Input() x, @Output() xChange from https://angular.io/guide/two-way-binding

:tada: This PR is included in version 2.0.0 :tada:
The release is available on:

GitHub release
npm package (@latest dist-tag)

Your semantic-release bot :package::rocket:


Bug in PhoneNumberProvider->getFromAddress

Expected behavior
Have a correct formated phone number (+[ISO_EXT][PHONE_NUMBER])
Actual behavior
The phone numbe isn't correctly formated. For instance, we have the following phone number:<PHONE_NUMBER> (valid french mobile phone number). When we look at the code of PhoneNumberProvider, we can see that the phone number will become +697112404, which is not a correct phone number. The expected one should be either +33697112404 or<PHONE_NUMBER>.
Steps to reproduce the behavior
Execute the method getFromAddress with a address that contains the phone number.
Remarks
Why should the module check the phone number as this information isn't used in the client dashboard of mollie?
And even if it's mandatory, it shouldn't be the responsability of the module to check the phone number.
Edit
More information:
The issue doesn't occur when it's a new client.
The error message I get is the following: "Cart Dump: [2021-01-03T16:08:34+0100] Error executing API call (422: Unprocessable Entity): The 'phone' field should contain a valid phone number, in E.164 format. Field: billingAddress.phone."
Environment

PrestaShop version: <IP_ADDRESS>
Mollie module version: 4.1.3
PHP version: 7.2.x

Hello, and thank you for your message.
I will check this out with the team, and with Mollie, and will get back to you once I will be updated regarding this case.
Thank you for your patience!
--
Best regards,
Invertus Support team

Hello, and thank you for your message.
I will check this out with the team, and with Mollie, and will get back to you once I will be updated regarding this case.
Thank you for your patience!
--
Best regards,
Invertus Support team

@Saimis777  thank you for checking.
If you need more detailed information, do not hesitate.
I can provide you the complete error message if needed.
Regards

@Saimis777  thank you for checking.
If you need more detailed information, do not hesitate.
I can provide you the complete error message if needed.
Regards

Hello @Saimis777, did you have any feedback from the team or Mollie?
Regards

Hello @Saimis777, did you have any feedback from the team or Mollie?
Regards

Hello @mitchello thanks for checking in, we're currently discussing this topic, estimating the work that needs to be done, as there are other fixes and improvements we want to implement, we're trying to bundle everything up in one release, I will definitely keep you updated regarding this case!
--
Best regards,
Invertus Support team

Hello @mitchello thanks for checking in, we're currently discussing this topic, estimating the work that needs to be done, as there are other fixes and improvements we want to implement, we're trying to bundle everything up in one release, I will definitely keep you updated regarding this case!
--
Best regards,
Invertus Support team

@Saimis777 thank you for your answer.
Regards

@Saimis777 thank you for your answer.
Regards

@mitchello The fix will be included in the 4.2.0 release, it's coming out very soon this month, it will be uploaded firstly here - https://github.com/mollie/Prestashop/releases so be sure to follow that repository, I will close this issue for now, and if you will encounter any other issues, please let us know, we are here to help!
--
Best regards,
Invertus Support team

@mitchello The fix will be included in the 4.2.0 release, it's coming out very soon this month, it will be uploaded firstly here - https://github.com/mollie/Prestashop/releases so be sure to follow that repository, I will close this issue for now, and if you will encounter any other issues, please let us know, we are here to help!
--
Best regards,
Invertus Support team

@Saimis777 thanks for the update, waiting for the release then.
Regards

@Saimis777 thanks for the update, waiting for the release then.
Regards

Hello @mitchello , hope you're having a nice day!
The official Mollie 4.2.0 was just released, a new number validation was implemented, you can download the latest version here - https://github.com/mollie/PrestaShop/releases/tag/4.2.0
Any feedback regarding the updated version is greatly appreciated!
--
Best regards,
Invertus Support team

Hello @mitchello , hope you're having a nice day!
The official Mollie 4.2.0 was just released, a new number validation was implemented, you can download the latest version here - https://github.com/mollie/PrestaShop/releases/tag/4.2.0
Any feedback regarding the updated version is greatly appreciated!
--
Best regards,
Invertus Support team


Terrascan results not publishing to Guardian

When running Terrascan against code, the policy finds violations which you can see in the log. When importing results into Guardian the log says "0 result file(s) created'.  Just above that line you can see the actual policy violations that Terrscan found in the code.

Please share your log excerpts here and I can try to help interpret them. It is difficult to guess what the problem may be without the detailed logs to help explain.

Closing this issue for lack of logs to investigate. Please re-open as needed.


test: Adding -cpu host for qemu for MacOS

Adding the -cpu host option to the qemuArgs function for
darwin removes the warning message, "host doesn't support requested
feature: CPUID.80000001H:ECX.svm [bit 2]"

/close
merge with #132


Check remote rather than just origin

Problem
Currently the remote checked against is origin/{branch_name}, lot's of people have more than one remote.
Solution
Check all tracked remotes for a branch in the current repo and show the status for each of them.

If this were to be added, it would be nice to override with a single remote. I have some repositories with a lot of remotes (Heroku applications) where I really only care about one being up-to-date.