Introducing FlashList: Let's build a performant React Native list all together

Rate this content
Bookmark

In this workshop you’ll learn why we created FlashList at Shopify and how you can use it in your code today. We will show you how to take a list that is not performant in FlatList and make it performant using FlashList with minimum effort. We will use tools like Flipper, our own benchmarking code, and teach you how the FlashList API can cover more complex use cases and still keep a top-notch performance.

You will know:

- Quick presentation about what FlashList, why we built, etc.

- Migrating from FlatList to FlashList

- Teaching how to write a performant list

- Utilizing the tools provided by FlashList library (mainly the useBenchmark hook)

- Using the Flipper plugins (flame graph, our lists profiler, UI & JS FPS profiler, etc.)

- Optimizing performance of FlashList by using more advanced props like `getType`

- 5-6 sample tasks where we’ll uncover and fix issues together

- Q&A with Shopify team

81 min
19 Oct, 2022

Comments

Sign in or register to post your comment.

Video Summary and Transcription

FlashList is an alternative to React Native's FlatList that aims for high performance and ease of use. It provides significant performance improvements over FlatList, with higher JSFPS and UIFPS. FlashList has been successfully implemented in Shopify's Mobile Shop, POS, and Inbox apps. The workshop covers the migration process to FlashList and optimization techniques. FlashList reduces unmount events, fixes item recycling issues, and improves load time and rendering performance.

Available in Español

1. Introduction to FlashList

Short description:

Hey, everyone! My name is Marek, a software engineer at Shopify in Berlin. I'll be introducing FlashList and handing over to Talha. Talha Nikwi, a development manager at Shopify, will walk you through the workshop. David, a developer manager from Barcelona, will also support us. Let's start with FlashList, an alternative to React Native's FlatList. We've had issues with FlatList's performance and responsiveness, so we need a faster and flat list. RecyclistView is a popular open-source library that can fix these issues, but it has some shortcomings like a complicated API and difficulties with dynamic heights.

Hey, everyone, my name is Marek. I'm a software engineer at Shopify, and I'm based in Berlin. And I'll be doing a presentation as an introduction to FlashList, and then I'll hand it over to Talha to lead the rest of the workshop. So if you want to introduce yourself as well.

Yeah, sure. Thanks, Marek. Hi, everyone. My name is Talha Nikwi. I'm a development manager here at Shopify. I lead a team called Retail Dev Accelerate, which is taking care of a lot of infra-related work for our POS application. I had the opportunity to collaborate with Marek and David on the FlashList project. And I'll be walking you through the workshop after Marek is done today. Thank you.

And then David will be here to support us, so if you want to give a quick introduction as well.

Yeah. Thank you, Marek. I'm David. I'm from Barcelona, Spain. I see some people from Spain as well in the audience. Nice to see. I'm a developer manager here at Shopify since a year ago and I was part of the FlashList team and I'm proud of showing this to you today because it's a project that it was like super nice to work on and to see the impact that they're doing in the community. So yeah. I'm glad to be here today.

Perfect. Then without further ado, I will share my screen to go through the presentation and yeah, let's start.

Awesome. I suppose everybody can share see my screen now to tell me. As I mentioned, my name is Marc Fort and today I will be giving a quick introduction to the topic of this workshop which is FlashList. So let me start with a tweet here. What if React Native ends up holding us back. Hold us back. Where are you rendering? A list of cards with checks in them. Now, of course, this is a bit of an over exaggeration, but it gives you a hint at how lists are perceived in React Native and that is inside React Native community but also outside. Additionally, we've had our share of issues with FlatList, the default component coming from React Native. This is our shop app running on a low-end Android device. As you can see, it's not responsive at all and it has a lot of blank cells that sometimes span the whole screen. In general, this is definitely not the user experience we want for our users. So we need a faster list. And we need a flat list. But first, let's consider alternatives such as RecyclistView. RecyclistView is a popular open source library that tries to fix the performance of lists in React Native. And the advantages are that it actually really is fast if you implement it properly. And the API is highly customizable, so you can achieve almost anything with it. And it is also quite well tested. It has been used for a bunch of years now in larger companies. And it has held up well. But it also has a couple of shortcomings. Primarily, the API the API is really complicated leading to less than desirable developer experience. It is also quite difficult to achieve performance cells with dynamic heights. And additionally, due to the fact that Recycler's View is a JS only implementation, there is there are also some first render layout spaces that should not be there.

2. FlashList Implementation and Performance

Short description:

We built our own version called FlashList to address the shortcomings of FlatList. FlashList aims for high frame rates, minimal display of empty items, and ease of use. It uses a similar API to FlatList but introduces props for better performance. FlashList utilizes a Recycling Pool to efficiently manage item rendering, saving resources. We also fixed the first render layout issue with the Auto Layout View. FlashList provides a performant dynamic cell height and utilizes the Recycle engine. We'll discuss metrics during the workshop, but preliminary tests show significant improvements over FlatList.

So these shortcomings meant for us that we really needed to build our own version at Shopify and we called it FlashList. The goals of the projects have been to achieve a high frame rate for both UI and JSFPS. We wanted to minimize as much as possible the display of empty items and we wanted to make the library really easy to use and achieve as much performance as we could for a really smooth developer experience.

So this is the API for FlashList that we've come up with and as you can notice, we have mostly just changed the name of the component from FlatList to FlashList and try to keep the vast majority of the props the same. Now there are some props in FlashList that do not exist in FlatList for achieving better performance, and you will learn about some of those later in the workshop. Dynamic Heights, they pose no sweat and as I mentioned, that is even with the FlatList kind of API.

So let me answer a question now, how is FlashList so fast? And I'll start with actually explaining how FlatList works first. So in FlatList, we have a couple of items that are in the viewport here indexes from four to six, then we have a couple of preloaded items that are the bottom of the list. And then we have a couple of items that are still loaded in memory, two to three. Now, the amount of items in memory is in the FlatList case, quite high. But as you scroll down enough, FlatList will need to free up some space in the memory. And that's when VirtualizedList comes in component that FlatList uses under the hood. And what it will do is as you scroll down, it will empty the items, so that it replaces the content with just an empty view and keeps the dimensions of the cell, so the list layout does not change. This also means that as you scroll up and you get to these emptied items, you will need to render them always from scratch. And also as you scroll down and you need to load more items, you will also always need to render these items from scratch, which takes a lot of resources.

