This "visual overview" in the beginning of the video was a very clever Idea. It helps us to have a transparent idea of the things we're about to learn. I'm really proud of you for making so many wonderful and so helpful video tutorials! Thank you so much! Keep it up! ;)
Fabulous... Was thinking of improving performance. I was conditioned to think *having separate widgets for expensive stuff is the way to good performance*. Thank you. That 10 sec summary is cool. Thanks for that...
Great! That conditioned thinking is not wrong, sepending on how widgets are grouped together (and rebuilt) then definitely, it can have a performance impact. Painting is just one part, and generally we shouldn't be too concerned about the cost. Only use a repaint boundary if you see performance issues in certain areas that do heavy painting. There are a lot of other performance considerations as well and I'll be making more videos on it!
@@FunwithFlutter Ohh... Cool. That's why it's called *repaint* Boundary. It's only a boundary for painting tasks. Which implies, I will split expensive widgets in some occasions. Thanks mate. Happy coding ☺️
Dude, you saved me! I was having a lot of performance issues due to custom paintings, now i can fix then! Thank you so much! =) Is it your course updated to Null Safety?
The code is! I'm busy updating/migrating the code snippets and other examples throughout the course. The vids are not yet updated to null safety :( Glad that this vid helped though!
What do you do when Flutter decides to cash a dynamic widget all on its own? BTW, thanks for having an explanation in a way that makes good sense. From Ethiopia.
Hmm, can you tell me what you tried? Slivers are used in CustomScrollView, and just like ListView it should manage the RepaintBoundary for you, so no need to add an extra RepaintBoundary. In the video I have an example showing a ListView. Because the ListView will always repaint independently from whatever is outside of the list, that's why they have a RepaintBoundary by default - same with CustomScrollView (Slivers). If you enable the debugRepaintRainbowEnabled flag and scroll in a CustomScrollView (or ListView) you will see the different colored areas that are grouped (painted) together, showing where the layers are being cached for quicker scrolling. You'll also see the colors changing when you scroll back, meaning they are not being cached and the list is deciding to repaint them. If you want to increase the caching then you can play around with the cacheExtent attribute in a CustomScrollView. If the cacheExtent is high enough then Flutter will cache the previous slivers that were scrolled into view for further up the list, so now if you scroll back the colors may not have changed if those layers are still cached. That all said, I only minimally understand how lists and grids are optimally rendered. "Infinite scrolling lists are notoriously difficult for toolkits" - quoting the docs. And there's a ton that goes into it to make it performant. I'd say trust the Google engineers on this and just use the lists like normal, while playing around with the attributes the lists expose (such as cacheExtent) to tweak it the way you like.
Thanks for a very well explained video. I have a CustomScrollView with a blurry app bar like the iOS style but the performance is terrible. Can I apply RepaintBoundary to solve it? Any advice would be appreciated!
W/FlutterActivity( 7241): Tried to automatically register plugins with FlutterEngine (io.flutter.embedding.engine.FlutterEngine@4d9c159) but could not find and invoke the GeneratedPluginRegistrant. . . How can I solve this issue??
Men, I got a question, what means when the vertical red or green bar in the performance overlay never stop? is there a issue? how can I find out the problem?... Thank you for the answer 😎
Sounds like you have some logic that is still being triggered that’s causing the background work. Best way would be to use Flutter DevTools and profile the application. That will show you what methods are being called and allow you to find the source.
Definitely not. Something I explain in way more detail in the course. There have also been similar questions to this where I provide a detailed answer. Painting all of the widgets to screen happens extremely fast and under most circumstance we should not worry about performance. Only seek to improve performance when it's an issue or when you believe it can be improved. Wrapping everything in a RepaintBoundary will result in higher memory use as more parts are being cached, and painting is generally cheap. Only do it for widgets with expensive paint operations or when widgets repainting should have no effect on other part of your tree (for example, a ListView - which has a repaint boundary by default). Here is a long answer I gave to similar questions: The long answer: In Flutter you have Widgets, Elements and RenderObjects. Widgets are inexpensive and get rebuilt all the time, Elements keep track of widgets and their positions in the Tree (and their associated RenderObjects). The RenderObjects are responsible for layout, painting, etc. Flutter is very efficient in only rebuilding the part of the Tree that need updating (basically when the immutable widgets change). It also won't perform unnecessary work when it's not needed. This is mostly managed for you and you do not need to care, but as Flutter developers we can do things to guide the framework to manage the life cycle efficiently (keys, constants, small build methods, etc). Painting works differently though. When one widgets changes (even if it's in a separate build method) then Flutter/Skia will repaint everything that is within the same display list (RepaintBoundary). There are many different phases/computations that happen from widget -> to finally displaying the widget on screen. Repainting everything on screen is not necessarily a problem and under most circumstances this will happen fast. BUT, we have the OPTION to tell Flutter that this part of the widget tree should be treated independently from another part (in terms of Painting). If you're just laying out text then there is no real need as it's inexpensive to paint, but if you're doing crazier things or if you have a widget with an expensive paint operation then it makes sense to wrap it in a RepaintBoundary. Depending on the platform you're targeting you may have a different approach as well. On desktop you have more memory which frees you up to be able to cache more images (display lists) instead of repainting them, so maybe using more Repaint Boundaries. But there is not need to overuse them. ListView is a great example of using a RepaintBoundary, as whatever painting happens in a ListView is independent of other painting on the screen.
so when you said if you click on the button whole widget tree gets repainted. So it means if i tap a button the screen the whole screen will be repainted . Right?
Technically yes, but this isn't a problem. Skia/Flutter does this extremely fast and this is definitely not something you have to worry about. As Flutter developers it's more important for us to manage the Widget lifecycle and avoid unnecessary rebuilds (keys, constants, small build methods) - as this allows the Flutter Framework to be efficient in taking our widgets and updating what should render on the screen. But Painting is different to the Widgets rebuilding, everything inside a RepaintBoundary will be repainted when something in that RepaintBoundary needs to be repainted. Not a problem most of the time, as Painting normal widgets are not expensive. Here is a long answer that I gave to a similar question if you want more info: The long answer: In Flutter you have Widgets, Elements and RenderObjects. Widgets are inexpensive and get rebuilt all the time, Elements keep track of widgets and their positions in the Tree (and their associated RenderObjects). The RenderObjects are responsible for layout, painting, etc. Flutter is very efficient in only rebuilding the part of the Tree that need updating (basically when the immutable widgets change). It also won't perform unnecessary work when it's not needed. This is mostly managed for you and you do not need to care, but as Flutter developers we can do things to guide the framework to manage the life cycle efficiently (keys, constants, small build methods, etc). Painting works differently though. When one widgets changes (even if it's in a separate build method) then Flutter/Skia will repaint everything that is within the same display list (RepaintBoundary). There are many different phases/computations that happen from widget -> to finally displaying the widget on screen. Repainting everything on screen is not necessarily a problem and under most circumstances this will happen fast. BUT, we have the OPTION to tell Flutter that this part of the widget tree should be treated independently from another part (in terms of Painting). If you're just laying out text then there is no real need as it's inexpensive to paint, but if you're doing crazier things or if you have a widget with an expensive paint operation then it makes sense to wrap it in a RepaintBoundary. Depending on the platform you're targeting you may have a different approach as well. On desktop you have more memory which frees you up to be able to cache more images (display lists) instead of repainting them, so maybe using more Repaint Boundaries. But there is not need to overuse them. ListView is a great example of using a RepaintBoundary, as whatever painting happens in a ListView is independent of other painting on the screen.
What if we already use a Consumer widget on a child widget where only the child will be updated when something is updated? Is the performance the same as having a RepaintBoundary?
Good question. Guess that is something I do not explain well in this video, but in the course there are dedicated videos addressing this, and this video builds on that. To quickly answer your question: What you're describing is efficient from a Widget rebuild and layout perspective. Using Consumers/Selectors will result in only parts of the widget tree rebuilding, and allows the Flutter framework to be efficient in what it determines to need updating (creating RenderObjects from Widgets). The long answer: In Flutter you have Widgets, Elements and RenderObjects. Widgets are inexpensive and get rebuilt all the time, Elements keep track of widgets and their positions in the Tree (and their associated RenderObjects). The RenderObjects are responsible for layout, painting, etc. Flutter is very efficient in only rebuilding the part of the Tree that need updating (basically when the immutable widgets change). It also won't perform unnecessary work when it's not needed. This is mostly managed for you and you do not need to care, but as Flutter developers we can do things to guide the framework to manage the life cycle efficiently (keys, constants, small build methods, etc). Painting works differently though. When one widgets changes (even if it's in a separate build method) then Flutter/Skia will repaint everything that is within the same display list (RepaintBoundary). There are many different phases/computations that happen from widget -> to finally displaying the widget on screen. Repainting everything on screen is not necessarily a problem and under most circumstances this will happen fast. BUT, we have the OPTION to tell Flutter that this part of the widget tree should be treated independently from another part (in terms of Painting). If you're just laying out text then there is no real need as it's inexpensive to paint, but if you're doing crazier things or if you have a widget with an expensive paint operation then it makes sense to wrap it in a RepaintBoundary. Depending on the platform you're targeting you may have a different approach as well. On desktop you have more memory which frees you up to be able to cache more images (display lists) instead of repainting them, so maybe using more Repaint Boundaries. But there is not need to overuse them. ListView is a great example of using a RepaintBoundary, as whatever painting happens in a ListView is independent of other painting on the screen.
Fun with Flutter sounds like I should take the course to really dive deeper into flutter! I’m comfortable with all state managements and flutter concepts but this in-depth understanding of code optimisation is something I should learn :) Is there a link to the course?
Totally worth it to do a deep dive into the inner workings. The link: bit.ly/funwithcourse with discount applied. Go directly to Section 7 if you only care about the performance part!
Not too sure what you mean. const will make sure that the widget doesn't rebuild unnecessarily, however painting is different. Even if a widget is not rebuilt it will still be repainted within the same repaint boundary when another widget causes a repaint. Similar questions from other people provide a more detailed answer
Flutter will cache an image the first time it is rendered in app. Not sure how this is persisted (session or app). I think app. But not sure. More info here: flutter.dev/docs/perf/rendering/ui-performance#checking-for-non-cached-images. You can also take a look at flutter.dev/docs/perf/rendering/shader which will allow you to "warm up" the shader. Which will allow you to get smooth performance from the first time the app is opened. Obviously only worry about this if you need to. Under most circumstances you should experience performance issues in Flutter
@@FunwithFlutter the point is if it is cashed during compile time as a static const. if i create a repaintedBordery in the login screen maybe if the user loged in will never use this screen again until signing out. So if it will cached in the cache memory in this case will be a useless.
Is there any way to render flutter animation as in mp4 format and save it to local device gallery... *PLEASE REPLY* If yes then how to do that please make a video on that *pleaseeeeeeeeeeeeeee*
Hey i have an issue regarding flutter RepaintBoundary. I used repaint boundary to take screenshot of a widget. With normal widgets it works fine. Even with images too. But i dont know why when i put texture widget or flutter video_player widget inside repaint boundary, and i try to take screenshot of it, i always get null image. why is that ? Here is the sample flutter app i made to test it. All instructions are on the readme page on how to test it. Here is github link github.com/premingiet/flutter_texture_screenshot I used Android device to test it.
This "visual overview" in the beginning of the video was a very clever Idea. It helps us to have a transparent idea of the things we're about to learn.
I'm really proud of you for making so many wonderful and so helpful video tutorials! Thank you so much!
Keep it up! ;)
Thanks for the nice words :)
Thank you so much!!!! Now I fixed most of my performance issues!!
Fantastic!
Fabulous... Was thinking of improving performance. I was conditioned to think *having separate widgets for expensive stuff is the way to good performance*. Thank you. That 10 sec summary is cool. Thanks for that...
Great! That conditioned thinking is not wrong, sepending on how widgets are grouped together (and rebuilt) then definitely, it can have a performance impact. Painting is just one part, and generally we shouldn't be too concerned about the cost. Only use a repaint boundary if you see performance issues in certain areas that do heavy painting. There are a lot of other performance considerations as well and I'll be making more videos on it!
@@FunwithFlutter Ohh... Cool. That's why it's called *repaint* Boundary. It's only a boundary for painting tasks. Which implies, I will split expensive widgets in some occasions. Thanks mate.
Happy coding ☺️
Excellent video and really helpful! RepaintBoundary is definitely not a very well known Widget, this was an outstanding presentation of it!
Thanks a lot for the kind words. Glad you found it useful!
Yup. That's bad. It's a useful one. But not a well known one. Hopefully flutter will make repaintBoundary *the widget of the week*
Thank you! It's very helpful, for both canvas painting and app debugging.
You're welcome
Dude, you saved me! I was having a lot of performance issues due to custom paintings, now i can fix then! Thank you so much! =)
Is it your course updated to Null Safety?
The code is! I'm busy updating/migrating the code snippets and other examples throughout the course. The vids are not yet updated to null safety :( Glad that this vid helped though!
@@FunwithFlutter i'm looking to buying it, i just need some money ;). And once again, thanks for this great content =D
Excelente video, muy buena explicación. 😎
Thanks!🙃
My god this was beautiful
Thanks!
What do you do when Flutter decides to cash a dynamic widget all on its own? BTW, thanks for having an explanation in a way that makes good sense. From Ethiopia.
very useful video respect🙌🙌🙌
Glad you think so!
Wonderful presentation, one question: how do we deal with Sliver? I tried but it seems RepaintBoundary doesnt work with Sliver
Hmm, can you tell me what you tried? Slivers are used in CustomScrollView, and just like ListView it should manage the RepaintBoundary for you, so no need to add an extra RepaintBoundary. In the video I have an example showing a ListView. Because the ListView will always repaint independently from whatever is outside of the list, that's why they have a RepaintBoundary by default - same with CustomScrollView (Slivers).
If you enable the debugRepaintRainbowEnabled flag and scroll in a CustomScrollView (or ListView) you will see the different colored areas that are grouped (painted) together, showing where the layers are being cached for quicker scrolling. You'll also see the colors changing when you scroll back, meaning they are not being cached and the list is deciding to repaint them. If you want to increase the caching then you can play around with the cacheExtent attribute in a CustomScrollView. If the cacheExtent is high enough then Flutter will cache the previous slivers that were scrolled into view for further up the list, so now if you scroll back the colors may not have changed if those layers are still cached.
That all said, I only minimally understand how lists and grids are optimally rendered. "Infinite scrolling lists are notoriously difficult for toolkits" - quoting the docs. And there's a ton that goes into it to make it performant. I'd say trust the Google engineers on this and just use the lists like normal, while playing around with the attributes the lists expose (such as cacheExtent) to tweak it the way you like.
@@FunwithFlutter Yeah, I missed the point ScrollView has RepaintBoundary by default. Very clear explaination. Awesome, thank you so much.
@@FunwithFlutter Coooooool!!! How did you know that?? I want to improve my flutter skills like yours. What do you recommend?
Thanks for a very well explained video. I have a CustomScrollView with a blurry app bar like the iOS style but the performance is terrible. Can I apply RepaintBoundary to solve it? Any advice would be appreciated!
Wonderful tutorial, can we please have your course on udemy.
Yes please
W/FlutterActivity( 7241): Tried to automatically register plugins with FlutterEngine (io.flutter.embedding.engine.FlutterEngine@4d9c159) but could not find and invoke the GeneratedPluginRegistrant.
.
.
How can I solve this issue??
Men, I got a question, what means when the vertical red or green bar in the performance overlay never stop? is there a issue? how can I find out the problem?... Thank you for the answer 😎
Sounds like you have some logic that is still being triggered that’s causing the background work. Best way would be to use Flutter DevTools and profile the application. That will show you what methods are being called and allow you to find the source.
So should we wrap every static widget with repaint boundary?
Definitely not. Something I explain in way more detail in the course. There have also been similar questions to this where I provide a detailed answer. Painting all of the widgets to screen happens extremely fast and under most circumstance we should not worry about performance. Only seek to improve performance when it's an issue or when you believe it can be improved. Wrapping everything in a RepaintBoundary will result in higher memory use as more parts are being cached, and painting is generally cheap. Only do it for widgets with expensive paint operations or when widgets repainting should have no effect on other part of your tree (for example, a ListView - which has a repaint boundary by default). Here is a long answer I gave to similar questions:
The long answer: In Flutter you have Widgets, Elements and RenderObjects. Widgets are inexpensive and get rebuilt all the time, Elements keep track of widgets and their positions in the Tree (and their associated RenderObjects). The RenderObjects are responsible for layout, painting, etc. Flutter is very efficient in only rebuilding the part of the Tree that need updating (basically when the immutable widgets change). It also won't perform unnecessary work when it's not needed. This is mostly managed for you and you do not need to care, but as Flutter developers we can do things to guide the framework to manage the life cycle efficiently (keys, constants, small build methods, etc). Painting works differently though. When one widgets changes (even if it's in a separate build method) then Flutter/Skia will repaint everything that is within the same display list (RepaintBoundary). There are many different phases/computations that happen from widget -> to finally displaying the widget on screen. Repainting everything on screen is not necessarily a problem and under most circumstances this will happen fast. BUT, we have the OPTION to tell Flutter that this part of the widget tree should be treated independently from another part (in terms of Painting). If you're just laying out text then there is no real need as it's inexpensive to paint, but if you're doing crazier things or if you have a widget with an expensive paint operation then it makes sense to wrap it in a RepaintBoundary. Depending on the platform you're targeting you may have a different approach as well. On desktop you have more memory which frees you up to be able to cache more images (display lists) instead of repainting them, so maybe using more Repaint Boundaries. But there is not need to overuse them. ListView is a great example of using a RepaintBoundary, as whatever painting happens in a ListView is independent of other painting on the screen.
so when you said if you click on the button whole widget tree gets repainted. So it means if i tap a button the screen the whole screen will be repainted . Right?
Technically yes, but this isn't a problem. Skia/Flutter does this extremely fast and this is definitely not something you have to worry about. As Flutter developers it's more important for us to manage the Widget lifecycle and avoid unnecessary rebuilds (keys, constants, small build methods) - as this allows the Flutter Framework to be efficient in taking our widgets and updating what should render on the screen.
But Painting is different to the Widgets rebuilding, everything inside a RepaintBoundary will be repainted when something in that RepaintBoundary needs to be repainted. Not a problem most of the time, as Painting normal widgets are not expensive. Here is a long answer that I gave to a similar question if you want more info:
The long answer: In Flutter you have Widgets, Elements and RenderObjects. Widgets are inexpensive and get rebuilt all the time, Elements keep track of widgets and their positions in the Tree (and their associated RenderObjects). The RenderObjects are responsible for layout, painting, etc. Flutter is very efficient in only rebuilding the part of the Tree that need updating (basically when the immutable widgets change). It also won't perform unnecessary work when it's not needed. This is mostly managed for you and you do not need to care, but as Flutter developers we can do things to guide the framework to manage the life cycle efficiently (keys, constants, small build methods, etc). Painting works differently though. When one widgets changes (even if it's in a separate build method) then Flutter/Skia will repaint everything that is within the same display list (RepaintBoundary). There are many different phases/computations that happen from widget -> to finally displaying the widget on screen. Repainting everything on screen is not necessarily a problem and under most circumstances this will happen fast. BUT, we have the OPTION to tell Flutter that this part of the widget tree should be treated independently from another part (in terms of Painting). If you're just laying out text then there is no real need as it's inexpensive to paint, but if you're doing crazier things or if you have a widget with an expensive paint operation then it makes sense to wrap it in a RepaintBoundary. Depending on the platform you're targeting you may have a different approach as well. On desktop you have more memory which frees you up to be able to cache more images (display lists) instead of repainting them, so maybe using more Repaint Boundaries. But there is not need to overuse them. ListView is a great example of using a RepaintBoundary, as whatever painting happens in a ListView is independent of other painting on the screen.
What if we already use a Consumer widget on a child widget where only the child will be updated when something is updated?
Is the performance the same as having a RepaintBoundary?
Good question. Guess that is something I do not explain well in this video, but in the course there are dedicated videos addressing this, and this video builds on that. To quickly answer your question: What you're describing is efficient from a Widget rebuild and layout perspective. Using Consumers/Selectors will result in only parts of the widget tree rebuilding, and allows the Flutter framework to be efficient in what it determines to need updating (creating RenderObjects from Widgets).
The long answer: In Flutter you have Widgets, Elements and RenderObjects. Widgets are inexpensive and get rebuilt all the time, Elements keep track of widgets and their positions in the Tree (and their associated RenderObjects). The RenderObjects are responsible for layout, painting, etc. Flutter is very efficient in only rebuilding the part of the Tree that need updating (basically when the immutable widgets change). It also won't perform unnecessary work when it's not needed. This is mostly managed for you and you do not need to care, but as Flutter developers we can do things to guide the framework to manage the life cycle efficiently (keys, constants, small build methods, etc). Painting works differently though. When one widgets changes (even if it's in a separate build method) then Flutter/Skia will repaint everything that is within the same display list (RepaintBoundary). There are many different phases/computations that happen from widget -> to finally displaying the widget on screen. Repainting everything on screen is not necessarily a problem and under most circumstances this will happen fast. BUT, we have the OPTION to tell Flutter that this part of the widget tree should be treated independently from another part (in terms of Painting). If you're just laying out text then there is no real need as it's inexpensive to paint, but if you're doing crazier things or if you have a widget with an expensive paint operation then it makes sense to wrap it in a RepaintBoundary. Depending on the platform you're targeting you may have a different approach as well. On desktop you have more memory which frees you up to be able to cache more images (display lists) instead of repainting them, so maybe using more Repaint Boundaries. But there is not need to overuse them. ListView is a great example of using a RepaintBoundary, as whatever painting happens in a ListView is independent of other painting on the screen.
Fun with Flutter sounds like I should take the course to really dive deeper into flutter!
I’m comfortable with all state managements and flutter concepts but this in-depth understanding of code optimisation is something I should learn :)
Is there a link to the course?
Totally worth it to do a deep dive into the inner workings. The link: bit.ly/funwithcourse with discount applied. Go directly to Section 7 if you only care about the performance part!
If widget not change by time. Is it same benefit with const widget
Not too sure what you mean. const will make sure that the widget doesn't rebuild unnecessarily, however painting is different. Even if a widget is not rebuilt it will still be repainted within the same repaint boundary when another widget causes a repaint. Similar questions from other people provide a more detailed answer
@@FunwithFlutter yes. thank you !
the meaning of cashing RepaintBoundary is temporary or just in a session on app?
Flutter will cache an image the first time it is rendered in app. Not sure how this is persisted (session or app). I think app. But not sure. More info here: flutter.dev/docs/perf/rendering/ui-performance#checking-for-non-cached-images. You can also take a look at flutter.dev/docs/perf/rendering/shader which will allow you to "warm up" the shader. Which will allow you to get smooth performance from the first time the app is opened. Obviously only worry about this if you need to. Under most circumstances you should experience performance issues in Flutter
@@FunwithFlutter the point is if it is cashed during compile time as a static const.
if i create a repaintedBordery in the login screen maybe if the user loged in will never use this screen again until signing out.
So if it will cached in the cache memory in this case will be a useless.
@@FunwithFlutter thanks a lot for docs, i will read all of them.
Is there any way to render flutter animation as in mp4 format and save it to local device gallery... *PLEASE REPLY* If yes then how to do that please make a video on that *pleaseeeeeeeeeeeeeee*
Oof no idea sorry
Hey i have an issue regarding flutter RepaintBoundary. I used repaint boundary to take screenshot of a widget. With normal widgets it works fine. Even with images too. But i dont know why when i put texture widget or flutter video_player widget inside repaint boundary, and i try to take screenshot of it, i always get null image. why is that ? Here is the sample flutter app i made to test it. All instructions are on the readme page on how to test it. Here is github link github.com/premingiet/flutter_texture_screenshot
I used Android device to test it.
First Comment
Nice