Angular 7 Virtual Scroll - To Infinity and Beyond
Key Takeaways
This video teaches how to use Angular 7 Virtual Scroll component with Firestore for high-performance, infinite, and real-time list rendering. It covers setting up the CDK, using the cdk virtual scroll component, and implementing real-time data updates with RxJS and Firestore.
Full Transcript
[Music] angular seven is officially here and one of its coolest new features is the virtual scroll behavior in the component development kit it allows you to easily build a high-performance list that only renders the items visible to the user in today's video I'll show you everything you need to know about virtual scroll but we'll also take things a few steps further by making an animated infinite and real-time if you're new here like and subscribe and I'm giving away some winter swag with this video all you have to do is leave a comment below and we'll pick a winner on the live stream on Wednesday so first of all what is virtual scrolling and why would you want to use it it's useful when you have a large list of items to loop over but you only want to render the items that are visible in the viewport this should give you much smoother performance when working with big lists because the browser only needs to render a small subset of the data the cdk provides a handful of components and directives to make virtual scrolling super easy in addition it provides a handful of tools that makes it much easier to measure the scrolled element which we can then use to pull data from our back-end database in batches giving us an infinite real-time virtual scroll the first thing you want to do is make sure you're up-to-date with angular version 7 then we can quickly add the cdk to our app by running ng add angular material you'll notice that when you do this in angular 7 it gives you a prompt to have questions to go through you can just select the defaults and then if you also want to follow along with the firebase part you'll want to install angular fire at this point as well but I'm going to start with just the cdk basics before we get to that point if we jump over to my app module you can see that I'm importing the scrolling module from the cdk and then I also have a couple of components generated just for this demo so you want to make sure that you have the scrolling module here in the import section and then optionally angularfire for the back-end stuff now that we're all set up let's start by looking at the basics of virtual scroll the first thing you'll need is a big list of something to loop over so I want to show you how to generate a ton of fake data really quickly first I wrote my own helper function that will return a random emoji and then I installed the fakir j/s library that we can use to generate fake names and email addresses and stuff like that then I'll set up a property of people and then I'll define that property as an array of 100 elements then we can map each element that array to an object with some fake data so we'll give each object a name a bio and an emoji so that gives us a big array of items to loop over now we need to go into the HTML and set up a context for our virtual scroll we can do that by just dropping in the cdk virtual school viewport component it has one required argument which is the item size or height which is represented in pixels so typically with a virtual scroll you want items to have a fixed height if possible so with that being said let's quickly jump over to our CSS code you'll first want to make sure that your viewport has some height so in this case I'm having it fill up the entire height of the viewport then each item inside of my viewport will have a fixed height of 100 pixels which matches the item size argument in the component itself and just for bonus points if you want to make it look cool this is a good place to customize the pseudo selector for the actual scroll bar element to give it a different style and size as the user Scrolls down when inside the context of a scroll viewport the cdk gives you a structural directive called cdk virtual for it replaces ng4 but it works exactly the same way if we go ahead and serve the app what's happening is that the cdk is keeping track of the items in the list and which items will fit into the viewport a good way to demonstrate this is just by using a plain CSS animation because that animation will be applied each time the item is rerender so I'm using a little library here you may have heard of called animate CSS and you'll notice as I scroll up and down the animation is reapplied to each element because it's being rear-ended in the Dom in a regular list the CSS animation would only be applied on the initial page load so that's kind of an interesting little side effect with virtual scroll that you can play with now there's a couple of other basic things that you need to know first of all the virtual scroll component emits a custom event called scrolled index change eventually we'll use this to implement our infinite scroll because it emits the index of the item that the user has scrolled to so we can use that to determine when to pull the next batch of items from the database then you'll also notice that this component has its own public API that we can use to do things like measure the viewport or get the total item list size or even dynamically scroll to a specific element in order to use those methods you'll need to grab the component from the Dom and you'll definitely want a strong type it so will import the cdk virtual school viewport component and then we can grab it with view child then we can set it up as a property called viewport and if we start typing this out you'll notice it shows us a bunch of different methods that we can use so that's how you can interact with the component dynamically in your typescript code for example if you have some chat messages you could use this to scroll directly to the bottom or update the scroll position when new messages are received now that you know the basics we're ready to build out our infinite real-time scroll using firestore I created an infinite scroll video with firestore a while back but today's solution will improve upon it in two big ways first of all it will make the list real-time so even though we're pulling items and batches they'll still be updated in real time if the data changes on the back end and the second obvious improvement is that this will be a virtual scroll so we should be able to get much better performance as the user Scrolls through more and more items and also the cdk will just make our code much more simple and reliable now starting in the component type script we'll first import angularfire store as well as a bunch of different stuff here from rxjs we'll pull items from the database in batch sizes of 20 then we'll set up a property for the viewport itself and then one to determine whether or not we've reached the end of the list and then a behavior subject to keep track of the offset that we'll use to make our query to fire store and it's important that the subject starts with null and not undefined or an empty string because we need that null value to start our query to fire store so every time this offset changes we're going to want to make a new query to fire store for the source data but we only want to do that when the user Scrolls to the bottom of the current list so we can listen to that index change event that I showed you earlier and then we'll run this next batch method which takes the event as well as the very last item in the list as its argument then if we've reached the end then we'll just go ahead and return and not pull any additional data but otherwise we can take the viewport rendered range end value and compare that to the total items in the actual list itself and conveniently the cdk has a method for that called get data length so if the ending index equals the total length of the items in the array then we know that we've reached the end we can send the next offset value to our behavior subject which will reactively pull a new back of items from the database and then while I have you here I'm also going to set up a track by function which just tracks the index of the items in the array and only renders the ones that change that's just a good thing to have for real-time data because otherwise the entire list would rerender for each item that changes so now I'm going to break this down into manageable chunks the first one is getting an individual batch from the database and to do that we need to know the last scene item in the previous batch I've added 200 records to firestore of the same dummy data that I showed you earlier and I want to do a paginate query on that data so first I want to order by that user's name and then we'll start after the offset value which needs to be null if we're starting a new batch otherwise it needs to be the name of the last user in the last batch and lastly we'll limit our query to our batch size which again is 20 from there we'll go ahead and call snapshot changes to get these documents snapshots as an observable if this observable emits an empty array then it's safe to assume that we've reached the end of our collection in the database at which point we can set the end property to true now the tricky part is keeping everything up to date in real-time across multiple batches in order to do that reliably we need to take the array of documents and then map them to an object where the key is their document ID this allows us to update a documents data anywhere in the list based on its key value instead of its index position this ensures that every document in the array is unique because otherwise we are at risk of adding duplicate documents to the array if things change between the queries so the next thing we want to do is go into our constructor and set up a source observable that first listens to the offset value and then merges and new batches whenever the offset changes which again will happen when the user Scrolls to the bottom of the list that event can be fired multiple times so I'm going to throttle it by 500 milliseconds just so we're not sending off redundant requests to the backend now you'll notice that I'm using merge map here to merge a new batch into the stream it's important to use merge map here and not switch map because otherwise the previous subscriptions would be canceled meaning that only the very last batch would be real-time from there we can pipe in the scan operator which will just merge in the current batch with the existing batches so this batch map observable is our main source of truth because it contains all the mappings for the individual item keys and their data but we still want an actual array to loop over in the front end so we can go here and define our actual infinite array of objects as this batch map but map to the object values which will give us an array of objects and that takes care of the main logic for our infinite real-time virtual scroll that may have seemed relatively complex but in the grand scheme of things it's very simple considering what it does now we just have a couple of small modifications in the HTML if you want to show an index in your list you can just say let I equals index and then we'll also add in our track by function that we defined earlier then we can listen to that scrolled index change event and the first argument will be the event itself which is the index number then the second argument is the offset value for the query which in our case will be the name of the very last person in the array we can actually just parse that value right here in the template not the prettiest code in the world but it works then the last thing we need to do is unwrap the infinite observable my preferred way of doing this is using an NG container and then unwrapping the observable with the async pipe we can then say as people to give us a template variable of the array of objects and then we can just use it throughout this HTML now if we pull up the demo you can see that we have all of our objects here in the database and they're queried in the same alphabetical order that we get when we order them on the firebase console and if we make any changes to our data on the right it'll be reflected in the UI on the left in real time it is important to keep in mind that the actual position of the item won't change and if it's deleted it won't be removed from the list but if you need that functionality that could definitely be made possible with some additional work in the code now I am pulling up the browser console and you'll notice that there's an array being console logged on the right every time we get to a certain event the array size initially starts at 20 and then as we scroll down it will change the offset and our array grows from 20 to 40 to 60 and so on and from the users perspective it happens so fast that it looks like this list existed all along which is exactly what you want with an infinite scroll but we are keeping track when we get to the end of the list so when we finally reach that point we'll go ahead and give the user some indication that there are no items left to retrieve that's all folks if this video helps you please like and subscribe and if you want to take your development to the next level consider becoming a pro member at angular firebase comm you'll get access to all kinds of exclusive content like full courses and my book designed to help you build and ship your app faster thanks for watching and I'll talk to you soon
Original Description
Learn how to use the new Virtual Scroll behavior in Angular CDK v7 to build a list that is infinite, animated, and realtime with Firestore. https://angularfirebase.com/lessons/infinite-virtual-scroll-angular-cdk/
- CDK Docs https://material.angular.io/cdk/scrolling/overview
- Firestore https://cloud.google.com/firestore/docs/
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Fireship · Fireship · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Angular 4 Development and Production Environments with Firebase
Fireship
OAuth with Angular and Firebase Tutorial
Fireship
Anonymous Authentication with Angular and Firebase - Lazy Registration
Fireship
Angular Router Guards for Firebase Users
Fireship
Angular Firebase CRUD App with NoSQL Database Tutorial
Fireship
Upload Files from Angular to Firebase Storage
Fireship
How to Deploy an Angular App to Firebase Hosting
Fireship
Sharing Data between Components in Angular
Fireship
Loading Spinners for Asynchronous Firebase Data
Fireship
Angular 4 Transactional Email with Google Firebase Cloud Functions
Fireship
Firebase Database Rules Tutorial
Fireship
Autocomplete Search with Angular4 and Firebase
Fireship
Reddit Inspired Upvoting System with Angular and Firebase NoSQL
Fireship
Angular Drag-and-Drop File Uploads to Firebase Storage
Fireship
Text Translation with Firebase Cloud Functions onWrite and Angular 4
Fireship
Custom Usernames with Firebase Authentication
Fireship
Twitter-Inspired Follow Unfollow Feature with Firebase and Angular 4
Fireship
Simple Pagination with Firebase and Angular 4
Fireship
How to Connect Firebase Users to their Data - 3 Methods
Fireship
Add Toast Message Notifications to your Angular App
Fireship
Facebook-Inspired Reactions System with Angular and Firebase
Fireship
Learn NgModule in Angular with Examples
Fireship
Lazy Loading Components in Angular 4
Fireship
Stripe Checkout Payments with Angular and Firebase - Part 1
Fireship
Process Stripe Payments with Firebase Cloud Functions - Part 2
Fireship
Selling Digital Content in Angular with Stripe Payments - Part 3
Fireship
Angular 4 Full Text Search with Algolia - Part 1
Fireship
Algolia with Firebase Cloud Functions - Part 2
Fireship
Firebase Phone Authentication in Angular 4
Fireship
Top 7 RxJS Concepts for Angular Developers
Fireship
Learn Angular Animations with 5 Examples
Fireship
Advanced Firebase Data Filtering (Multi-Property)
Fireship
Realtime Maps with Mapbox + Firebase + Angular
Fireship
Angular Reactive Forms with Firebase Database Backend
Fireship
Send Push Notifications in Angular with Firebase Cloud Messaging
Fireship
Top 7 Ways to Debug Angular 4 Apps
Fireship
Infinite Scroll with Angular and Firebase
Fireship
Use TypeScript with Firebase Cloud Functions
Fireship
Realtime Graphs and Charts with Plotly and Firebase
Fireship
Role-Based User Permissions in Firebase
Fireship
User Presence System in Realtime - Online, Offline, Away
Fireship
Location-based Queries with GeoFire and Angular Google Maps
Fireship
Angular ngrx Redux Quick Start Tutorial
Fireship
Angular Ngrx Effects with Firebase Database
Fireship
Progressive Web Apps with Angular
Fireship
Angular Ngrx with Firebase Google OAuth User Authentication
Fireship
RxJS Quick Start with Practical Examples
Fireship
Send SMS Text Messages with Twilio and Firebase
Fireship
Firebase Database Performance Profiling
Fireship
Native Desktop Apps with Angular and Electron
Fireship
Subscription Payments with Stripe, Angular, and Firebase
Fireship
Firestore with AngularFire5 Quick Start Tutorial
Fireship
Angular HTTP Client Quick Start Tutorial
Fireship
Google Sign-In with Firestore Custom User Data
Fireship
Star Review System from Scratch with Firestore + Angular
Fireship
Angular Chatbot with Dialogflow (API.ai)
Fireship
Learn @ngrx/entity and Feature Modules
Fireship
Infinite Scroll Pagination with Firestore
Fireship
Faster Firestore via Data Aggregation
Fireship
Contentful - CMS for Angular Progressive Web Apps
Fireship
More on: Frontend Performance
View skill →Related AI Lessons
⚡
⚡
⚡
⚡
The AI Moat Paradox: The Better Models Become, the Less Models Matter
Medium · AI
170,927 AI Papers Reveal the Biggest Research Shifts of the First Half of 2026
Medium · Machine Learning
170,927 AI Papers Reveal the Biggest Research Shifts of the First Half of 2026
Medium · Data Science
[PoV] When Everyone Is Smart, No One Is
Medium · AI
🎓
Tutor Explanation
DeepCamp AI