Platforms, on the other hand, take a different approach. We, again, have a couple of items in the viewport. We have some items that are preloaded, but the amount of those items is quite low. And most importantly, we have a concept called Recycling Pool. So as we scroll through the list, the items that are not visible on the screen anymore, they are put into the Recycling Pool. And then when we need to load more items, Flashlist will look into the Recycling Pool, and if there are any items that are currently not in use, it will move that item back into the list and just rerender it with the new data. This means that, for example, if only a text in the cell changes, it will have to re-render just that part, and it will not have to create anything from scratch. And that makes it quite As a visualization, you can see as we scroll, the items are being put into the recycling pool, and then when we need to create more items at the bottom of the list, FlashList will actually start pulling out the items from the recycling pool back into the list, and we will start to get instances and IDs that we've actually seen before. And again, this saves a lot of resources. We also needed to fix the first render layout issue. So this is how the first layout issue looked with Recycle List View, and you can see that the items kind of overlap each other. Now this is only for a couple of frames, so this recording is slowed down to make this more obvious. To get deeper into the problem, on the left hand side, you have how Recycle List View expects the layout to look like. It expects every item to be the same depending also on the estimated item size, which is a problem we'll also learn more about later at the workshop. But the actual layout, the thing that's actually rendered on the screen, is different. Here we have item number zero that has, for example, 100 pixels of height, but then the item number one, it has, for example, 200 pixels, but Recycle List View still counts with it having only 100. And so the item number two is then over the item number one, resulting in items overriding each other. So we implemented a native view called Auto Layout View that goes through the whole list. And whenever it sees items overlapping each other, or when there are spaces between items, it automatically fixes those UI issues and puts everything edge to edge as it's supposed to be. So with FlashList, if we look at the recording we can know like. To sum up the FlashList implementation, we have an API that's very similar to FlatList. We've implemented a native view to fix the first render issue. We've been able to achieve performant dynamic cell height with the simple API similar to FlatList and we have used Recycle as the inner engine that we've built on top of it to achieve the API. And also give you more performance out of the box. So we'll quickly look at some of the metrics but you will also get the metrics first hand during this workshop. I have been using a Motorola Moto G10 device which is quite low-end and so keep that in mind when seeing the numbers. First let's look at FlatList UI in JSFPS using Twitter sample. Very similar to what we will see in the workshop. And as you can see, the JSFPS drops multiple times to zero and UIFPS drops to sub-10 as well.

3. FlashList Performance and Workshop Setup

Short description:

FlashList provides significant performance improvements over FlatList. It achieves higher JSFPS and UIFPS, resulting in a more responsive user interface. The plugin developed for this project shows that FlashList has significantly fewer blank spaces compared to FlatList. FlashList is production-ready and has been successfully implemented in Shopify's Mobile Shop, POS, and Inbox apps. The excitement in the community is growing, and the project can be found on GitHub. Telha will now take over and guide you through the coding part of the workshop.

And also give you more performance out of the box. So we'll quickly look at some of the metrics but you will also get the metrics first hand during this workshop. I have been using a Motorola Moto G10 device which is quite low-end and so keep that in mind when seeing the numbers.

First let's look at FlatList UI in JSFPS using Twitter sample. Very similar to what we will see in the workshop. And as you can see, the JSFPS drops multiple times to zero and UIFPS drops to sub-10 as well. So what we get in the end is average JSFPS of 11.8, average UI 44 and JS threadlock is almost two seconds which means that for almost two seconds user has not been able to interact with screen at all because when the JS is in the threadlock that's not possible.

If we look at FlatList UI in JSFPS with the same sample by just changing the name, we can see that the JSFPS never drops that low, never drops even close to being zero, and UIFPS stays around 64 most of the time. So we get an average JSFPS of 49 and average UIFPS of 58, which is about four times improvement just by changing the name.

We have also been looking at blank spaces using a Flipper plugin that we've built just for this project. And as you can see with FlatList, we get huge blank cells spanning the whole screen which are the real large parts at the top, and the average is around 280 pixels. With FlatList, we get a different story. We do get some blank cells, but they are quite limited and only appear for a limited period of time, and so the average in the end is around 45, or so, which is seven times better than with FlatList.

So, is FlashList production ready? Let me get back to the initial example of Shop App. On the left, you have FlatList, which was for multiple seconds not responsive at all, and it had those huge blank screens that were spamming the whole screen. And on the right, we do have some small blank cells, but only for a limited period of time, and more importantly, the app is extremely snappy, even on such a low-end Android device such as Moto G10. We are also using it in all of our apps in Shopify Mobile Shop, POS, and Inbox. And we've also seen a lot of excitement in the community, and the list is also being used extremely now in production as well. So you can check out the project on GitHub, but you will also do that during this workshop. And that's it for me. And I'll pass it over to Telha, who will get more into the coding part of the workshop. Thank you.

Thank you, Merik, for the amazing introduction to Flashlist. I'll take over from here. Let me start presenting my screen. All right. Second. Okay. So, before we begin, I'll quickly introduce everyone to— All right, even before I start, right, can I get some thumbs up in the chat if everybody can hear me okay? And if you're here, just to let me know. Awesome. Awesome, I get to see some responses. All right. All right. Okay. So, I'm sharing one document in the chat right now. Make sure that you use this link and open this document. So, this is what you're going to see. It's right here on my screen. So, this is basically all the setup steps that we have for you. I'm going to walk through each of those. I just want to give you a quick overview of what you can do in case you run into problems. So, first of all, there's a link for questions. Make sure that you use this link to ask us questions and not the chat. We are going to try and go through most of them towards the end of this workshop. There's a link to a performance tracking sheet, which I'm going to talk about very soon. You have a link to the slides that I'm going to present. Most importantly, there is this section called skip ahead. So, at any point, let's say, if you have not been able to complete a particular task, you can skip to any task that you want. Let's say, if you jump to task four, task one, two, three will already be done in that snack for you already. So, no need to worry if you are not able to keep up, you can skip ahead, and you can do it at your own, in your own time later on.

4. Workshop Introduction and Benchmark

Short description:

