Browsers become faster every day, but still, DOM updates are costly. If we have large lists, the browser needs to render them upfront, creating hundreds if not thousands of DOM nodes, even though the user might not even scroll that far in the list. Not only does this slow down the scrolling itself, but even the page load of our app. To optimize this experience, we can use virtual scrolling, in particular, in this lesson we’re using Angular’s CDK to implement that.
Juri Strumpflohner: [0:00] This is a very stupid application which will help us showcase the performance issues of having an enormous amount of DOM elements inside of your page. As you take a look at this application, we have here a main component, where we have an ngFor, which iterates over that list. That list is actually an array of 100,000 entries.
[0:18] In fact, if you go over here and scroll down, you see a huge amount of elements. Let's open the element panel a second. If I open here our app-root, you can see I click. There's even a lag in the Chrome dev tools of opening up here all those divs which are inside that app-root component.
[0:39] In fact, also, if I refresh the page, you can see the delay in the startup time. What we want to do is now optimize this, because actually, we don't want to render all of the items, but just those items the user actually sees. This is what is called virtual scrolling.
[0:56] If you go over to material.angular.io, we have here a section, CDK, which is the Component Development Toolkit, which is a set of components which are independent of machine or design, which rather help us create better and more performed application.
[1:10] One of those components which you have is the scrolling. The scrolling has also a virtual scroller in place, which we will use now to optimize our application. The first step is, obviously, to install the angular CDK. We do that by npm install @angular/cdk. I have already installed that. If you go to the package.json, you can see here the CDK being installed.
[1:35] The next step is to use that scrolling module. Let's go back for a second to the documentation. Let's go to the very top. We can see here that scrolling module. Let's copy that, go over to our app module, and import that as usual. We will reference it here in the import section, of course.
[1:56] Once we have that, we have our application set up. Let's go to the app component. We want to make this virtually scrollable. What we have to do here is to use the cdk-virtual-scroll-viewport. Let's enclose our whole template into that tag here.
[2:14] That virtual scroll viewport needs a couple of inputs. If you save it for a second, then go here to our console, you can see then we get an error because we need the item size. The item size is how big our entry is in our list so then the virtual scroller can calculate how many items will actually fit in the current viewport.
[2:37] Let's go here and specify the item size. Let's say 18 pixels. We also want to limit the height here of the total scroll viewport. Let's say here style, height. Let's save.
[2:51] You can now see the list is smaller, but we still have a lot of elements inside here. Let's open here to app-root, CDK virtual scroller, which wraps it now. As I open here the inner div, which hosts all of our DOM elements, still all of them are there. It seems that virtual scrolling is not working.
[3:08] The reason is that we have to exchange here our ngFor with the one provided by the virtual scroller from the Angular CDK. It is called cdkVirtualFor. Once you have that, let's save again. You can now see already how fast our application is to boot up. If I do a refresh again, you can see it's already here.
[3:26] Let's inspect here our DOM tree. If I navigate in here the div, it opens immediately. You can see here the elements which are present on our page, which go until 23. If I scroll, you can see that further elements are being added as I scroll, and the ones at the very beginning are being removed.
[3:45] We always have a fixed set of elements inside here, which allows us to have fast scrolling so the scrolling doesn't suffer in performance. Still, we have a very fast start-up time because only a finite set of elements is actually rendered on our page.