Code Splitting with React, React.lazy, and React Router v5

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
whenever you're talking about the performance of an application making broad generalizations probably isn't the best idea just because it's so specific to the application itself with that said i'm going to make a broad generalization there's probably not something that will affect the performance of your application more and will be relatively simple than adding code splitting to your application what exactly is code splitting well the idea here is pretty simple don't download code until the user needs it for example say we had a really heavy registration flow if the user has already registered prior and they're just on the home screen it doesn't make sense for them to have to download all of that registration code if they'll never use it so that sounds great but now the question is how do we actually do it well if you're familiar with es modules you'll know that they're completely static what that means is you must specify what you're importing and what you're exporting at compile time not run time this also means that you can't dynamically import a module based on some condition as we're doing here if we were to try to do this what we'd get is an error saying import and export may only appear at the top level so now for a thought experiment what if import didn't have to be static what benefits would that actually give us well first it would allow us to import certain modules on demand that seems pretty nice and it would allow us to get closer to the vision of only downloading code when the user needs it so an example of that might be something like this where if we can assume that edit post is going to be pretty heavy and pretty large we only want to download that code if in this example edit post equals true so we can pretend the user clicked on edit post and then we went and downloaded all of that code to allow them to edit the post so again that sounds good but we've already talked about how this code is completely invalid well here's the good news this code does exist it's supported by create react app by default and it's currently stage four of the ecmascript process which means it will be in the official specification very soon what it looks like is this where now import can be used as if it were a function what we pass it is a single argument that is a string which references our file or our module that we want to download that's going to return us a promise and when that promise resolves we'll have the module that we can then do anything with so that's pretty cool we can now dynamically import modules only when the user needs them so now what we need to do is take this knowledge of dynamic imports and apply it to building a react and react router application this is where react.lazy comes into play put simply react.lazy lets you render a dynamic import as a regular component so instead of importing a component like this what it would look like is this invoke react.lazy passing it a function that function is going to return us the invocation of our dynamic import which will be a promise and now just like up here settings is a component because we use react.lazy that's going to allow us to render a dynamic import as a regular component inside of our component tree so let's take a look at some code so we can see how this actually works so here we have a pretty typical react application we have a few components home topics settings and tweets we have some links and then we have our routes to map the user's current location to our individual components if we were to look at this code what we'll see is home and topics are pretty straightforward they just render the text home or topics tweets it's a little heavier we have this little widget right here which is rendering all of my recent tweets we have a button to follow me and then we have some of my favorite tweets down here and then settings is going to look like there's not much here but there's actually a very large and heavy text editor right here so the idea and what we want to do is make it so if the user doesn't visit the tweets page the tweets route they shouldn't have to download all of the code for rendering all of those tweets and along with that the user shouldn't have to download all of the settings code until they visit settings so using dynamic import and using react.lazy we want to code split our application and before we do that what i'm going to do just so we can see the before and after difference i'm going to run over here and run npm run build what this is going to do because this app was built with create react app we can do this this is going to give us all of the different files we need to deploy our application so we have four files here two main files and one chunk what we'll see when we code split our app is instead of all of our code living in just these specifically these three files and more specifically really these two files because this one's just a runtime file once we code split we're going to see a lot more chunks and that way the browser only has to download the correct chunk rather than the one very large chunk right now we have uh two very big ones so let's go ahead and code split these so we'll do and i'm going to do this all in one go by using command d i'm gonna copy all of this and change that to const these are going to be equal signs and then we're going to do react.lazy we need to pass react.lazy a function that then will invoke or use dynamic imports just like that so now we have all of what appears to be our components they're really the result of invoking react.lazy though and now you might think this is just going to work but what you'll see here is if i save this and we restart our dev server you'll see that we have an error here saying a react component suspended while rendering but no fallback ui was specified so what we need to do as it says right here is anywhere where we are using a component created with react.lazy we have to wrap r where we have to wrap them inside of react.suspense indent all of this and we also need to pass react suspense a fallback that it can call as it's downloading the specific modules so we'll just say loading so now what we'll see is our app is going to behave the exact same so we have our profile we have our settings from a user perspective everything is the same but if we come over here and we run npm run build again instead of our code just being in one or two of these javascript files we've now split those out into all of their different chunks so again for example let's say this first one was our settings page the user wouldn't have to download this code until they actually went to slash settings to recap all you need to do to split your app and there's kind of a debate between splitting your app at the route level and splitting it just wherever you have heavy code it's easy for our example just to split at the route level because that's kind of the natural splitting point and that's what we did in this video so to do that what we did is we can actually go back to see this instead of just importing our code like this what we did was we invoked react.lazy passing it a function which will eventually resolve with our module using dynamic imports we save the value of that to different variables obviously these are now components that we can render inside of our application but we need to make sure that we wrap those inside of react.spence suspense giving it a fallback problem
Info
Channel: uidotdev
Views: 9,790
Rating: 5 out of 5
Keywords:
Id: 0mQbxF-_S-M
Channel Id: undefined
Length: 7min 52sec (472 seconds)
Published: Mon Nov 02 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.