Let's get started with the workshop. Make sure you have Expo Go installed and open the provided link. Connect your phone by scanning the QR code. Open the performance tracking sheet and add your name and device. The sample is a list of Twitter feeds with related tweets. Clicking a horizontal item changes the primary tweet. Now, let's move on to the first task. Click the Run Benchmark button and wait for the average FPS result.

All right. So, without further ado, let me get into the workshop, right? I'll start presenting.

All right. So, make sure that you have Expo Go installed in your phone. And just make sure that you open, this, the link that's mentioned in the document here, open the following scan, you can open this, and you'll see something like this. I'm also going to scan this QR code and make sure that my phone is connected. Make sure you scan your QR code and not mine. So, here we go. You can see my device on the right, it's the Moto G Stylus. Okay. So, I have my device connected at this point. You can see this device does show up in Snap. I can click on the reload app button to reload at any point. And on the left, you can click on the no errors and one warning and logs to view the logs that are going to show up. So, that was a quick introduction on how Snap is going to work.

Right. As the second step, go back to the document and open the performance tracking sheet. It's going to look something like this. So, what I want everyone to do after you have launched the sample and you can see it in your ExpoGo application, just go ahead and click this checkbox and add your name and device on the left. This is how we can keep track of how everyone is progressing. Joshua, you make sure that your ExpoGo app is up-to-date. Alright. Go ahead and add your names. Alright, first Android device on the list. Glad to see that. iPhone 14 Pro Max is also there. Is there anyone who is running into any issues? Go ahead, go ahead. Yeah, don't worry about the rest of the columns. I'm going to walk you through what we're exactly going to do, and we'll do it together. Just add your names, your device, and whether you have loaded up the sample in your Xpogo application. All right, we'll quickly explore what the sample is about, and then we'll start with the first task. This sample is a list of Twitter feeds, and some of these tweets have related tweets along with them. So if you notice, anything that has more than two retweets has a related tweet. So it's a combination of vertical lists and horizontal lists. If you click any of the horizontal items, it's going to change the primary tweet. And the element is going to become selected. And that's all that this sample does. Feel free to play with it.

So moving on, I'll just move on to the next task, and we'll start doing stuff now. All right, what's the first thing? So what we want to do is, if you notice, there's a Run Benchmark button on the top. I want everyone to click on it and wait for the benchmark to run and finish. It's going to give you an average FPS number at the end of the run. I'll do it along with you. Let's do it together. All right. OK, mine is running. OK, so I got a result. My average AFPS was 1.7. Remember, mine is a pretty low end device. It's a Moto G Stylus with a Snapdragon 665.

5. Benchmark Completion and Next Step

Short description:

After completing the benchmark, enter the average number in the baseline column. Make sure to reload the application and choose the correct link if needed. The performance number depends on the device used. Nested vertical and horizontal lists can be complex. Please ensure you're using the correct sample. Let's move on to the next step.

So after you are done, what I want everyone to do is go and put this average number in the baseline column. You just have to click that run benchmark button and wait. All right, very nice. A lot of people have been able to do it. Remember, you have to put the average number and not the max FPS. Yeah, Josh, your number is pretty high. If you think you have not got the right number, make sure that you reload the application and make sure that you chose the right link and just run the benchmark again, and you can update it later. Yes, this number is indeed dependent on device performance, and I'm using a very low-end device, Moto G Stylus, Snapdragon 665. Flat list, all the items are memorized. Everything is as it should be. It's just that when you have a vertical list and a horizontal list nested together, it's a pretty complex thing. Ah, that's what? You opened the final sample directly. All right, Joshua, make sure you fix it. So we'll go ahead in the interest of time because I really do want to take questions in the end.

6. Sample Overview and Migration Start

Short description:

Let's look at the sample and start the flash list migration. Change the name to flash list and import it. Reload the application. First step to migration completed.

Okay, so what's the next thing? What we want to do now is, let's look at the sample, all right? If you open the SRC folder inside Twitter, you would find three files, TweetSell, TweetContent, and Twitter. Twitter is where our flat list is defined. So what I want everyone to do is start their flash list migration. I'm going to do the first couple of things with you, so follow along, but the rest of the tasks, I might pause for a minute or two and let you do it. So what we just need to do is, we need to change the name to flash list, and I need to import it. All right. That's all. Change the name to flash list, and I'm going to go ahead and reload the application. Okay. And that's it. We have completed the first step to migration to flash list.

7. Observing Load Time and Optimizing Performance

Short description:

We observed the load time for the list and discovered that it took over one second to render. FlashList provided a suggestion to set the estimated item size to 279 pixels, which significantly improved the load time to 485 milliseconds, cutting it down by more than 50%. Specifying the estimated item size is crucial for optimizing performance. We then proceeded to repeat the process and recorded the JSFES of 2.9 under task 1.

What's the next thing that we want to do? What we now want to do is we want to observe the load time for this list. What's load time? Load time is the time that it takes for your items to actually become visible on the screen and flash list has a neat API that enables you to do that. So, I'll go ahead and do that. Of course I'm copy-pasting some code, but feel free to type it in.

So, this is the way you do it. You add an on load listener. It gives you an object from which you can select elapsed time in milliseconds and you can log it. So, let me just reload the app again and you'll see that we'll have a load time appear. All right. So, my load time for this list is 1319. Really huge. It's taking over one second to render. If you notice, Flash list is giving us a warning here. It's saying that estimated item size is not defined. And based on the current configuration, I can set it to 279 to optimize performance.

What does this mean? So, before rendering, Flash list usually has to make a guess on how many items it should start with. And in a lot of cases, that estimate can be wrong. In this particular case, it might think that each item is 100 pixels. But after rendering, as a developer, now I know that my items are on 279 pixels, and Flash list is giving me that suggestion. And I can provide this information to Flash list up front, and it can use it to optimize some of the things. So, let's go ahead and do that. What we'll do is, we'll have to do estimated item size, 279. Once I've done that, let me reload the application again. Let's wait for the load time to show up. All right. My load time is now 485 milliseconds. What happened here? FlashList was able to make a much better guess on how many items it requires in the beginning. That led to a smaller number of items being mounted. And, if you see, we have already cut down the load times by more than 50% just by specifying that estimated item size. It's extremely important that it's specified. We have seen estimated item size and its impact. Now, give me a quick thumbs up if you have been able to do this. Thumbs up. Done. Anything in the chat? Awesome. I'm seeing some things come up. That's great. All right. So, let's repeat what we did the first time. We are going to click Run Benchmark Together on the updated code and we'll record the numbers under task 1. Let me do it. All right. It's running for me. All right. It's all white. Okay. The JSFES is now just 2.9. Still pretty bad. I'm going to go ahead and guard it under my row. 2.9.

