[MUSIC PLAYING] CRAIG LABENZ: One of the first
things new Flutter developers learn about is the ListView
widget, because it's so easy to use when you
need your widgets to scroll. And once you know about this,
all is well in scrolling land, until one of the
widgets you want to parade through your
viewport is itself a ListView. Suddenly, Flutter is barking
at you about viewports, receiving unbounded dimensions,
and well, many things are unwell in scrolling land. What the Flutter? If you've seen this error in the
past and read Flutters message, you probably saw the suggestion
to set Shrink Wrap to true. You did that and
the error went away and peace was restored
to scrolling land. The only problem was a
threat was still lurking. Shrink Wrap can be a
costly performance hit. To understand why, let's refresh
our understanding of lists. Imagine you're below deck
on a cruise ship looking out a porthole. Suddenly, a large school
of fish starts swimming by. You're not moving
anywhere, but the fish are zipping through
your field of vision. You have no idea how
many fish are to come. For all you know, it
could be an infinite line of fish stretching
deep into outer space. Either way, you can only see
a few fish at any one time. And this is how ListViews work. The porthole in our
analogy is the space that you allot
for your ListView, and the fish swimming
by are your widgets. And this idea of a
specific viewport is critical when you
consider what Flutter has to deal with when one
of the widgets it encounters is itself a ListView. Now suddenly there's
two portholes? How is this supposed to work? Well, the fact is it can't. And so Flutter requires
your inner list to completely evaluate itself
and figure out its full size up front and then proceed
by your top level viewport, behaving as if they're
all just one widget. You might have
guessed it, but that's exactly what Shrink Wrap does. It forcibly evaluates an
entire list of widgets. And now you might be
guessing another thing, how this could be a big
performance problem? If one of those inner lists
contain lots of widgets, especially if they
have animations, when it approaches your
viewport and Flutter is forced to render
it completely, you're at a high risk for
dropped frames, jank, stutters, the worst. The bigger your inner lists
are, the more important the following change is. Let's look at some code. Imagine you have this scenario,
a ListView comprised entirely of ListViews. If you set Shrink Wrap to
true on each inner list and set never scrollable
scroll physics, Flutter will technically
be able to render your UI. But remember that
danger still lurks. Luckily, the fix we need to
implement is very simple. First, replace the
outer ListView.builder with a custom scroll view. Second, change our inner list
of widgets from ListViews to SliverLists. Third, we grab
all the widgets we were putting in those
inner list views and put them in
Sliver Lists instead, which require a delegate. Now, I don't know about
you, but delegates always make me think something
scary is about to happen. But luckily, this
one isn't scary. If you're converting from
inner ListView.builders, a great choice is the
SliverChildBuilderDelegate, because it looks so similar. Copy over that
indexed widget builder function from your old
ListViews, this time using it as a positional parameter. And you're done. You can now scroll through
your list of lists, knowing that each inner list
is still building efficiently, only rendering whatever
fish are currently in front of your viewport. To play with this yourself,
check out the DartPad link below. Notice how the behavior
of the build methods print statement changes from
step one with Shrink Wrap and step two with Slivers. That's a huge
performance improvement. For more info on Flutter,
head to Flutter.dev. [MUSIC PLAYING]
Excellent. Thank you!