Top 10 performance pitfalls - HTTP 203

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
bad inlining sounds like a like a pop band a a hop band no a pop band pop band i thought you were made up a new genre it's like hip hop but it's not so hip it's just hot just a hop band [Music] so so i've been looking at the performance of some websites recently uh specifically formula one websites but i also looked at the google i o website and i can't do an episode on that because showing other people's websites plans in all kinds of legal difficulty and checks um so i can't do that but instead what i'm going to do is show you the top 10 web performance pitfalls that i have seen while looking at a variety of different sites recently um i had nine good ones but then once i had nine what i have to tell you gotta throw in a tenth of you because it sounds better it's the one like which which video are you gonna look at on youtube the top nine no or the top ten yes absolutely so that's what this is the top ten uh first we should talk about how a page actually loads or how it should load oh wow we're going back to the basics oh yeah well this is mostly load time performance stuff in fact almost exclusively this is this is load performance i would say first up you need whatever you need to display core content for a news article it's the content you know it's the text uh or the image if the image is part of the code content as well you're saying for a blog post if it's more app-like then maybe this is just um the shell of a user interface uh don't render buttons that don't work that's you know it's annoying no one like clicking buttons and nothing happens so you would just like maybe have the shell of a user interface next it's what you need to make that first interaction work uh for a blog post or a new story the main interaction is reading so there's probably not too much to worry about here um for an app more like you know squoosh or something this is where you make the buttons work this is where you make those buttons appear uh so that first interaction is there and then there's everything else this is a bit of a simplified model um you can introduce more phases more progressions whatever but really if more of the web just had these three phases everything would be so much faster i'm going to show you some things that have happened that stop this model working correctly uh the things that get in the way so in number 10 and remember i said i just kind of threw one in to make up the numbers that's this one number 10 it is sprites and icon fonts i mean by very definition they load more than you need yes and this happens less and less now which is why it's way down on my list but i have seen this cause a delay especially to the uh interactivity part here's a sprite um like i say i can't show stuff from other sites so here's a google one this is what you'll find on google.com so it's one image file and it contains a whole bunch of icons we used to do this in the http 1.1 days because in http1 you could only download one thing at a time we used to spin up multiple connections so you could download more things in parallel so if you had um 60 icons or whatever it's that's lots of connections that you will need to spin up well with http 1.1 you would spin up six but you would only be downloading six at a time and yeah i was able to say because you couldn't even spin arbitrary spin up arbitrary amounts of connections also limited by spec to six so you had six requests in parallel at most so reducing i think the spec limited to two browsers quickly ignored this oh okay that's good to know it was still pretty limited to between 6 and 10 depending on the browser from memory so this image here on the google site is 100k but individually those icons a lot of them are 500 bytes if you encode them individually google does use all of these icons at once there's a little button you press and it shows you all of the different google apps and they all appear at once so it's not too bad but what i've seen on other sites is like a 300k sprite sheet but the page is only using one of those and that means the user is paying 300k for one image that could be 500 bytes i'm guessing their point was it's in the cache so all subsequent loadings of another icons would be super fast but the first impression matters this is uh really at the root of web performance is a lot of sites are built with this model of like well let's prepare everything in advance and then give you something and it's just not a model that really works it it depends on the user doing particular things afterwards but you can get the same benefit by giving them everything they need first and then downloading the rest in the background and you get that same you're ready for the next thing but you didn't compromise showing them the first thing and that's really those faces i'm talking about and it's the same with icon fonts uh we saw that actually on the google i o website they were pulling in a whole icon font and they were using the hamburger icon and that was it so that's like 50k for what should be like 30 bytes or whatever i would say yeah avoid it these days just serve the stuff separately it means the browser can be smart about which icons it needs which icons it needs with higher priority yeah it's just it's just something we don't need to do anymore in the world of http 2. next up number nine dom ready delay and this was one that i didn't expect to come up but it it did appear on a couple of sites it's a real gotcha actually uh this is what it looks like so you've got your main script in the head it's got it's got defer you know so it doesn't block rendering great and then at the bottom of the body you've got some less important scripts and they're using deferred as well so there's no render blocking going on here it all looks good on the surface but in the first script it does this and it might not do that literally it might be using some like jquery ready function or some other kind of red function that bundles with with a library but if it uses dom content loaded under the hood that will wait for all other deferred scripts to download and to execute and so this this kind of model that looks great from the html where you've got like one thing at the top there and then the less important stuff further down it's spoiled by having this dom ready thing is the correct alternative and dom ready because there's a second event right which basically we're looking for is the an event the dom parsing from the index html is done so there is another thing called ready state which has which has two points one which is before the deferred scripts and one which is after so you can use that but hey if your script is defer it's already going to wait until the dom's ready anyway so the solution here is just don't use it right you know don't use dom ready there might be a cases where someone added this code in because one of the other scripts adds something in that they need or whatever but if you need a certain part of the dom to be there and then you enhance it there are better ways of doing that there are web components that you don't have to go all in on web components with shadow dom and all of that but you can use just the the shell of a custom element as a way to be alerted that when an element appears on the page there are mutation observers as well but really in most cases i would say just you know if you've got a deferred script that's going to run when the dom is ready off you go next one number eight this is bad in lining all right so inlining is when we bundle one asset inside another i mean we tend to use inline to refer to some particular kinds of formats like we don't tend to do it when you ban bundle javascript within javascript we just call that bundling inline it tends to be another format inside another format and it's often great for micro optimizations but when it goes wrong it goes wrong badly so i'm gonna do a countdown with an account down here we go here are the ways that i've seen inlining go wrong first up javascript uh in-line javascript for your first interaction tends to be a really good way of doing things um we did this on squoosh we've got all of our javascript for our first interaction inlined at the bottom of the document um but yeah it should go after everything that's needed for the first render and your first render is html and css i actually saw a couple of sites recently that had a few hundred k of javascript right at the top of the document and this is pretty much as bad as a blocking script the browser has to download 100k worth of stuff before it can render the content before it can discover things like images and maybe other things like you know css and other scripts and yeah you're saving an extra request but also you're giving up lots of cash granularity and all other kinds of things so inlining is you said like is a good tool to have but you should use it very consciously and with small units absolutely yeah avoid blocking your content render on javascript is good advice in general uh but just inlining it is just the same problem put in a different spelling you know it's the same thing so you put it at the either in a separate file is fine as long as it's loading in a non-blocking way using defer or async next one images i would say it's almost always a bad idea to inline images because they can be quite big and it's the kind of thing that you could have involved in your build script and someone changes the image doesn't compress it as well or something and it turns from like a moderately bad thing to a really really terrible thing um i saw one website where they had an svg because svg's small right but inside that svg they had a 1.9 megabytes png in line it was you know and something had gone wrong there they didn't mean to do that but because it was inlined because the svg was inlined in the javascript as well so it became like a huge huge problem and also base64 will make your data one-third bigger yes which um you spoke about huffman the coding in the last episode does give you a lot of that back but um yeah it's still quite a bit bigger um i want to call out svg specifically because inline images doesn't happen so much but inline svg is happening a lot more because you can put it in your html you put in your css you can put it in your javascript and it's sometimes a really good micro optimization but it can also be big i saw a site that had a set of sponsor icons they're quite high up in their page before the main content and it all added up to be like a few hundred k of svg yeah that's so and because it's inlined it's now blocking domain content and other things if it's in separate files it means the browser can you know apply different priorities to different icons especially if you scroll away before it loads them uh it can do the right thing it can also render that main content much earlier my main reason for inlining svg is because i wanted to be affected by my css which is an image tag it doesn't do i know i feel like that we it would be good if there was a better way to do that like somehow have a you know svg that comes from an external file but it can be um affected by your html i guess really the answer there is just fetch it with javascript and then put it in the page we'll give you that yeah one thing i see a lot right now um and i think it's for the same reasons you mentioned there is people putting svg in their javascript uh but as jsx so it's been converted to you know the the pure javascript interpretation of jsx which does add some overhead um and you end up with these large complicated bits of svg and now in the javascript and that's a problem for your first interaction because if your first interaction contains these icons especially if they're icons that you don't need right now they're adding size to your javascript means it downloads slower your first interaction happens later all right next one is the big one can you guess what it is um i don't think i don't i don't think it's worth no it's not worth it woof is a really good format of this type of file though i want to say like it is it is a web font but i think we should wait until watson has calmed down and yes it is it is wolves inlining wolves is bad you are absolutely correct it is web fonts uh especially because you know this is going to be inside your css css blocks rendering and so if you add 500k of fonts to that that means blocking for a lot longer and this this is what i've seen now fonts are difficult when it comes to web performance because it you know while the font's downloading it might mean that your text is blocked or that your text will swap which is also not great but when you inline font data it's going to block the whole rendering of the page and also it could be blocking rendering on fonts you don't even use on that page and that's what i was seeing so almost never do this i say almost never because you know there are cases where if you subset the font to just a few characters you can get away with it but you you know you have i was about to say you do it on procs you actually build it for prox where we inline the fonts but specifically only the letters that we use for the first render yes and they do it in scrooge as well the scrooge logo is just the letters for squoosh inside that svg file so yes okay there are cases where it's good but you you have to be so careful um it's yeah it can't just be for general fonts all right back to the main countdown we love talking about images let's talk about some big images images download in parallel they don't block things like you know rendering they don't block rendering like css blocks rendering and also the browser is smart like it gives images in the viewport a different priority to images outside the viewport so what is what is the problem here in the viewport it would just have the same priority or higher as the script so if your image is too big that can delay your first interaction because the image and that script are going to be fighting for like the you know the same bit of bandwidth because just because like http 2 can download things in parallel doesn't mean you magically get twice the bandwidth that you have right it's still you know sharing those things out so it's another opportunity for us to plug squoosh you squoosh make your images smaller many images i see on the web it could be a 10 for the size and it's not always down to using some new format that's only supported in chrome which i'm talking about avif here but like even just as a jpeg things could be so much smaller and webp has has really good support now as well yeah i did a couple of experiments about 50 of the page weight is images on average according to hd archive at least and the vast majority of those images can be compressed to half their size even fully automatically without perceptible loss of quality so we really have a lot of things we can do better with images on the web absolutely yeah and as i say a lot of time it doesn't matter it just means that image is going to load slow but in some cases it delays like more important things uh another thing that i want to point out that sort of gets lost a lot of people don't know about is that this image will still load like images predate css by some years uh so the idea that images load before layout um or before css layouts well it happens before because they existed before css layout even existed so this will download the browser will download it at low priority it will still use bandwidth of course but it will be at low priority because it knows it's not in the viewport this won't this means that the image is now dependent on the layout and so it knows it's not part of the layout so it won't download that's something i didn't know and find it really interesting that you could i guess it makes sense because the image tag has been used to pre-load images via javascript without even being attached to the document so it needs to load but that loading equals lazy now had to actually introduce image to be self-aware about whether or not it is being laid out and where it has been laid out that i changed that behavior something i didn't realize yeah and that comes at a cost as well so don't just put this on all of your images because especially for your main image at your top of your screen uh if you put that if you put loading lazy on that then the browser has to download the css it has to lay out the page and then it will go oh there's an image here i'll start downloading that whereas without uh without that attribute it will start downloading the image much sooner so yeah it use it on things that you know are not going to be needed yet but don't use it on images right at the top of the page all right next up sticking with images but this time how they're loaded loading main images with javascript i see this a lot http 2 is very good at loading things in parallel the browser is good at figuring out the priority thing should be most of the time sometimes gets it wrong but it's good most of the time but the problem with loading content with javascript is the javascript has to load and execute before the browser knows anything about the next thing you know uh so i see this kind of thing going on where there's an image carousel sort of thing that's powered by javascript and it will just be divs on the page with data attributes which means nothing to the browser awesome javascript implementation of responsive images and then some javascript comes in goes oh this should be an image and it creates the image and then it starts downloading but that's many many seconds later depending on the on the connection and you can't bandaid fix it with like a preload or prefetch but really you should be using the elements that are given to you by the platform here and you're absolutely right one workaround is to use preload which is a good way to tell the browser about stuff that's going to be needed later but yeah really you should only use preload if you're out of better options and in this case we have the image tag which is pretty good at loading images and responsive images have really good support across browsers so there you go the browser will see this as soon as it passes the page and it will prioritize accordingly use all of the smarts that are built into the browser all right next up number five uh halfway through the list now primary resources on other origins i saw this on almost every site that i audited it looks like this i've seen it with unpackaged specifically a few times but also just separate cdns or separate services or whatever http 2 is great it means you can have many things uh downloading in parallel over the same connection but because this is pointing to a different server it has to then set up another connection and this is this is one of those things that used to be good advice like because you had that connection limit to a server in http one uh we would use lots of servers and up that limit but now that's bad advice because with http 2 we only need that one connection but if it's on another server we have to set up another connection and that takes time that can be a couple of seconds on 3g um i also say like i think round trip time and as a result creating a new connection to a server is one of the costliest things in the first load of a page absolutely not not too bad if it's for secondary content so i wouldn't worry about that but it's bad for primary content i would say i really like unpackage i use it on a lot of like prototypes and playing around and that sort of thing but unpackaged will also redirect to the latest version of the library by default so what what happens here is you end up paying a connection cost and then it does a redirect and that tells the browser to go and request something else and i saw this on a few sites and that is just like on 3g seconds seconds and seconds worth of time just wasted on just finding out the right thing to download yeah not great all right next up number four external font services this is a little bit similar to the previous one but it's so commonly specific to font services that i i want to give its own place in this list a lot of font services are not your friend when it comes to web performance um and that's a shame because we all like to use web fonts very you know nice to have a different design on the page so the problem starts here we've got a render blocking resource css but it's on another server so we need another connection so there's a couple of seconds but then they tend to serve the fonts themselves on yet another server so that's yet another connection another couple of seconds wasted even if it was same server it doesn't matter because font files are requested using calls uh and they that will always use another connection uh if it's no credentials so that's that's a fact not many people know yeah if you're making a cross-origin request if it's with cause uh you know like fonts or like you know fetch or xhr whatever that will use a different connection to say an image file or a css file or a script file uh because it wants to keep that boundary for privacy reasons so yeah anyway another connection and then some even go on to do this where it's like yeah like a style sheet is requesting another style sheet and that's even more render blocking time it's it's bad it's just really bad because this also this import isn't discovered early so it while you know it might not create a new connection it will definitely incur another round trip because now this file has to request it before any more processing can be done yes and i have seen cases where it's on yet another server as well absolutely disaster yeah when you've got a stylesheet that loads of stylesheets you could use a preload you know to say that makes it happen in parallel rather than in series you can do that with the font itself as well just make sure you use cross origin on there but again remember that those urls might change if you're using them on a different service you know you might put all of these preloads in and then tomorrow they've changed their urls and now you're pre-loading a bunch of stuff that you don't even use and that's even worse for performance if you don't know the full url you can use a pre-connect that'll at least set up the http connection sooner again make sure you use cross origin to tell it whether it's a cause connection or not but really the best solution is to bring those fonts and css onto your own server and you can do that with google fonts because it's all open source which is great uh you can't do that with close source fonts for various contractual and legal reasons i mean check with your your your service that you use maybe they do allow it maybe they don't but i think yeah some will allow it but only if you pay them a bazillion dollars you know they tend to up the price for doing that which is not great so what you can do is you can do something like this you can async load your css so this is using a preload tag to load some css with high priority and then you've got the actual uh your stylesheet tag there initially uses a print media which means it will load low priority but that's so your preload will bump the priority back up but it means it won't block the rendering of the page either and then once it loads you switch the media and it applies to the page this is some arcane javascript magic by the way yes well this is the the filament group came up with this and it used to be a lot worse um before we had things like preload to be able to do this so this is much better than it used to be um you'll also want to use the font loading api to provide a smooth transition because this will this will just do swap swap fonts unless you add some css to change that you can add as much css as you want to control this process with the font loading api so there you go not easy but it's okay for font services that won't let you do anything better than this it's better than blocking rendering for all of that time all right getting to the final few ones layout instability and this is this is a big one um it's kind of different to the other ones because it might not be part of your main content code it might not be part of your first interaction code but if something comes in late and adds stuff to the page which moves stuff around then your content isn't ready like if your user's reading something and it moves from under them it's not ready yet it's so frustrating um to avoid it like javascript should enhance what's already there in the dom so if you've got an image carousel you would start with the first image there and it would be you know the correct width and height taking up space on the page and then the javascript comes in and adds the buttons or hydrates that part of the page depending on what terminology you're using uh but adding those buttons those buttons will just appear rather than shifting around of a content on the page it's just yeah horrible user experience when stuff shifts around and i'm really glad that we're using metrics now to call out sites which which have a really bad experience here um yeah so test your pages on the slow connection and ensure stuff doesn't move around uh one special mention i would say uh a lot of sites still do this where this image will take up almost no space on the page and then the browser will download enough of the image to know its width and height and then pop it will take up the the correct aspect ratio space on the page and everything else shifts around don't have to do this anymore if you give the image a width and a height it doesn't have to be correct just the correct aspect ratio and then auto height the browser will reserve space for that image no shift which is great and with the aspect ratio css property you can give the same behavior to things that are not images if you have something that has any content in it but you want to reserve something with a certain aspect ratio use the aspect ratio css property yes i what is the browser support good enough for that yet i know i thought so i will put a link i'm going to do some i'm going to put do some really quick live kenner using excellent live fact-checking aspect ratio and i think it's in firefox it might not be in safari no i well the thing is that yeah it might it's not in 14.1 so yeah maybe it's not ready yet but i feel like they were deeply involved inspecting this it is in the next firefox next firefox next chrome oh there you go that's yeah i i've been wanting that forever good bit of aspect ratio ended but this image thing landed much sooner it's still relatively new like in terms of the age of the web but it's you know it works across all browsers now which is really nice you don't get that layout shift you don't have to use the padding hacks that sort of stuff oh you got the padding i'll put a link to that as well in case anyone's trying to target some super old browsers uh next we're at number two now this is over bundling um so this is a little or as i call it under splitting i'm just splitting that's a better name for it and yeah it's a form of inlining isn't it um but this is mostly about css and javascript um inlining javascript in javascript and then lining css in css and it's it's much more common of a problem uh a lot of sites will have one javascript file for their whole site or one css file for their whole site and that means any given page the user is downloading like the chunk of the website the entire website just to get to that first interaction or even first render the google i o website if you visit like the link to our talk you download but before you even get to render you download all of the animation data for the home page even though you are not on the home page like no it is it's like 600k or whatever it is it's absolutely massive like it also the google i o website it feels okay to say nasty things about one of our own sites i know it's you know don't want to do it too frequently to other people's websites but oh good god the google i o website isn't great is it and they've also got like all of the ui strings in a bunch of other languages like most users are only going to see one language but it's like the rosetta stone in there mate it's it's incredible anyway don't don't do that um chrome devtools has this excellent coverage report that you can do uh you reload your page and tell you how much of your javascript and css is being used uh it's it's a good way to identify a problem early on like sometimes you've got a huge bit of javascript that is used but you shouldn't need that much javascript to do a thing you know this won't highlight that but you can see in this case uh there's a bunch of javascript being downloaded that isn't being used just because there's some script unused isn't a problem because if it's part of your everything else low priority bundle that's fine but for your blocking render stuff or for your first interaction stuff you want to see a high coverage there because you just want it to contain the stuff that you really really need we built a website remember this one i i do uh we lose various bundles to see you know how they do things and one of the things we looked at is code splitting uh so the information is here for a bunch of different uh bundlers for how you would split that out and ideally have an entry point for every type of page on your site not literally every page but like on the google i o website you would have one entry point for the home page and one entry point for the page that displays the information about an individual session all right we're at the end now it's the final one number one oh and it is this ah content loaded with javascript the fastest way to get to first render on your page is html and css and doing it with javascript is always going to be slower like if you really really optimize things you can get close but it will always be slower and usually it is a lot slower because you you i mean by very definition the index.html file is the first one that the browser loads like everything else will come in later yeah and so the more you have in there the better you're doing you can end up with a pattern like this where your html downloads and then you know the browser goes there's some javascript i'll download that and then the javascript downloads and it executes and whatever and then the javascript goes well actually i need some data from this 3k json file and so go and fetch that and then i'll look through that and find the data and put it on the page it's it's slow it's slow and there are cases where it's your only option depending on what apis you're using or whatever but really it's very few uh but it's a pattern i see in the wild a lot and it is very slow even a static render that is just a ui shell will really help with this perception of performance you know like even if it's fairly basic at least the user gets something other than just a white screen but even better if you can do a content render just using your html in your css and i i'm gonna be shamelessly plugging the talk that the two of us gave at jams.conf where we go through these steps like we we send a shell we teach our build system to build a shell for a highly interactive web app a game and try to cut down the javascript required to get the first interaction going and the game overall isn't that small so that that walks you through those steps yep that's a talk that we rehearsed to death we spent so much effort rehearsing it and then like i did the video edit myself because the conferences video didn't come out very well and about 300 people watched it so yeah yeah we'll send more people to that video get my money's worth out of that one i do want to call out a specific form of this problem which i've seen a couple of times and i didn't i didn't realize how bad it was at first um it's when this happens so i think this happens when the developer will notice a lot of layout shifting on the page as their javascript is loading in so they'll hide it with an overlay that might have a loading spinner in order to say the word loading or something and then the main javascript loads and they remove that overlay ta-da this suffers from a priority issue so if you've got a blocking bit of javascript in the head of your page the browser's like whoa i am going to fire all the bandwidth for that because that is blocking rendering it does the same with css and it will do this like sort of the same with fonts as well a different phase and then things like images if they're in the viewport it starts pouring bandwidth into those like the browser tries to do this so it gets the fastest load time of course it does but this tricks the browser because it sees the script at the bottom of the page goes not important not important you already have your nice black overlay with a spinner the user is happy we've got a bunch of content on the page here and that that's going to include images and css backgrounds so i better get those ready like in parallel with the javascript and that's what happens it tends to the images uh end up the same priority or even higher priority than that script at the bottom you've created a a blocking experience but not one that the browser actively recognizes as a blocking experience so your recommendation is put the spinner first put a blocking script another first script in the middle and then the content after right do you know what that would be faster that's the thing that would actually be faster but no like the the truly yeah the best thing you could do here is a proper static render uh that gives you the contents with no layout shifting um or if you have this problem if you do just want to do a quick fix link roll preload as script in the head of the document there and the browser will bump the priority of that script loading at least that's not a perfect solution but if you've got 10 minutes that is a solution that will improve things massively uh especially depending if you've got a few big images on the page and that's all i've got um i'll put some links into the articles i wrote where i looked at individual sites um that includes videos so you can see how many seconds are added by each of these you know performance gotcha pitfall things and how fast things could be if you know alternatives were used which are much better for performance and and we're gonna link to our talk and all of you watching should watch that one because we need more views on that one yes please thank you very much uh but yeah please please go and do that yeah oh it's so close to the end so close to the end why didn't i i'll wing it i'll just swing it i don't need notes i've got all this in my head i've been doing this job for 20 years all right well that's some good b-roll
Info
Channel: Google Chrome Developers
Views: 23,171
Rating: 4.9628868 out of 5
Keywords: purpose: Educate, pr_pr: Chrome, series: HTTP203, type: Trailer/Promo, GDS: Yes, http 203, http 203 series, chrome http 203, http, web dev, web, dev, chrome developer, google chrome developer, google developer, chrome developers, google developers, google chrome, chrome, google, Jake Archibald, Surma
Id: Lh9q3h2khlc
Channel Id: undefined
Length: 36min 30sec (2190 seconds)
Published: Tue Jun 22 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.