8. Observing Mount and Unmount Events

Short description:

Let's move on to task two. We want to observe the number of mount and unmount events in the tweet cell and tweet content. We'll use a code snippet and reload the application to observe the events. Once we have the data, we'll run the benchmark again. Remember to comment out the console.log to avoid performance impact.

Okay. I'm glad to see that a lot of you are able to get this done. Make sure that you are picking the average number and not the maximum or the minimum ones.

OK. All right, moving on to task two. Right, what we want to do is, as Merrick described, FlashList's goal is to reduce the number of items that are being created and destroyed. So how can we observe that? We can use the following code snippet inside our tweet cell and tweet content items.

And, all right, Mia, you can simply click on the link here and task one would already be done for you. And you can just start with task two if you were not able to finish it. But if you need a few extra minutes, go ahead and take that. All right. OK. So let's go ahead and do this. So first, I'm going to go to tweet cell and.

I'll use effect. And use effect. And I will return a function here. Which is going to take console log. They console at log. Tweet cell. I'm out. And we only want this to run only when the components and months I'll pass and empty dependency array. Very simple piece of code.

And same thing I will copy. And paste inside Tweet content. That's on line 72. And I'm going to change my console to Tweet content. And I'm going to import use effect. Go ahead and take your time. There's no rush. So I am done. I'm going to reload the application now. Give me a thumbs up if you have done this. Awesome. Great, great, great. Okay, okay, let's observe. I'll clear the existing logs. Let's see. I'm going to scroll manually, and okay. You see our tweet cell is unmounting all the time. Tweet content is also unmounted. A lot of unmount and mount events, and this is something that we want to really avoid. All right, so the idea of this particular task was to just observe how many mount and mounts we have, and then just run benchmark one more time. So let's do that. Make sure that you comment out the console.log, because it impacts performance. But we are going to go ahead and uncomment it in the next task. So I'm going to go comment console.log, reload the app, wait for it to load.

9. Console Log, Key Prop, and Flashlist

Short description:

Comment out console.log, reload app, run benchmark. Results may vary on low-end Android devices. Task 3: Removing keys assigned in Flashlist. Keys are often added in Flatlist, but in Flashlist, they can make a huge difference. Remove one key from primary render item in Twitter. Look for the other key in tweet content. Remove it. Reload application.

Make sure that you comment out the console.log, because it impacts performance. But we are going to go ahead and uncomment it in the next task. So I'm going to go comment console.log, reload the app, wait for it to load. So and let's run the benchmark again. Okay, for me the result is 8.9 FPS. Right? I believe it didn't do much for, you know, changing performance at all. Given that this is a low-end device, sometimes results can be a little bit flaky, and I believe that's what happened because I certainly didn't make any changes to improve anything. Okay. So let's capture those results. A lot of you are 41, 47, 44 already, 56. Yeah. I mean, iPhone 13 and iPhone 14 Pros, they have really solid single-core performance. That's why they can just brute-force their way through some of these performance issues. But there are a lot more visible on low-end Android devices, even mid-range Android devices. I think that's what the result is going to reflect. All right. I will move on to the next one once we are over 50 percent. Come on. Yeah, sometimes Snag doesn't reload. If you are suspicious, just trigger a reload either from the web console or by shaking the device and using the reload button. All right. Let's proceed. What's task 3? I wanted to quickly touch on the function of key prop and react. Whenever key prop basically maps your JS instance to an actual UI instance in the DOM, and whenever you change a key in React, it's going to recreate both the UI node and the JS node. This is specifically what we want to avoid in Flashlist. The next task is all about figuring out where these keys have been explicitly assigned, and we are going to remove them and see their impact on the mount and unmount operations happening. We have observed that in a lot of cases, when you're using Flatlist, you tend to add these keys, because it's not really impacted by it. It's destroying and recreating anyway, so having it or not having it does not make much difference. But as you will notice, in case of Flashlist, it can make a huge, huge difference. I'm going to remove one, and then I'll have you look for the other one. All right, so if you go to Twitter, you'll see that the primary render item has an explicit key defined. What we want to do is we want to go ahead and remove it. That's it. And we also want to go back to tweet cell and again uncomment our oncehold.log so that we can observe the unmount events again. So that was the first key. Go ahead and try and find the other key if it's defined anywhere. And let me know where it is in the chat. Could be in any of these components. I'll wait a minute and then we'll proceed. Okay, it looks like people have found where the, where the key is. Yes, it's inside tweet content. and it's on line number 78. If you see this, this, this key isn't even part of any map statement. This really isn't required unless somebody explicitly wanted to destroy and recreate this element. So we can go ahead, remove it. Let's reload the application. Okay, let it reload. Sometimes it takes a while even after it shows up yet. Now it actually reloaded. Okay, let me scroll.

10. Fixing Unmounting Issue and Running Benchmark

Short description:

The tweet content is still unmounting, but the tweet cell is no longer unmounting. This is because we removed the key prop defined on the tweet cell. We will solve the issue of tweet content unmounting soon. Let's remove the use effect for tracking unmounts and comment out the tweet content unmount. Then, we will run the benchmark again to check for any improvement.

Right. If you notice tweet content is still unmounting, but tweet cell is no longer unmounting at all. Like I don't see a single log in there. And the reason is because we removed the key prop that was defined on tweet cell. So the only problem we have right now is tweet content unmounting, and we'll figure out how to solve that very soon. So given tweet cell isn't unmounting anymore, I'm going to just go ahead and remove this use effect for tracking unmounts. And like we did last time I will comment out tweet content unmount, because it's going to interfere with our benchmarks. So comment that, reload, let's do it. And then we are going to run benchmark again and see if we have any improvement.

11. Benchmark Results and Task Four

Short description:

List loaded in 491 milliseconds. Some improvement, but still not great. Let's move on to task four.

