Making Load Times Ultra-Fast with webpack

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
paying the pipe but like we also have like five different telemetry systems and so having a platform is really nice is that Microsoft are a platform company so we can totally relate to that business strategy also so I'm gonna pull up this slide first but hi everybody Wow holy is there enough chairs for everybody there's four seats here so in case you do don't have to stand was I in sitting motor standing mode are we good can i I don't know I think I'm I think I'm gonna stand after seeing how many people are here it's anyway so yeah so thank you all for coming David did you want to like talk about did you want to your introduction yet or do you just want me to go okay cool well you know so thank you to David maybe a little round of applause for having him bring me here and set this up and such short notice so thank you and check out hack collab is his startup you know which is event like meetups events base and all that kind of stuff and Jay s camp but yes so so I wanted to I had a couple things that I could talk about today but I'm gonna give you kind of a sneak peak of a segment of one of my workshops that I do it's actually a 16-hour workshop so I hope you brought your sleeping bags cuz we're gonna no we're not gonna be here that long but one of the pieces is about web performance and I love sharing this at meetups and talking about web performance one because web pack was solely made for web performance alone and it's so I mean I'm a little biased and it's near and dear to my heart so yes my name is Sean Larkin I'm a program manager at Microsoft I work on what's called the developer experience group for Microsoft edge specifically my team my sub team is called ecosystem so like the thing that I'm responsible for doing is reaching out to frameworks build tools web pack parcel roll-up like all of these popular tooling maintainer x' other JavaScript libraries that are prolific and creating relationships with them one of the things that we think is super awesome you may have heard we're building a new browser Microsoft and so one of the things that we wanted to start out and do right by developers is make sure that their voices are being heard and what better way to do that is to start with all the open source frameworks and tools that you use and I mean awesome Microsoft are unique compared to a lot of other big companies is that we use the same technologies that you use every day whether BVS code typescript react web pack you know any like name a JavaScript library that works with react and I can probably confirm it for you like all those things so like if we're innovating for us we innovate for you so to have these relationships is really important so that's why I do in the ecosystem team that was really long-winded so yes I'm also a maintainer and I fit kind of the dev advocate role also for a web pack who uses web pack maybe a few people cool who uses like a CLI tool that uses web pack does they're more hands yeah there's the rest of people no I'm just kidding who uses like make make okay yeah there's my yep I feel you man we used to make it Microsoft to see make actually but um anyway so a little bit about myself and then I'll jump forward to later in in the slides here but I'm a former tech support rep gone rogue I got tired of not solving people's problems you might have heard this feel before you viewed her to talk by me but so I started learning JavaScript and then I'm sorry I started learning Ruby objective-c and then I finally like fell in love when I found JavaScript so you can also find me like so literally at all the places that's at the Lark in and it's just a play off of my last name to be funny but most people don't get it so I also have an AMA where you can try and ask me anything be like it doesn't have to be webpack related be life I don't know money doesn't matter so now typically if this was a workshop we're gonna be here for 16 hours I have a whole like segment of content that you know I have expectations for you but you don't get that I mean you're only gonna get to talk about one of those things today and that's going to be web performance so with a show of hands like how many in their last sprint has had to focus on some sort of web performance feature okay so that's a third of the room how many in the last like I don't know six months has had to do web performance how many hates new or like how many people hate doing it because like it usually requires you to like dig yourself out of a hole of software engineering that you've done like that's like me every time we never focused at well at my previous job we never focused on web performance we came back we're like how do we make this fast we said we have to rewrite nine months of work so but that's I'm glad to see no hands that came up for that so when I talk about what performance today I'm gonna talk not about like there's many different like people can say perf matters and like all sorts of stuff but like the specific web performance I'm going to talk about is page load time so how long it takes for like me to like open my phone and go to dynaTrace com right and how long it takes for that page to be interactable with right so that's probably one of the most important statistics when it comes to your web application and you may say Shawn are you sure cuz features matter too and I know they do but um just remember that that's the kind of web performance I'm gonna be talking about I'm not gonna talk about like scroll jank or like you know how fast this paint is happening or how deep in the react stack are we going in render cycles like nobody know we're not gonna talk about that kind of stuff we're not building a Multi triangle that like needs 60 frames per second doesn't matter so with that in mind the top three causes of web performance problems are as seen here so the number one is the amount of JavaScript that you ship on the initial download of your application did you know that javascript is the most expensive resource for the browser to process it has to happen on the main thread for a variety of reasons and it not only do you have to parse javascript the engine has to evaluate the JavaScript and then if the codes even used then it gets executed right but as you're gonna learn here pretty soon not all JavaScript gets used on your web applications so the next is the amount of CSS that is downloaded for the initial download and it's not just the size but the complexities of CSS are really interesting also so it's it's not as expensive as JavaScript but it can be just as expensive depending on the scale and how much CSS you're shipping so what has to happen is that you have this I wish I had the diagram I'm gonna steal it from one of our internal documentation is on the Microsoft edge page but like it shows how essentially we have this layout engine and a formatting engine and a composition engine and what you find out very quickly is that the more selectors that you have you have this like o of n complexity in calculating like which selectors respond to this piece of the layout and so long story short more CSS the longer takes for your page surrender and initially load and then finally like a distant third so like like here's the top two in like this one is down here is the amount of network requests that you know are concurrent for the initial loading of your page and like you'll be like Sean why did you use this kind of wordy explanations because they're very like I'm very deliberate about what I've said here right cuz it's the initial download and you'll learn why so here's some goals I don't want you to like have a panic attack because some of this these are really high goals so there's things that I've talked about already or the mentioned so the first thing for JavaScript you know we strive but we strive to have 200 kilobytes of JavaScript uncompressed so this is before you gzip it this is before like this is the amount of JavaScript on your initial download is pivotal to ensure that on the lowest priority device so let's say like you're in India and you have a 2g network that your product is going to be instantly accessible in three seconds and that's the number that you're trying to reach now you may not have clients who are in India and they might not need it but you might work for Hospital and you might make hospital software and your doctor is basically has to choose between waiting in extra two seconds or treating a patient right and so I urge you to create think critically about performance still mattering in a variety of scenarios so it doesn't have to be like this it could be five hundred kilobytes but the point is is that it's a significantly known low number and I'll show you how we can accomplish it and then also 100 kilobytes of CSS uncompressed I stress that really heavily right there's a lot of JavaScript libraries that are like here's the new whatever micro micro date functions library only one KB and then like I replying the tweet is this the uncompressed size no Sean it's actually 40 kilobytes I'm like come on you have to know what the uncompressed and I'll tell you why is because compression is only a network feature it only solves a faster delivery across the network because it's a smaller size however the browser still has to uncompress parse evaluate and execute that JavaScript so one megabyte of compressed JavaScript might actually cost five megabytes in its real actual cost and then finally here we have HTTP so for the network it depends so like if you're using h2 you can actually get anywhere from 20 to 50 I just say 20 to start with and you know they're low benchmarks and you can always you know you you don't have to get these numbers right away this is something you can strive for you can increment towards using your CI system and then finally this like my favorite number and it's kind of blocked here by the camera so maybe all oh there we go you can kind of just say it so 90% code coverage so only about 10% of your code is unused when the page loads so now you might say like Sean how do I actually test this so let's go to a page should we just should we pick a page that I know or should we hot should we do dynaTrace is it okay are you sure okay if the landing page is the landing page like a WordPress site okay wait no let's do mine okay let's do meet you of Omaha a company I worked for already just in case I don't put them on the spot like that I don't want to you know okay so this is the insurance company I used to work for they sell mutual insurance and like you know all this kind of stuff look there oh look our network location services are working anyways so to be able to understand your code coverage what you have to do is open up Chrome developer tools now in the future here you'll actually be able to use this exact same tool in the edge the new Microsoft edge developer tools so something you can consider some to consider okay no pressure okay so mine is open by default so let's back up for a second so I hope you can see this okay you can so the first thing that you're gonna do is actually hit command shift P or if you're on a Windows device its ctrl shift P you're gonna see this drawer pop up and you're gonna type in coverage so the first item that will show up here is show coverage and just hit enter/return so it opens up this empty panel and what we're gonna do is we're just gonna hit the reload button right so what this thing is what this tool does is it going to instrument exactly what resources were needed to make this page renderable right so in this specific case is going to track JavaScript and CSS and it's going to tell us all of those different assets that were needed and requested on the initial download and we're necessary to render this experience that we just saw here like this painting so not any other pages just this one specifically and that's important right so if we look here you know this is a pot a tool I worked on you know the team like we did okay not bad for an initial implementation so but one of the coolest things about this coverage tool is it actually shows you the percentage of code that was actually used right so when I say code coverage I'm talking about like this number down here says 500 kilobytes a 1.1 megabytes are not even used to display this page but as I just talked about code has to be parsed evaluated and executed and so you just still paid 66 percent of the cost of loading this page for half of the code you don't even use why okay so well why is a harder question but I'll show you how you can fix this right so when I say code coverage a good example I was just at a company Mar feel who knows Mar feel okay so I was just over there with them and they showed me we were doing some code coverages there at like one of their internal pages was like 30 percent I was like that is great right because only 30 percent of their code is not used so try to strive for something around 30 40 start their increment slower but the point is right is that if these two resources are the most expensive processes why are we shipping dead code that is equally expensive to process so let's go back to the slides now that you know how to use this tool you know how to analyze all these things probably most of this at a glance besides the network so then it can't we talk about Shawn how do we solve this problem Shawn I have 60 percent of my code is unused how to how do I you know like what would be the solution does anybody have an idea like just don't think about code splitting but if we have 60 percent of the code that's not needed up front we should take it out right separate it to be loaded later at another time right so that's exactly what code splitting does so I'm here to talk about how we solve this and one of the coolest things is that honestly in my opinion 80% of the websites that I see today 80% of the websites that I triage at Microsoft internally this is the number one most impactful like practice that you can apply towards web performance on your web application why because most people the reason why their sites are slow is because they're shipping too much JavaScript really the reason why is because a majority of it is unused so I tried to find a definition of what code splitting is right and then so when I initially was working on these slides I was like okay I can find some historical data this must be a common computer science technique turns out it's not because the first thing that shows up is the webpack v1 docks on coats blowing so however who knows what this framework is I know diet race the every single diet race person should raise their hand right because they use Google web toolkit right okay so Google web toolkit had this sick idea and crazy thinking let's make Java compile to JavaScript and then use it as a web framework like crazy who would do that no I'm just kidding he goes no so but Google web toolkit is actually the pioneers of this technique now what I use it today no but the technique is something that's super valuable and is the reason that web pack exists so code splitting in GWT terms they have this method which instructed to the gwit compiler that just says like GWT run async and so by implementing this it you could put functionality inside of this function call or whatever it's called in Java and on this onclick event handler you're actually executing this code inside but what when this is compiled actually takes this code here and compiles it into a separate Java JavaScript file that isn't needed up front right because only if this click handler occurs do you need to fetch that extra JavaScript and then evaluate it and give the user the functionality do you guys use GWT run a sync have you used it not yet there you go go try it out I think it's still in the API I'm - sure I don't endorse using good no no I get I get so we gotta talk I might go to lunch we'll see ok so then comes I can't up top this so bad look at that anyways but then comes web pack there's actually a really unique story about this and I have to pull up the github so that you can actually see with your true eyes the start of webpack itself and how it actually came into fruition I know from a unconfirmed location oh no remind me later oh that's fine okay github just being safe okay so if you go to the bottom of our web pack readme on our project we have like ignoring all of our backers and sponsors we have a specific location that's dedicated to all the people oops there we go all of our sponsors and backers a place that's dedicated to all the other projects that came before us that we think right so James Burke of required yes sub stacker browserify defunct zombie for the browser field spec but most importantly Google web toolkit and then this project called modules web make so like I'll be blown away if anybody even knows what this project is okay so why PAC was born because and this is so crews words because I wanted code splitting for modules what make interestly the issue is still open so so the story is this Tobias copper's is a is a software engineer at this time in 2012 he is working on his he's working on his master's thesis which was to make a web page but he had experience with quit and he was like I had this idea can we use this tool modules what make but I want to implement code splitting so keep in mind this is a byproduct of his thesis which is to make a web page so he reaches out in 2012 and says hey I would like to add this feature called code splitting I think it's really cool and I think it would be a perfect fit for modules web make and medico the original maintainer was like hey you know it's it's a missing feature but I don't think we want to mess with this stuff and kind of like beats around the bush and then says soukra I'm not sure and you know basically Tobias is like no we can totally do this I promise and then he's like here I rewrote modules what make in two days and here's an example with codes like all things well I don't think this is gonna work you know we have other goals I don't think this is gonna work out too well if you you know change the fork and you know change the name and you know if you want to want to keep working on your other thing he's like okay thanks for the feedback and then like they talk about limitations and he's like okay I hope it's okay I moved it to webpack slash webpack and so that's 2012 web packs first commit had code splitting by default right so and you'll learn here that this isn't using some plug-in this is a default feature in web pack okay and so obviously the issues yeah like 2015 Dan Abramov showcase react hot loader and basically put web pack more huge on the map pete hunt at OSCON west also said hey Instagram uses this crazy tool by a German guy named Tobias right and also showcase it and so you can see here in 2016 when web pack got really popular people were like is there anything gonna happen with this right people started looking at the bottom like hey is this a feature medic who's like no next quarter next year right 2016 so really that's how it started right so I don't know I think that's a special story and unique to us and but we still give thanks to medicube for being super cool and just you know being like yeah hi digress okay so what is code splitting so code splitting is the process of splitting pieces of your codebase into you can just say chunks ignore the async but the most important thing here is that it's at Build time so everything that webpack does is static right so when you run web pack you get output in its bundles right of JavaScript that you can run for your web application when you code split you'll get more JavaScript bundles which will contain the code that you want to load later but you'll see very quickly here that web pack will handle any of the asynchronous loading so how does it work now I usually give this crazy diagram which I'm not going to but instead I can just tell you that when make a dependency graph we just give it a special color a shade and we say well okay anything that's colored this way and in the module graph let's just put into another file you might say sha why should I care I just want to build some apps man like who cares about performance well the future of the web is is mobile as you know who like has to support a mobile or responsive page right okay so half of you so mobile like a majority of the new traffic on the web today is mobile and the point is is that when you load less JavaScript it gets interactive faster but if that's not convincing enough to you don't take my word for it take this study that says sites that loaded in five seconds versus the the world wide web average currently 19 have 60% more pageviews per visit 35% less bounce rate 70% longer sessions 25% higher visibility better indexing on SEO for both Bing and my in Google search 2x greater mobile ad revenue 77 percent of the mobile sites take longer than 10 seconds to load today on a 3G device 19 seconds is the average load time for most of these networks but did you know that if a page takes longer than 3 seconds to load you lose half of your audience so think about that food for thought right so let's talk about code splitting right we're gonna solve this problem so there's two types of code splitting in web pack and I'm gonna so like there's kind of a syntax so ok it's static and dynamic and I use heavy quotes because it's not really dynamic nothing in web pack is ever dynamic we don't do anything dynamically everything is done at Build time and you receive you know but we can kind of fake it and so we say dynamic so static code splitting when would you use it so a good scenario is heavy JavaScript right so if you have a page right and let's so you need to do some like 3GS visualizations you're doing like some 3d rendering and you know on a canvas well it's not needed until you get to like you know until a user hits on a button right well don't import that stuff into your initial bundles Blasi load it right lazy load it until the user clicks on that button so also anything temporal so when I say temporal I mean is that not visible now but then becomes visible later right it still drives that message like it's the code or the functionality for it is not needed yet so only when it becomes visible do you want to actually load this this javascript or the functionality and then finally I mean all of these things mean anything temporal but like I want to give more like I don't know things that you can really tune your everyday coding so like routes who has a client-side router okay yeah so like all of your JavaScript routes should be lazy loaded right because I mean a users gonna go to one but the rest of them don't need to be loaded up front right okay so anything temporal doesn't exist yet and then does exist on the web site so I I'm going to go over like a I'm going to do a little live coding for you and I hope I hope you know it'll be understandable like I always like doing it after this kind of pseudo fake code so here is an example of code splitting in the wild um okay so at the top we're statically importing a you know a module called listeners right this is some event listener keep keep an open mind here and then the next thing we're gonna do is we have this variable called get modal right so it's pretty common somebody clicks on a button loads of modal so get modal is gonna be our JavaScript module that has the functionality to like make it visible and it has you know probably some more JavaScript lated to it maybe it shows an image or just some other functionality API calls whatever the point being is that this is equal to a function that returns a dynamic import so who's seen the dynamic import syntax okay okay okay I just want to make sure for those who don't know dynamic import syntax is a new syntax that's is now implemented in all browsers I believe somebody can correct me if I'm wrong but it's at stage three all browsers have implemented it outside of build tools what it allows you to do is dynamically load a JavaScript module at runtime right but this was a unique opportunity for us with web pack right because we could say hey we know about your entire code base at Build time so we could take this and separate this JavaScript out so there's a huge benefit to being able to have those JavaScript bundles that are separated before before a runtime and I'll talk about it why later but the point being is that this is browser valid syntax and we wanted to align with that so that someday if you want to pop web pack out let's say your dev environment whatever it still works it's browser valid that's super important to us so what's going on in this code base so listener dot on and then it looks like we have an event called did something to warrant a modal being loaded keep an open mind okay so what happens then we call this function and behind the scenes what web pack does is it converts a dynamic import to a promise so you can really think about it as we have a function that returns a promise like so we've called the function we unwrap the promise and what the value inside of it is going to be the default export of that module so we get our modal module we're gonna actually use it we're gonna say you know get the modal and then a knit modal you know some pseudo code but the point here is that we waited to actually use this javascript module and call it for only with inside this event we didn't statically put it at the top of the file so what happens right so what's gonna happen here is that JavaScript or web pack sees this special coloring for the dependency graph right we have we now have three modules in our graph and one has this special shading for it we know that it's an async import or dynamic import and so what web pack does is it says okay separate this into a separate bundle this one's going to be a main bundle and these are just whatever names it might be main yes but the point is we create the additional file that doesn't get loaded up front okay so I'm gonna do a really super quick live walk live kind of triage of a really really small web application that's just JavaScript no frameworks so that you can understand maybe how you can go and take and identify something that should use code splitting that doesn't already today so let's go to this beautiful web application look I have a span and okay so let's just go through the code top to bottom okay so let's see I'll hide this since we know we're building okay cool so we import some CSS don't worry about that there's web pack specific features we have this function called make unique span what is this dear okay so I dive into it looks like it uses lo - es but what it does is it creates an element called a span whatever the span text is it actually splits it into an array and uniques it hold on let me close this so I don't get any more spam for my co-workers who are just like waking up and wanting to do things okay and then we just take and set the inner text you know vanilla Dom API is I know we're all great at them and okay so we use it here we use it up front and then we got some other stuff to contribute like adding this div with a welcome and we put an image inside of it it looks like yeah cool and then we on this button so when we click the button it's going to add this text right so we unique the text it takes away that unique like you know D duplicates any characters cool makes sense so can we do better right is there something that you notice that could be fixed feel free to shout it out I don't mind so I say yeah well yes we're what what function could be code split that's right make unique span right because we don't actually use it up front we so like a great litmus test or a way to identify can i code split this is if I comment this out and reload the page does it still render do I still get the same functionality do you need it up front no no so let's go ahead and refactor this code so that we're actually code splitting it we defer this functions use until the end so the first thing I love to do so one thing that I like for visibility as a developer is that I like refactoring code like in line where it was right so the first thing I'm gonna do is I'm gonna comment not only this out right that's the other test like can I comment this out do I need it up front No so we commented this out we know it still works I mean in a dev server so I can see my environment if you don't believe me let's just do something like this boom like it's a live page I'm not faking it okay hey you know it developers we only believe it if we see it okay so just to show you it's a live dev server it's real code so what we want to do is first fix this static import so the first thing I'm going to do what I like to do naming pattern wise is I like to say like get something like because it makes it kind of obvious it's maybe asynchronous so get unique span is equal to a function right that returns a dynamic import and it's going to be the same path to like path the same module right okay so there's the first step now if we looked inside of our build like feedback here what you would have saw is that there's a new JavaScript bundle created automatically already even though I haven't even like fixed the functionality webpack knows immediately that when you use a dot dynamic import it's gonna say take that module put into a separate bundle and don't load it up front right so now we actually need to use this function but only when the user clicks on the button right so I'm a huge deep driven developer and so I always have to double-check what the value of promises are I can't like just live like I can't free ball that so all do you get making me expand right we're gonna call our function we know it returns the promise because I just taught you and okay so cool we're here so far I'm gonna put a debugger in right because that's debug driven development I'm just gonna put like M because I know it's a module of some sort okay so let's crack open the dev tools and and we're gonna learn this like what do we get out of this when we actually use this functionality okay so come on where is it is that it let's try again what are you click oh gosh hey thanks crowd crowd driven development I'm like why isn't this working but indeed it's working right the way we wanted to okay so click all right I can feel my face getting red that's so cute oh my god he's embarrassed okay no this happens all the time I have no shame okay so we have the debugger there we stop the debugger statement and so now we can actually identify like oh they're so like great features of chrome dev tools give that team a hand we can see there's the module and it has basically the value here so like if real real debug driven development is we're gonna console.log the crap out of it until we know where the the original function is right so I hit em and there we go there's a property called default right so I told you that webpack will convert the module to always return the default export so in this specific case we know well there's our function right span text and it has all our code there it's pulling the lodash unique like I can even just say m dot default if you don't believe me we're all skeptics I know there's the function right so in theory we could basically reuse our commented out code right here can't we we could say Const like I don't want to rewrite this who does so I can maybe just assign a new variable called make you nice man that's equal to m dot default right the default export of the module except use the right JavaScript okay cool so now in theory right I should be able to just drop this above uncomment it out remove the debugger reload the page hashtag Yolo okay is it gonna work you think it's gonna work there we go look okay so we just code split this module but if you don't believe me yet I said we're gonna like we gotta make sure right you have to quadruple check because that's how we do it we don't want to debug live in production so what's the best way that we can find out okay so here's all of our initial JavaScript resources right we have the main dot J's which is our single bundle so all the code that has that that is statically imported ends up here needed for the initial render and then so I'm just going to clear out the traffic right and so technically I should see something when I click right there we go so here's the extra JavaScript bundles that have our functionality included so let's just I'll make it large so we can see now we wrap our code in source Maps because it's our dev mode but the point being is you can see the function write span in tertex you know unique spandex there it is we didn't need that javascript up front and so we just deferred it until we actually needed it so yes that you just learned how to code split and you just witnessed it live so would you believe that that is code splitting that that is the full feature that is how you accomplish it so oh save questions to the end we'll have lots of time for questions I know that there will be many so I want to now talk about a slightly different pattern that I think is really cool once I figure out how to get back to the page that I was on which is the slides there we go okay so now there's dynamic now I won't live code this because it takes a little bit of time you'll just have to believe these believe these fake slides or these pseudo code ampuls so to do dynamic code splitting dynamic because nothing in webpack is truly dynamic we are using the same pattern right so we're we have a function or we have a variable that's assigned to a function it takes a parameter but it's that function returns a dynamic import but this time we're doing something slightly different so this time we actually have template strings and an expression in it so we have a partial path and then we're interpolating at that parameter into the path right so but what this enables us to do is we can now take and use let's say a runtime a runtime variable like I don't know in this case we want to apply a theme so window dot feeling dot stylish would that be cool if your API was that easy and then we can call get get theme and actually pass a string in right and you know module dot apply theme right like you'll apply the theme in the same way else if feeling trendy you know cool that's super neat and what this does is it lets you load bundles based on runtime conditions you might be like what what this made zero sense Sean what the heck is that lat taco lady I love that my slides so let's break it down because I had no idea what was going on here first so this is what I want you to focus on the most important piece here is that we have a template string with a partial path right and then we have this variable you might say well Sean everything static so how is this possible well we're passing webpack enough information to be able to resolve something right we have told webpack well there is there are modules here in this themes folder so web pack you need to be clever and try and resolve any possible module that's inside of it and we could the the technical term is called a context module yeah you can blame Tobias for that it might be easier if you thought about a directory module right so you imported like you are passing a directory that you know you interpolate a module name but you're gonna get something in return so I think the best way to describe this so here's our folder layout so we can I like just using stories where we tell web pack to do things so hey web pack find me all modules in this possible or find me all the possible modules in this partial path and resolve them make sure they exist and tell me all about them and then create individual JavaScript bundles for each possible module but do not put them in the initial bundle so what this means so now if we went back to the slide here we would realize that when somebody calls get theme stylish if stylish is inside of this is a module name you'll actually load you know to chunk is that lazy loaded bundle right so you get that automatically so it feels dynamic but as you realize it's not really it happens at Build time don't forget that so when do you use this now honestly you can use this anywhere but I think I like to just use specific scenarios to kind of I don't know enrich your mind and things that are possible right so you could go back and be like oh wow we can do this today or tomorrow or wait yeah we all work tomorrow so a be testing who has to do a/b testing right that that's not fun this ayat it is I ate it one I hate it because I look at people's code and I see like JavaScript that's unused and I'm like why is this here they're like well these are you know this is a test scenario for a/b tests I'm like why are you loading it if you don't need it and they're like I don't know Sean well look you can use this for a B testing right so super awesome you could do thousands of permutations generate a thousand web pack bundles only load the test cases that you need upfront based on the data that you get from like the window or from the user theming super awesome for theming you saw the code example super relevant and it's just convenience right like I can use static imports for this entire process like here but what it looks like is like I'd have to define like seven functions that import individual modules and then build a switch case and it's like well if this then do you call that function if not this and then Elsa for you know in a switch case so like this is really convenient right because you can just pass a string so convenience is the last item so I'd say exercise time but really one of the things that now I could talk about a whole bunch of other things like unique perf scenarios like I don't know yeah let's just go age to service workers progressive web applications performance hands building for you know all sorts of stuff but I think really I want to just leave it on code splitting one of the things that I haven't talked about yet that I will bring up is I'll answer a question up front first because I always get this question and everybody asked me and then we'll talk about this so somebody say like Sean but if you have a bunch of coats building everywhere it doesn't that mean that you're putting the network like a network delay in between user activity technically yes right and so however the good news is that we have a solution for this you remember I talked about how statically getting these chunks at build time is really useful right so does anybody use service workers at work couple few people well the service worker API basically allows you to use this feature called an asset cache or a serviceworker cache so what you can do is with tools like the work box web pack plug-in pre cache files here I'm just gonna showcase this one because it's really spelt it's nice the point being is that you can use plugins in the web pack ecosystem that'll generate a serviceworker for you and it puts all of those lazy loaded bundles and resources in a serviceworker for you so you don't have to like go all crazy offline PWA mode you could just have a surface worker that pre caches all of those assets for you so what happens is that when the user visits your page in a background thread any of the lazy loaded bundles that you want to put in the cache will be requested in a background thread so it doesn't mess with the render like it doesn't affect the initial render of the page but what happens is like well now let's say I go to the next out instantly that file is already available so there's no network cost so using a service worker here who's like up like this is the best use for a Service Worker my opinion like if you use a service worker at all do it for this right because it's not only like useful for let's say single page applications it's also great for like multi page application architectures you can take and literally like here if I go to Mutual of Omaha comm let's do this we can do this and we inspect it and let's see I think it's under application hey there's our Service Worker so if we actually looked at this you can see this is what we did right a plugin so this uses offline plugin it's basically the functionality is identical to the work box plug-in you drop a plug-in in your configuration instantly creates a service worker and puts all of the lazy loaded resources in a network cache now you can have limits for things that you want to cache so I think like for this one we don't cache all of these upfront but the point being is that you can essentially download all of these extra resources in a background thread and you get like 50 gigs of like cache storage not to say that you should use 50 gigs of cash storage I mean most apps don't cost more than a couple like Meg's right or 10 Meg's so you don't have to feel too guilty about cashing everything the point being here is that now the user never pays for a network cost once they've gone to the page once so this is one of the best ways to employ you know like negating the network cost so that question always gets brought up like so now you don't have to ask me I mean you can still ask me it doesn't matter I'll just say the exact same thing but I could also say link rel prefetch and preload but it's not standard in all browsers so and it's not as useful as serviceworker cache so just use a service worker ok so finally now this one might this always stirs people up so I don't want you to get a little worked up here ok always focus on code splitting before you focus on caching so it's like I'm trying to let me think of a scenario ok customer a who heavily uses webpack and as a close partner to us comes to us and says Shawn we really want to understand how bundles splitting works or we want to create a vendor bundle with exactly this stuff in it right I said okay well why are you reaching out because you're having web performance issues and load times are like yes I said okay could we load your page in production and see what's wrong okay fifty-five percent of the code unused twelve Meg's of JavaScript so that the problem is creating vendor bundles and focusing on network caching is only going to solve the network delivery right only a couple browsers support bytecode caching which allows you to negate maybe parse time so I always tell people always focus on code splitting first right because you're always going to get huge benefits I wish I could I can't share our internal case yet but look towards the Microsoft edge blogs because I'm about to publish an internal or a team internally that we did what's called a performance Club and so I work with this team and we do like this long document and we talk about like how we identified areas of opportunity to solve and like this one was like 18 Meg's of JavaScript - - right and we cut load times in half which was super impactful so look for that okay so the next question which is Shawn how in JavaScript frameworks am I going to actually do this do code splitting right so I know I'm like answering questions before they get asked but I should just add these slides so who uses react okay cool so we'll start there so react dot lazy as of the latest stable react version you have the ability now to almost have first-class code splitting so it's like one-and-a-half in my opinion and I'll show you why and then you can feel free to disagree or be upset about it but that's not my problem no no okay so we worked really hard to encourage the react team to do this and we were super happy that they decide to one because it reflects a common problem no I don't want where is it this is not the this is not the one I want react I lazy here we go okay so who uses like the latest react like all of you probably because okay cool so now so this used to actually be really complex to lazy load interact application because you had to set a bunch of different things and like different events and all sorts of stuff so instead of just statically importing a component if you have one this temporal you can use react dot lazy so I think the lazy function just lives here I'll find it it lives just like usually its import react comma and like component lazy suspense so you can take and swap that out for an identifier that equals react dot lazy which takes a function that returns a dynamic import right so similar API to what you saw in vanilla JavaScript land and then you use suspense to handle like fallback for like if it takes a long time to load and there is a network cost it'll show a spinner component or something like that so but the point being is that now with not too much extra effort you have code splitting here for this component now I might encourage them in the docs to maybe include an example where it is temporal like based on some state then you return this component but the points is still the same right so any time that you use the static import you would change it to be this instead and then based on some sort of state or event or a route you then choose to return this component so who here uses Vijay s sorry okay yeah well guess what you get a way easier time so um I'm just gonna pull up a view J's project sorry to all the react fans here no it's okay I'm biased I just I really love view if you don't realize this already where is it I have it somewhere um where did it go I thought I had it here well I'll just show the docs well no because it's actually more impactful to just show you I'll use this trip report progress so I'm doing this like side project at work because you know when I travel places it would be nice for me to have an easy app instead of writing out a giant document to talk about what I talked about so I was trying to make an app that does it okay so as you can see I've already spoiled it but the beautiful thing so if you don't know about the UJS long story short here is that they use this single file component system because they built on web pack it's a platform to create developer and user experience features and which is great and so instead of like JSX they have a templating syntax that compiles to the same thing that JSX does so it's unidirectional data flow and all that stuff no to a binding but they use kind of like things that were really popular in angularjs like directives and like you know stuff like that so the point being is that if I want to use a custom component in another custom component there's a registration system that can be statically analyzed so down here I have to import this trip form for it to show up right and I register it in this property called components okay so long story short is that their API they built it in a way that says anywhere that takes a component instance so like just statically importing it also takes a function make it large here a function that returns a dynamic import of the same component so I've literally had to do nothing but make a one-line change first-class code splitting verse 1.5 class code splitting in my opinion okay so and this is actually like when we're at Meech of Omaha we were doing like a big framework assessment because we're an enterprise company in Java architects you know how they get their like assessment for everything no offense you guys are Java football you get it you're like you're like yeah that's right so essentially we determined that like this specific exact feature maybe because I'm also on the web pack team was the most impactful for us because we knew that even if we gave like a designer some project they built a bunch of components and just statically imported them anywhere we have the satisfaction of knowing we could go in and make one line changes to make huge performance impact six months down the road so to us we saw this huge return on investment so that's enough me standing my soapbox review yes okay now finally angular so angular does not specifically have a unique API for code splitting at the component level however Todd motto has this great article angular code splitting okay here it is so angular has a little bit more verbosity into how its defined but you can kind of trick component code splitting by using this load children feature and a route but if you are using angular what's cool is that I guess you don't have to use the dynamic import everywhere maybe not my ideal API but that's just my opinion however basically you just pass the path to the module and then the name of the export that you want to lazy load in this case their routes so if you don't already if you've not read this before it's called learn well I mean it's kind of a Todd motto like selling his courses but really this article is just it'll get you 90% of the way there so take a look at that Todd's good friend of mine I left a lot okay so I think I've gotten ahead of all the other questions I can think of so at the end of the day like these are the top things that you can focus on when it comes to web performance always try and focus on these things first right now at the end of the day you should just measure right so you use the performance tool measure how long it takes to become interactive but like most of the time I don't even do that upfront like I go to a project I just look at these numbers like check the coverage okay it's a huge amount unused code split at all and then like huge wins so ideally I'd love to see we get to a place in the world where we actually have to focus on more specific kind of performance concerns like image loading and maybe even vendor caching but right now in the kind of place in the web this is the most impactful thing that you can do you know not to be too hand-wavy so yes thank you [Applause] okay good hello of course yes okay so I'll repeat the question to the people on the livestream can hear so I'm just gonna summarize it and then you can be like Sean that's not even what I said you want to basically you're asking what are the implications of using what pact chunk name API or like the magic comments when your code splitting does it have an effect on it encode coverage as well so okay the web pact chunk name feature really all it is is kind of a developer experience feature that just gives it a name for a lazy loaded bundle however there is a scenario where if you give a bunch of bundles the same webpack chunk name which is not recommended for code splitting then it merges them into a single chunk so number one don't do it so don't don't name multiple lazy loaded bundles the same name right because then it merges them together ideally you want them separate and then to use the webpack chunking magic comment so the feature here it gives me a good segue right because I can kind of talk about it briefly in my workshop I kind of go way in depth all the magic comments but you can go to webpack j/s org and like my favorite part is that this is searchable right like okay magic comments you go to our Doc's page boom okay so I get excited about how cool it is because it like find things in the doc and it's useful not everybody has those experience with Doc's so why pack junk name basically it's an inline comment that you can allow your bundle to be named there's a long-winded history to why it is the way it is you could probably find it at a github issue long story short and web pack 5 we're going to minimize the need for this because we're gonna allow we're gonna have named bundles in your development mode by default so this should be an easier experience you may not even need to use it anymore but for those who let's say how like a good example the Microsoft Outlook wet so what do we call it Outlook Web App OWA is one of the largest single page applications they generate four hundred lazy loaded bundles right and we're talking across twenty thousand modules probably one of our most premier react applications that really focuses on performance and so they use this significantly because they want to understand how to debug but like by default web pack just gives numbers to these bundles instead of names and so this is a nice developer experience feature that you can leverage yourself so answer your question hopefully awesome yep yes yes well actually so I leave it out because I don't well yes so view does support it so instead so there's kind of like a shorthand and then there's a more heavier API that lets you have all these features so I'll show you if you go to the view j/s org website and you search view async component factory or async component let's see okay actually here it is beautiful thank you thank you docs team they're so good okay as a view what is it 2.3 Evan also saw this feature show up prior to like when like react loadable and a bunch of other libraries started adding these features so this is possible in the same way so instead of assigning it to just a function that returns a dynamic import you can have it be equal to a function that returns a object in this case and then has a component property which takes a dynamic import and then you can also pass a loading component an error component even the delay for like if it loads faster than 200 seconds don't show the loader right or if it takes you know and time it out after 3 seconds right like so it it's really rich and configurable so like that's all possible we found a mutual like we didn't need to use this as much maybe there are just a few cases and scenarios but yes it is there and it is available if you need to use it any other questions oh yeah I owe you a question I owe you a question unless I answered it ok ok you're next yep so vendor splitting is what I was talking about like so I I cringe at my dot at our Docs because we have the like we call we have like code splitting and then we say vendor splitting and bundle splitting the only code splitting that creates asynchronous bundles is code splitting anything else is like a cache ability feature so like what you refer to as vendor splitting is like using the Commons chunk plug-in or split chunks and 95 98 percent of the time I endorse people to not touch it so like don't mess with it whatsoever first fix unused code and then if it's like well we could do more by removing duplicate code across like let's say multiple entry points go ahead and use the feature but 90% of the time we found it does more harm like that's why we've removed it from a common plugin to like this kind of embedded API in web pack 4 because we saw people kept using it but creating these giant vendor bundles unknowingly what what the consequences would be so not to say like don't use it we do a lot of this stuff by default and you can find it in our documentation under split chunks I believe so I think it's maybe it's the split chunks plugin do we talk about it yeah so like on a disclaimer none of you use this until you fix the cut until you implement code splitting first promise I promise it's please listen to me I don't even like showing it but I it's okay so there's this plug-in and it's an API that helps you handle like multi page app architectures but like I have found in 90% of the cases that just code splitting and not even worrying about this and letting webpack do the defaults is more performant like in most cases but we do have some scenarios where we handle like split chunks is turned on for lazy loading like for asynchronous bundles but like it's only like really there's very specific scenarios where I've really found it useful and in most of them it's not so I know it doesn't directly answer your question but I'd say focus on focus on code splitting first so that's actually the advanced code splitting feature that webpack does behind the scenes that does vendor caching so it's a vendor caching feature for for lazy loaded bundles but you're absolutely right the only reason why is because I'm also importing lo - alo - library and so we have this special algorithm if I didn't use unique from lo - it would just create one bundle but you can actually read about let me see optimization split chunks so it actually kind of showcases we have like a retied that talks about this where is it yeah yeah yeah so here's the examples so the default is only for lazy loaded bundles and we just basically say does the lazy little bundle contain modules from no module is is like that no module bigger than 30k are the number of parallel requests you know greater than a certain amount does and it doesn't affect the initial you know right so like then we choose to create a async vendor bundle and but that's okay right because it doesn't affect the initial load time so we kind of have this freedom to do that knowing that it's a good practice right but don't touch it by default I'm sorry I don't mean to gate keep this feature but I just see in 90 percent of the time it does more harm than good so but good great observation actually cuz like I was a nervous I was like oh they're probably gonna say something about two bundles but it's true if I didn't use Uniqlo - like I can do it if you don't believe me but yeah so yes any other questions there are still a bunch of hands I think oh yeah yeah here you can you can drive this I'm sorry okay so is that that's not specific to lazy loading it doesn't sound like right right right so so what was the name again or Julius okay whoever you are person I'm not gonna put your name human person developer so there are yes more techniques that you can take advantage of for optimizing your web application you're absolutely right that there are many others what I have found in my experience and in a lot of real-world applications is that this is probably the most high impact and like high impact and like return on investment performance feature that you can implement in your application today and almost actually like I have statistics that say like out of all top 1000 Alexa or 10,000 Alexa websites the average amount of unused code is like 55% so like we can make the web like that much faster so I always yeah so there's lots of other techniques but this one's just specific to like the issue with unused code and and you know kind of shows why codes building is even an important feature today okay yeah no it's actually great like it's a great question I agree with you so the question is like how do you what is the suggested device for code splitting when you're using central state like a central state management library because it's not just Redux Malbecs has the same issue flux has the same issue okay so one one of the caveats is that you basically have central state that's like you try and have to have statically available for all of your code right so like that's one caveat right I can tell you what newer frameworks do today and I think that mark so mark I'm forgetting his last name he's the maintainer Redux but I believe there might be documentation or there might be features in the works on how they're gonna try and accomplish this because it is a prolific issue a so the answer at least I can tell you so I'll show you how one framework does it and I think that it should be possible or it may be possible today but I just don't how to do it myself with Redux so in view we have a very similar library called view X the UX async wait it's a view register module yeah okay so view X has this way of taking and dynamically or to lazy load pieces of your store right so this would be the applicable case right so essentially anywhere that we have a method called register module I say we but I'm not even on the team I'm just I'm on the fan team anyways
Info
Channel: hackcolab
Views: 3,817
Rating: 4.9200001 out of 5
Keywords: webpack, sean larkin, microsoft, javascript
Id: U8_2WdocS9Q
Channel Id: undefined
Length: 68min 26sec (4106 seconds)
Published: Tue Apr 02 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.