Moving To React Suspense - Jared Palmer - React Conf 2018

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] [Applause] [Music] all right so the goal of this talk today is to figure out what you're gonna do on Monday so you're gonna rewrite your whole app with hooks probably right like that's like thing one like just everything's got to go you know and every single thing also needs to be with suspense cuz it has to be used but no we're actually the goal of my talk today is to convince you not to rewrite your app and over the course of the next 30 minutes or so I'm gonna show how you're gonna incrementally approach the next probably week or two or you know a couple months of your job by using suspense to enhance the way your application not only loads modules but also assets and eventually data so but about me Jared Palmer at Jared Palmer on Twitter I am a lead engineer at the Palmer group we are a strategy design and engineering firm based in New York we help large businesses enterprise with mostly digital transformation in doing all of that I actually pump out a lot of open source stuff - you may be familiar with some of my libraries maybe you use them for mix form library for react Razzles for server-side rendering react FNS is a handful of render props and high order components for mostly wrapping web in web api's backpack is for node like lambdas and backends and such we're going to react definis a little bit later because it kind of will come back and apply but back to the moment we all been waiting for the topic of discussion loading stuff is hard how many people write the word is loading like more than 10 times a day right like I just keep writing this word it's just like that movie with number 23 I just keep seeing it yeah so loading stuffs hard and if you think about your applications a lot of time and energy is focused on just coordinating through this like stuff when it comes in when it comes out what to show the user would not to show the user and ultimately what ends up happening is you have some great applications an idea and you read on Twitter like I need to make it so fast and so amazing I need to minimize everything I need to optimize performance she make it fast and to do that you defer non-critical resources what does that mean so you're gonna may be lazy load your bundle you're gonna split out data into just component parts all over your screen and you're gonna make sure that your users like get to your app the good stuff as fast as possible but in doing so you've introduced this conflict because you end up having all these loading indicators that Andrew just showed off and how those can kind of actually be detrimental to user experience so suspense can help us there and so what I'm gonna do now is show you a little application I built a little application I built it's called suspense off' i and yeah so it's Drake and Big Sean and Ken wheeler so okay so it's built with create react app it uses good old local local set state no redux no Apollo no no relay you just reach router again I was trying make this fast right so I implemented code splitting on my own I'll go into that in a second it's got a home page and it's got an artist page and you saw those spinners already right we're gonna get there in a little bit but you can you know play awesome music like the sick Drake track like just the best most of me there's copyright issues so I had to go with the Mozart just this awesome just bumping right now unreal okay so tonight off but no it plays music it's got some albums cool but it's got tons of loading spinner so let's do that again right so this is like on a decent connection right but if we actually like slow things down and I stole this widget shamelessly from I think Dan maybe wrote it all right slow this things down a lot so often times we want to make our apps responsive on slow connections so we have all these loadings indicators right and that's great because the Miss situation like that you want to give the user some feedback that like the app still like working because nothing's worse than seeing nothing right but on like superfast connections this gets pretty janky just like Andrew showed right like we don't better just that's again since instantaneous so suspense can help us there so let's get to it so the goal this is to show it like basically build an app that would be probably similar to the apps that you're going to you know that you all build and take you through how you can move to suspense and how you can incremental e adopt this again everything's opt-in you don't have to do this only do this if it makes sense and you'll find situations where maybe you don't want to because it's not really worth it so step one we need to enable something called strict mode and make sure that our application passes strict mode and what strict mode is is a little wrapper that you can throw at the top of your application to just make sure that you're not using any deprecated API s so we're just going to wrap our app in react strict mode and you can actually do this in prod in production and there's no downside strict mode okay so just pull up the console here and it looks like we have a little error so this error is because we're using a deprecated lifecycle and we're using that deprecated lifecycle in our little code split component so this code split component I wrote and what it does is it takes a function that utilizes web packs dynamic import it's got that functions got a return I promise that resolves to a component it stores that component if that component exists it just renders it immediately but this doesn't stop all happens in will mount which has been deprecated so we're shouldn't read this message and listen to it we're gonna move to did mount said will mount was gonna block the render okay so we fixed that so we click around our application and we're good no more errors no more warnings or to say so cool so we are we're in business where we've we've done sort of step 0 here so we can remove this and Andrew showed that you don't actually you can start using suspense without enabling concurrent react but for the purposes of this demo let's and - in order to allow react to actually take advantage of that like in order for react to actually wait and pause rendering we need to enable concurrent mode so let's do that now so we're all familiar with react render that's how we mount our applications to the Dom so there's a new way to do that though with concurrent react and that's called create route so it's kind of similar a little different so we're just gonna react dot create react down to create route and write pass it a Dom node and then we're gonna call dot render and we're gonna pass in our app alright and look at that nothing changed it's like a big deal right like you just enable concur and react that's awesome okay so we're still have spinners remember this is all incremental so now that we're in concurrent react we're going to take a note from Andrew and go into our app component and we're going to basically wrap the whole thing oops we're gonna wrap the whole thing in react suspense react down suspense and this is gonna take a fall back and we're gonna make a big winner here spinner Booya auto import okay let's go back to the top here okay so had this codes like a component thing but I don't need any more cuz now react as react not lazy so let's just like lose this so it's gonna be really weird about this live coding demos I think I'm about to delete more code I'm actually going to write so actually excite all of you cuz deleting code is great all right so let's let's get rid of this I'm just gonna do react lazy here and with react lazy before I was like taking out like manually grabbing the default export from my web pack dynamic import that's this right here but react out lazy expects that anyway so I can just go ahead and delete that too okay so now I want to show you that the chunks are still loading some I go to the network tab and I'm gonna refresh the page and if we scroll back up to the top here let's see we scroll back up to the top we saw someone there G there let's see we keep going that's the it's the homepage chunk if we go back to the artist page we don't load another chunk and that's because it's cached now so that's react not lazy and suspense pretty cool so we're ER we're moving along so as I said the first thing you're probably gonna do is take care of deferring modules and using react lazy but the second thing you can do is use suspense for assets so images video audio script tags style sheets of thoughts yeah fonts so it's cool because you can pause rendering and coordinate really challenging or otherwise difficult loading States so let's take a look at the our artists page here we're gonna concentrate on on this for a second here so our artist page it's lit up in two three three three components it's got the details which is up here it's got top tracks and it's got albums and each one of these is your classic data component responsible for data it's got some state and did mount it fetches some stuff it sets as loading it's got some logic this guy shows a spinner if it's loading and then it shows the thing and that's cool so in this artist header we have this image here and on fast connections it's totally fine it's pretty clear and this little API built actually has multiple versions of every image so on fast connections is great our users on you know a MacBook Pro our users get really high res photos but if we were to be in a slow Network it would be less than ideal so let's go to our network tab here and let's take this down I'm just gonna put this on to like even fast 3G let's go back for a second here yeah that's not great the way those images are uh not good makes me sad so now to rezone the MacBook Pro and so it'd be better if we could show something some sort of version of the image that maybe was optimized for bad connections so one technique that's pretty popular is to use something a low quality image placeholder and the idea there is you take a smaller version of the same image and you load that as fast as possible and in the background you load the high-res version and then when if the high-res version is ready you swap it in that's pretty cool normally you would have to do that every single time and what I mean by that is it's it's basically like it's still loading this little spinner writes a little concept of a loading State to have that low-quality version and then flip it in but with suspense what you can do is you can add a suspense component where I'll do this in a second and you can let react figure out whether or not it should stop what it's doing and wait until that high-res version has been downloaded and then just show the high-rez version or if it should fall back and that leads to as you're about to see a pretty great user experience and also developer experience so let's do that so the API for that is we're gonna create a resource from react cache and react cache as you just heard from andrew is a new package it's a basic cache from that's gonna store basically anything that's asynchronous that can resolve to a value or a thing and then what it allow us to do is it can allow us to access that in a synchronous manner so we're gonna create an image resource with our cache and this is gonna take an input it's gonna be a source and it's going to return a promise and in that promise we're gonna do is we're gonna make an image and then we're gonna sign it its source and when the image loads we're gonna resolve the promise resolved okay cool so now back down here and our artists header we're gonna wrap this little area in suspense I'll call this react dot suspense just leave that for a second I'm not gonna press save just yet okay just render image but we're gonna what we're gonna do is we're actually gonna make this image component kind of like suspense off' I'd and the way we're gonna do that is is we're gonna make a new kind of image component with a capital I and this is gonna take the same props is a normal lowercase image components as we source all just props there and then what's gonna happen is we're gonna read from the cache image resource that read source and we're just going to return a lowercase I image spread props here so what's gonna happen here is when this uppercase image capitalized image when it renders and it gets to this part right here this image resource number when I said like you can access stuff synchronously that's a sync so that's what's gonna happen here what's gonna happen here is the image resource that read call is gonna find the nearest suspence ancestor its parent and it's gonna reactions gonna pause at that parent and then make a decision either render the fallback and continue down the tree or it's going to wait long enough for that data or whatever the value that's going to resolve from the cache is and waits for it and then it will provide it back to its children or to you as a this could be like you could return it so it could be like image itself so we're gonna do now is we're gonna use capital i image and lower case image this is a little strange so as the fall back of our suspense component we're gonna put the image but we're gonna put the smallest version of it the low-quality version and then we're gonna use the same version of it the same component but with a capital i to be the high res version and I made some CSS to make this more obvious so this will be preview and this will be loaded okay so that was it on a fast connection it just the opacity animates in on a slow connection and let's prove it even more on a slow connection what you're gonna see is this comes in and you'll see hopefully there we go so you'll see it's swap so you'll see the low-quality version go and then the high-quality if it version go there you go so you see down here you have the the avatar is the high-res version or they and the sorry the high-res version the HD and the can you see that yeah you could see that and so that and that's and that's the low quality and then the high quality so there you go but to really like control this you can set a max duration and let's just say that with max duration the what you can do there as you can tell suspense to basically the maximum amount of time that you're likely to wait before rendering for the fallback so let's set that at like I don't know 500 milliseconds okay cool how much just do it again let's see if we can show there it is okay there it is so with max duration we can force it in there alrighty cool so that's great because I'm slow connections our users see something but on fast connections it's just exactly what you want it's the high-res version so we can go about doing that in a couple of places in our application right and my team has sort of been playing with us for a little while and just speed things up we like started going through all the different kinds of elements that you'd want to suspense if I and so image is one of them script is one of them we sort of collect them all together in something that we're gonna call the form so you MPI npm install the platform and it's crazy all these people from google love it it's like this really weird I don't know they already know about it it's it's awesome but um yeah so there's image there's script there's video audio and all these components are like react suspense ready and so we're just gonna use them use the image again it's the same exact thing we just wrote so let's go back here and let's use image import image I love this from the platform so you don't have to use this this is just but you know I encourage you just write them on your own but get lazy whatever so an album grid same trick just use react dot suspense set a max duration 500 here and the fallback and we'll just copy this image again do the same exact trick one more time just low and the high and we'll do a loaded and preview all right there we go now our albums come in there too so we're moving right like we're moving we're making our app better and that's sort of the point there so what's so that's this that's the second part of like I guess your movement to suspense will be assets and I said as I mentioned you can do this with audio you can do this with video you can do this with fonts but you also do there's data and I will say that the data story isn't quite complete yet with react cache but it's going to get there so it's pretty experimental so use with caution it's likely that if you're using an Apollo or a relay this is gonna be abstracted away for you so you won't need to worry about it but we're gonna clean this up and just show you how it might work so artists albums we still have this these spinners right and we're just talking about how like those aren't great and we still this loading state with suspense as Andrew showed and I'm about to show you can kind of get rid of that in all this code that in a pretty nice way with the react cache so we're gonna import unstable create resource from react cache and we're gonna create a artists albums resource and this is just gonna be this little fetch here because it's the identity function we don't eat it to pass anything we'll just do that and now we can delete all this and we can delete this too and we can delete at and we can delete that okay and now instead we can replace with albums actually you know what we can even delete that you know we can do artists albums resource dot read this stuff props tidy so all the albums just came in first no loading indicator we're in business there they are so what's cool about that is let's finish those out so they're in the cache already right so when I just did that again so let's do that again they're in the cache so once they're in the cache and this is one of the things that's kind of experimental their cache so if I come back to this page let's allow any requests here if I come back to this page I go back and forth here one more time the album is already ready so as you as your user goes around your application things will just survive in the cache and those will be like the images also are going to be in the cache so if they're on a really slow connection the images are gonna get cache because we just did our like image resource and the our JSON data is gonna get cached so if we went through the rest of the application and removed all this code we'd have a pretty awesome experience right so as soon as the user downloads something they're they're gonna keep it but one of the things that react cache story is not quite finished yet is with like invalidation and such but it's getting there so it's still pretty experimental so use with caution but it is a glimpse into the future I think so I hope the the goal here was to show you a sort of realistic application and show you how to how you might approach moving to suspense and some situations where you can apply it literally on Monday so let's go back to our slides real quick so the benefits of suspense that I see are a feels sync so when you create a resource and you read from your read from the cache it reads top to bottom and with JavaScript that's kind of like a rare thing so together with hooks and suspense it's sort of just you know you just look at a render function and understand what's going on it's really easy to coordinate so before it was somewhat challenging I've seen some insane loading States and I'm sure you have been in situations where you have to deal with multiple disparate loaders and stuff but with suspense it's declarative and truly easy to reason about because you remove the entire concept almost entirely and it helps you get to this fast and pretty balance so I mentioned before that when we're trying to optimize speed and performance it's often at the cost of user experience either on slow or fast connections we'd have to decide but with suspense you really get the best of both worlds so what happens on Monday so first start with your modules react lazy make sure you pass strict mode and then move to assets and then maybe think about date efficient but maybe wait and I want to show you one last thing though before we go go back to our app for one second here let's go back to index J s and let's go back to react Dom dot render so turn a turn-off concurrent mode and our app still worked even with all that suspense stuff we just added let's think about that for a second so suspense works without concurrent react and what the way it works is it automatically fires that fallback that loader so that means that you can still get all the bent the DX benefits of deleting all that loading state without necessarily getting all the way to concurrent react and even if you can't get your app completely safely into strict mode at the top level you can actually use something called concurrent mode this component called react a concurrent mode and wrap parts of your application in concurrent mode and so this is the idea is that you can incrementally adopt this everything is opt in but it also works with the latest version of react without concurrent mode so you get the same benefits you can prepare yourself and share components in and out of current concurrent react so I can't think of like a more adoptable solution than this that you can literally start as soon as you get to the office so I hope that gave you a glimpse as to what's to come and sort of how to use it and thank you for inviting me here thank you guys you guys are awesome thank you Facebook and the organizers this was this was fantastic so thank you all [Applause]
Info
Channel: React Conf
Views: 49,587
Rating: undefined out of 5
Keywords:
Id: SCQgE4mTnjU
Channel Id: undefined
Length: 30min 49sec (1849 seconds)
Published: Sat Oct 27 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.