Okay, let it reload. Okay, my list loaded, 491 milliseconds, give me a thumbs up if you're ready to run benchmark. Okay, nice, very nice. Let's do it. Oh, it's still going blank. If you notice my Moto G stylus goes totally blank in most of the runs. All right, 11.6. So in my case, I have a little bit improvement, but nothing major to really celebrate. It's still pretty bad, right? Go ahead, finish your benchmarks and then we'll move on to task four. This is where I think things are going to start getting interesting. Yeah.

12. Fixing Item Recycle Issue

Short description:

The items are repeating because they are not getting updated when they are recycled. This is not a problem in FlatList, but in FlashList, the current tweet remains the same when the item updates. We can fix this using the USE Effect hook. If currentTweet is not equal to tweet, we can call setCurrentTweet with a new tweet. After reloading, the issue should be fixed. Let's run the benchmark again and analyze the results.

Okay, we are over 50%. Okay, do you notice any issue with the list right now? Ever since we removed that key? If you already see the issue, you can comment. Okay, let me show you. Look at the top items. First tweet is by Chris, second is by Lorenzo. Yeah, somebody got it. The items are repeating. If I go back to the top again, the tweets changed. Why is this happening? This is happening because items are getting recycled and when they're getting recycled, they're not getting updated. I know this could also be because of which my performance improved. Because nothing is happening, items are already just moving. So I'll quickly show you what is going on and why this is a problem and how we can fix it and then we'll fix it together. If you noticed, to each cell, I told you right, that when you click one of the horizontal items, it changes the top level tweet. And this current tweet is maintained using a state, whenever that click happens, the state is updated. But when the item is actually getting recycled, the state is not changing, so current tweet is actually preserved and that's the whole problem. This is not a problem in FlatList because when it recreates the item, your current tweet is always equal to the incoming tweet. But here, when this item updates, current tweets still remains the same. So any ideas, anybody wants to quickly comment in the chat how we can fix it? Right. Perfect. Okay, it's our favorite hook, USE Effect. Let me show you how it can work. So this is the code snippet that we are going to use. So, what we need to do is, let's do it together. USE Effect. What we want to check is if currentTweet is not equal to tweet, we want to call setCurrentTweet with a new tweet, and we want to run this only if our tweet changes and not on any of those horizontal item clicks. So, the tweet will only change when FlashList reuses an existing component, and that's where we want to make sure that we are syncing the state. Feel free to copy this code snippet, use effect if currentTweet is not equal to tweet, setCurrentTweet, and format so that it looks clear. I will go ahead and reload. All right, it has reloaded. So my first two tweets are Aaron and by Gargley. And let me scroll. I'm not showing sure if I'm saying their names right, but forgive me. If I go back up, you see everything is all right now. There are no items repeating. Has everyone been able to fix the issue? Give me a thumbs up if it's fixed for you now. All right. Awesome, I'm glad to see everybody is able to keep up nice and easy. We were pretty apprehensive honestly in the beginning that is it too difficult? We even did like a trial run yesterday just to make sure that it's not too difficult. Okay, if everyone's ready, let's go ahead and run the benchmark again. And let's look at the results. We are adding another render. So it might actually slow down. Let's find out. In the meantime, can anybody tell me if this is perhaps not the best way to update the element and what can be the potential problem? Okay, if you see my numbers have actually decreased 6.6. Not seeing a whole lot of improvement. Okay. Oh, everybody is already beyond 50% with what I put in my numbers. That's so cool. I'm so glad to see this. Okay.

13. Migrating Horizontal List to FlashList

Short description:

Let's migrate the horizontal list to FlashList and look for bugs. After migrating, FlashList aggressively cuts down renders, resulting in the item not getting highlighted when clicked. We can solve this by using the extra data prop to ask FlashList to re-render when the current tweet changes. After reloading the app, the issue should be fixed, and the load time should be significantly reduced. Let's run the benchmark again to check the new performance numbers.

Okay, let's move on. Task number five. If you notice the horizontal list is also a flat list. So what we want to do is we want to migrate that to FlashList and we want to look at bugs. So go ahead and do it. Again, when you migrate, it's going to give you a suggestion for an estimated item size. I'm going to wait a minute to let everyone do it before I also go ahead and do it, all right. And then we'll discuss the bug and how we can fix it.

Okay, let's do 40 seconds. It shouldn't take much time and then I'll do it. Also try to find out or notice any bugs if there are any. All right, I'll also start doing it. Have to go to tweets cell. I'll change flat list to flash list. I need to import it, import flash list from that Shopify flash list. I am going to now reload. And hopefully it will give me a suggestion for my estimated item size because I don't want to guess it right now. Okay, I have a suggestion it's 352. Let me go ahead and add that estimated item size 352 and reload one more time. Anybody see any issue? A few items can repeat in the horizontal list because we are randomly generating that recommendations to it, but the repeating is not the problem.

Okay, I'll show you what the problem is. When you click on any of these items, the top tweet is going to change but the item itself is not going to get highlighted. Previously, you would see a light blue border show up. That's no longer happening, although it's functioning. So why is that? The reason for that is FlashList is extremely aggressive in cutting down renders. So instead of opting out of re-renders using use memo and things like that, you rather opt into re-rendering. So if your data has changed and your end item has changed, only in that case, FlashList does a complete re-render of items, otherwise it won't. So, and if you see our border color is dependent on whether the current, like the tweet displayed is the current tweet or not, and if this condition is true, the border changes. But in this case, FlashList is not going to re-render at all because the data has not changed when we click the item. So how do we solve this? We use the extra data prop, which is part of FlatList and FlashList both, and we can ask FlashList to also re-render if current tweet changes. Okay, I'm going to reload the app again, and once it's updates, this issue should be fixed. Okay, reload. All right. If you look at my load time is again reduced by almost 50%. Like I started out with 1.3 seconds, and it's not 238 milliseconds. It's an insane amount of improvement. But let's see if our bug is solved. All right, yeah. I can see the light blue border again. That's cool. Okay. All right, now let's go ahead and run the benchmark again and look at our new performance numbers at the end of task five, right? Now, it's looking better. It's looking a lot better. At least for me it is. Aha, 21.2. It's a pretty big improvement actually. It's very likely that folks with iPhones are already hitting the 60 top line at this point. Okay. That was it. Before I move on, I'll also quickly go ahead and you don't have to do this, you can just observe it with me.

14. Fixing Unmounting Issue and Reducing Unmounts

Short description:

I will uncomment the console.log and reload the application to see if the tweet content still unmounts. If it does, we'll investigate further. We'll look into the code to understand why unmounts are still happening. By checking the condition in the tweet cell, we can determine if the flash list is being entered. We have a fixed logic to decide whether to show related tweets based on the retweet count. We'll use the getItemType code snippet to inform Flashlist about the type of items and reduce the number of unmounts. After reloading and observing, we can see that there are no repeated unmount events.

I will uncomment this console.log and reload the application again. And you'll see that the tweet content will no longer unmount because we have moved to FlashList. All right. For unmounts, these are the previous items. Let me get rid of the logs. I'm going to now scroll, right. Oh God, it's still unmounting. That's weird. Okay. Right, what might be happening? Okay, let's reload one more time. Maybe there's still something wrong. No. All right, reload it again. Let's see. Okay, there are a few unmounts happening, which is okay. We'll figure out why that's the case. All right. Right. So to itself, we have okay. Let's move on to task number six.

Get item, type. What is get item type? This is the final piece of the puzzle, if I put it that way. If you notice, the unmounts are still happening because we might choose the wrong base to recycle items. For example, this particular tweet has no related tweets. And it might get recycled and reused to render a tweet which has related tweets. And what that means is we are going to see a lot of mount events as part of that. And vice versa, if I use this tweet, which has related tweets to render something that does not have those related tweets, all of those related tweets which we rendered before go to waste. Let's look at the code to understand why this happens. Inside tweet cell on line number 34, you'll see a check where I'm checking if recommendations.length is greater than zero, only then we are entering the flash list. So if this condition is mismatched with the request, mismatching between items, we can run into that issue. But we already have a fixed logic to decide whether or not we are going to show related tweets which is basically this. This is where we are checking if tweet.retweetcount is greater than two. We generate some related tweets and we show it to the user. What if we tell flash list that we are doing something like this? And flash list has a way in which you can do that. All right, so how does this work? So this is the code snipper that we are going to use. Get item type, you can go to your top level Twitter element and add this code. What's the code? Get item type, you are going to get an item. And if the item.retweet count is greater than two, we tell Flashlist that this is like a RT type element, which is like short for recommended tweets or related tweets. If the retweet count is less than or equal to two, we return T. So this way Flashlist can now figure out internally what items it should use to recycle what kind of items. And this is going to reduce the number of unmounts that we are seeing even more. Here, let me reload. My console.log is already uncommented, as you can see here, we will observe if we are still seeing any unmounts. Yeah. All right. Everything is loaded, let me scroll. Yeah, some unmount, two unmount. Flash to scan unmount a few things based on number of factors that it doesn't need. But on even scrolling quite a lot, right? You can see we are not getting repeated unmount events at all. Right, I'll give you a minute to do this.

15. Optimizing State Updates with Refs

Short description:

Unmounts are gone, UseEffect can be removed. Run the benchmark to see improved numbers. Discussing an alternate way to update states and avoid extra renders. Create a ref source to track the source tweet. Check if the source tweet is equal to the tweet passed by Flashlist. If not, capture a copy in the ref and call set current in the same render call. This method is faster than using UseEffect.

And give me a thumbs up once you also don't see any unmount. Did someone scan my QR code? I saw an iPhone. I saw iPhone log. Awesome, I think some of you have already been able to do it. But yeah, unmounts are totally gone. That's awesome, and that's what we set out to do in the beginning. I'll actually go ahead and get rid of this UseEffect because nothing is unmounted so I don't need it. I'm going to reload one more time. Whoever has connected to my snack, your app will also reload. Okay, let's see. Okay. Okay. Awesome. Let's do it again. Let's run the benchmark and see the new numbers. It's looking a lot better. Most excited to see what the new number is going to look like. And remember, my iPhone is also recording. 32.4. 32.4 for me. 32.4. 34. And see, even if you don't have a low-end device right now, the material is all there, the snack is there, so you can, in the future, load the starting snack on a low-end device and then try the final one to figure out how much of an improvement you can expect. But yeah, like on an iPhone, you would have already hit the ceiling right now. So because the JS render is not going to capture anything more than 60 FPS for now. A lot of people might be at 60 FPS, honestly, at this point, but there's one more task left. It's not over. Okay. What's, if you remember, in one of the tasks, we added a use effect. And this is something that I wanted to touch on exclusively, because usually people add use effects to update their states and sync it with external data. But there's an alternate way where you can avoid the extra render. Our current setup, if I go back to the code, this use effect is going to be called after we have done one update, and then it's going to check this condition called set state, which means that the item is going to render two times. And some of these items have these nested horizontal lists which are super expensive to render. So, we definitely don't want to do it twice. So, let's see if we can do it just once and how to do that. Okay. So, the code snippet is in front of you. Let me do it and you can follow along. What I can do is, I can create this ref source to it to track what my source to it is, right? Which is coming from, let's say, Flashlist. I made a copy of it. Instead of use effect, I am now going to in the same same render loop, or render path. I'm going to check if my source tweet was equal to the tweet that is now passed by Flashlist. If it isn't, we capture the copy of it in the ref and we call set current to it in the same render call. What this does is, so in this particular case, let's say I talk about tweet content, so the render method of tweet cell, our current component is going to get called twice, but the render of tweet content is going to be called once. So it's like two renders, but below that tree it's just one render. So Flashlist is also going to get rendered just once. So if you do it this way, there are of course multiple ways of doing it, and React has this documented on how this works and why this is better than using UseEffect. But for Flashlist, we strongly recommend that if you have states, you sync them using this method because this is much faster than using UseEffect. Again, the improvements depend upon your particular component, but as you'll see in this case, it's going to make a difference. Yeah, let me reload.

16. Observing Draw Distance and Final Results

Short description:

Let's observe if the repeat element bug still exists. Change the draw distance prop in FlashList to improve performance. Reload the application and run the final benchmark. The results show significant improvements in JSFPS, especially on Android devices. Even on iPhones, FlashList consumes less CPU compared to FlatList. Battery life and device temperature are also improved. Let's take a quick look at the results. The coding part of the workshop is now complete. We have seen remarkable performance improvements with FlashList. There is one more interesting thing to explore: JSThread.

And we're also just going to observe if we still see those repeat element bug or not. Okay, it has reloaded, let me scroll a little bit. Let me come back. Right, everything is looking good. Yeah. Give me a thumbs up if you were able to do this. Awesome, awesome. Okay, we are not going to run benchmark just yet. There's one more thing. Okay, draw distance. Many of you would be familiar with the window size prop in FlatList. FlashList also has a prop, it's called draw distance in this case. You can change this prop to a smaller, like by default, FlashList only draws 150 pixels ahead while FlatList draws 10 times of your viewport ahead of time. So FlashList draws a miniscule number of items compared to FlatList. But in case of horizontal list, you do not even need 250 pixels ahead of time draw. At least, you know, in this particular example, the item is pretty big, so I can probably just go ahead and change draw distance also. I'm going to make it zero. You can also choose not to do it, like even without it, we'll see a lot of improvement, but let's do it because we know that we don't really need to. And in case of FlashList, setting it to zero is not going to lead to any huge functional problems. Like in case of FlatList, I know in some cases when you change initial number to render or Windows size, you run into issues. Items do not load, but it's really a no compromise thing in this particular case. Right? If you are done with setting draw distance of the internal list, reload the application, and we are going to do the final run. Right, just 200 milliseconds load time. Okay, let's do it. Okay, it's looking pretty good. Don't even see blank spaces anymore. Okay, come on, come on, come on. 50.6, 50.6 for me. Okay, 50.6. Zach's results are pretty interesting. He started with 60 FPS. Still at 60 FPS. All right. So that's draw distance. I think we have, we have, and you know that brings us to the end of the actual coding part of the workshop. Let's quickly look at the results. So in my case, if you see I started at 1.7 FPS on a low-end device. Zach, it's okay. And my final number was 50.6. So I actually increased my JSFPS to 40, like by 48.9 FPS, and that constitutes to like 29 times improvement in JSFPS, right? And if I look at some of the iPhones we saw, see, interesting thing to note here is even on iPhone, if you're just seeing 1.2X improvement, flashless will actually be consuming very small amount of CPU compared to the flat list. So like brute forcing is possible, but you are burning through a lot, lot of energy and battery, your device is going to warm up, things like that. So you will still see battery improvements and devices are going to remain cool, even on iOS, but on Android, it's like night and day. I can already see, you know, KB getting close to 16 times improvements before the numbers was 7.2. Now the increase to 116 FPS, that's like almost 120 FPS. What are the other big numbers? Okay, iPhone 11 Pro going from 8.8 to 60, that's like almost six times increase. So on latest iPhones, we do expect you to see around 1.8 to 1.2 times improvement. But if you observe the CPU usage, it's going to show a similar trend as what you're seeing on Android. All right, all right. Since I have two more minutes before I finish, I would want to show you one more thing that's pretty interesting. So we have been looking at JSThread till now.

QnA

UIThread Performance and Q&A

Short description:

Flash reduces the burden on UiThread. Frame drops and freezing UI threads are common with FlatList. FlashList, even with recording, maintains a high FPS and avoids freezing UI threads. Dynamic heights are no problem with FlashList. No questions, but dynamic heights are supported. Share thoughts or comments.

What about UiThread? Because flash is actually reduces burden on your UiThread even more. So I can do that. So on my Android device, I'm going to go to Settings, Developer Options, sorry wrong option. I do this all the time. If I scroll down, there's something called as Profile Hardware UiRendering on Screen as Bars. Okay, going back to Expo. So first I launch what we started with our original sample. So this is with FlatList, both vertical and horizontal. Let me reload. So every time you see these bars going above the red line, that's a frame drop, and the longer it is, the worse it is. Let me run the benchmark and see how it goes, okay. Lot of tall bars. Lot of tall bars, and it's pausing because jsthread is not able to keep up and is not able to even issue instructions for drawing. But maybe while coming back, it's going to be better. All right. 1.7 again, and you see these huge frame spikes. And this is where your UI is also gonna freeze, not just blank, actually freeze. Okay. Let's go to our FlashList sample with everything done and fixed. Yeah, let me reload. I just reload all the time just to be safe. Okay. Let me run it, and, okay. All right. Even with the recording, you'll see that we remain below 60 FPS for quite some time. Of course, we are dropping frames because it's a low-end device, and we are also recording or mirroring. But yeah, if that's not the case, then it's honestly possible, even on this device, if I disconnect from mirroring, it'll do 60 FPS. And you do not have a single huge spike freezing your UI thread at all. So that was quickly some notes on UI thread performance. I'm going to quickly go and disable that. Right. So that brings us to the end of the coding part. David, do you want to run through any questions if you have any? Yeah, I was just remembering the chat so I have this slider. But in case that you want to, go ahead and raise your hand here if you want to do the questions here. I see no questions there. I see one question in the Q&A here. But I think everyone- I think you were coding so- Yeah, it's difficult to go to a separate, because it was extremely fast-paced. But yeah, go ahead, raise your hand, we will unmute you and you can ask your question. Or you can type it in the chat. Okay, what was it? It's the question from Juan that says, can the items have different sizes? I think we answered that in the presentation. Yeah, if you look at this already, right? The items are of different size. Right? Flashlist does not ask you anywhere, and this is one item, like this tweet and the horizontal tweet is actually one item. Because we are rendering it inside to itself. And Flashlist did not ask you for different estimates or fixed sizes anywhere, but it still works very well. So dynamic heights are no problem at all. Yay. Cool, if you want to share your thoughts or comments, go ahead, you can also do that if you do not have any questions. Yay. Thumbs up if you actually do not have questions. Okay.

Audience Feedback and Performance Gains

Short description:

Either we did something really good or really bad. The more complex your list, the more gains you're going to see. On our website, we claim up to 10X performance improvement.

Either we did something really good or really bad. Maybe I can ask a question like for the audience, like how many of you know about Flashlist before this workshop or how many have you tried before joining the workshop? Maybe just give a thumbs up as well if you tried in the past, or now it's first time that you see it. Nice. All right. I see Zain mentioned that are going to get back to React Native from Flutter after this workshop. That's a win. Yeah, and folks, see, the more complex your list, the more gains you're going to see. On our website, we actually claim up to 10 X, but you can easily go over that if your items are complex enough.

Watch more workshops on topic

React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Featured WorkshopFree
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
React Advanced Conference 2021React Advanced Conference 2021
132 min
Concurrent Rendering Adventures in React 18
Top Content
Featured WorkshopFree
With the release of React 18 we finally get the long awaited concurrent rendering. But how is that going to affect your application? What are the benefits of concurrent rendering in React? What do you need to do to switch to concurrent rendering when you upgrade to React 18? And what if you don’t want or can’t use concurrent rendering yet?

There are some behavior changes you need to be aware of! In this workshop we will cover all of those subjects and more.

Join me with your laptop in this interactive workshop. You will see how easy it is to switch to concurrent rendering in your React application. You will learn all about concurrent rendering, SuspenseList, the startTransition API and more.
React Summit Remote Edition 2021React Summit Remote Edition 2021
177 min
React Hooks Tips Only the Pros Know
Top Content
Featured Workshop
The addition of the hooks API to React was quite a major change. Before hooks most components had to be class based. Now, with hooks, these are often much simpler functional components. Hooks can be really simple to use. Almost deceptively simple. Because there are still plenty of ways you can mess up with hooks. And it often turns out there are many ways where you can improve your components a better understanding of how each React hook can be used.You will learn all about the pros and cons of the various hooks. You will learn when to use useState() versus useReducer(). We will look at using useContext() efficiently. You will see when to use useLayoutEffect() and when useEffect() is better.
React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
React Advanced Conference 2021React Advanced Conference 2021
145 min
Web3 Workshop - Building Your First Dapp
Top Content
Featured WorkshopFree
In this workshop, you'll learn how to build your first full stack dapp on the Ethereum blockchain, reading and writing data to the network, and connecting a front end application to the contract you've deployed. By the end of the workshop, you'll understand how to set up a full stack development environment, run a local node, and interact with any smart contract using React, HardHat, and Ethers.js.
React Summit 2023React Summit 2023
151 min
Designing Effective Tests With React Testing Library
Featured Workshop
React Testing Library is a great framework for React component tests because there are a lot of questions it answers for you, so you don’t need to worry about those questions. But that doesn’t mean testing is easy. There are still a lot of questions you have to figure out for yourself: How many component tests should you write vs end-to-end tests or lower-level unit tests? How can you test a certain line of code that is tricky to test? And what in the world are you supposed to do about that persistent act() warning?
In this three-hour workshop we’ll introduce React Testing Library along with a mental model for how to think about designing your component tests. This mental model will help you see how to test each bit of logic, whether or not to mock dependencies, and will help improve the design of your components. You’ll walk away with the tools, techniques, and principles you need to implement low-cost, high-value component tests.
Table of contents- The different kinds of React application tests, and where component tests fit in- A mental model for thinking about the inputs and outputs of the components you test- Options for selecting DOM elements to verify and interact with them- The value of mocks and why they shouldn’t be avoided- The challenges with asynchrony in RTL tests and how to handle them
Prerequisites- Familiarity with building applications with React- Basic experience writing automated tests with Jest or another unit testing framework- You do not need any experience with React Testing Library- Machine setup: Node LTS, Yarn

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Advanced Conference 2022React Advanced Conference 2022
25 min
A Guide to React Rendering Behavior
Top Content
React is a library for "rendering" UI from components, but many users find themselves confused about how React rendering actually works. What do terms like "rendering", "reconciliation", "Fibers", and "committing" actually mean? When do renders happen? How does Context affect rendering, and how do libraries like Redux cause updates? In this talk, we'll clear up the confusion and provide a solid foundation for understanding when, why, and how React renders. We'll look at: - What "rendering" actually is - How React queues renders and the standard rendering behavior - How keys and component types are used in rendering - Techniques for optimizing render performance - How context usage affects rendering behavior| - How external libraries tie into React rendering
React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Building Better Websites with Remix
Top Content
Remix is a new web framework from the creators of React Router that helps you build better, faster websites through a solid understanding of web fundamentals. Remix takes care of the heavy lifting like server rendering, code splitting, prefetching, and navigation and leaves you with the fun part: building something awesome!
React Advanced Conference 2023React Advanced Conference 2023
33 min
React Compiler - Understanding Idiomatic React (React Forget)
React provides a contract to developers- uphold certain rules, and React can efficiently and correctly update the UI. In this talk we'll explore these rules in depth, understanding the reasoning behind them and how they unlock new directions such as automatic memoization. 
React Advanced Conference 2022React Advanced Conference 2022
30 min
Using useEffect Effectively
Top Content
Can useEffect affect your codebase negatively? From fetching data to fighting with imperative APIs, side effects are one of the biggest sources of frustration in web app development. And let’s be honest, putting everything in useEffect hooks doesn’t help much. In this talk, we'll demystify the useEffect hook and get a better understanding of when (and when not) to use it, as well as discover how declarative effects can make effect management more maintainable in even the most complex React apps.
React Summit 2022React Summit 2022
20 min
Routing in React 18 and Beyond
Top Content
Concurrent React and Server Components are changing the way we think about routing, rendering, and fetching in web applications. Next.js recently shared part of its vision to help developers adopt these new React features and take advantage of the benefits they unlock.In this talk, we’ll explore the past, present and future of routing in front-end applications and discuss how new features in React and Next.js can help us architect more performant and feature-rich applications.
React Advanced Conference 2021React Advanced Conference 2021
27 min
(Easier) Interactive Data Visualization in React
Top Content
If you’re building a dashboard, analytics platform, or any web app where you need to give your users insight into their data, you need beautiful, custom, interactive data visualizations in your React app. But building visualizations hand with a low-level library like D3 can be a huge headache, involving lots of wheel-reinventing. In this talk, we’ll see how data viz development can get so much easier thanks to tools like Plot, a high-level dataviz library for quick & easy charting, and Observable, a reactive dataviz prototyping environment, both from the creator of D3. Through live coding examples we’ll explore how React refs let us delegate DOM manipulation for our data visualizations, and how Observable’s embedding functionality lets us easily repurpose community-built visualizations for our own data & use cases. By the end of this talk we’ll know how to get a beautiful, customized, interactive data visualization into our apps with a fraction of the time & effort!