Coding with Jon: Let's Build a Website! | episode 6

Jon and the team debug a HubSpot website using Chrome developer tools, focusing on pre-rendering techniques and load time optimization. They walk through performance metrics and coding fixes in real time, with practical demonstrations of how to speed up page rendering.
Sa hello friends. I'm back from EA Airventure, the biggest air show in the world. And you know what that means. Going to talk about going fast, specifically making your website fast. With me today is Dennis Viper, Edson, aj, Goose Laporte. And we're talking website performance. But that's not the but that's the only thing that's scripted today. We're winging it. So let's get started.
King of dad jokes over here.
We'll also see how long I can wear this leather jacket in a house in 80 degree weather outside.
Great, great choice by the way, John. Yeah, the hottest days and we're just.
To put on all the leather. Jim Morrison.
I never thought I'd hear that leather and John in the same sentence there. Thanks aj.
I do. I do ride a motorcycle after all. This isn't just for show. There is a real motorcycle in my garage. Well, what I thought we'd talk about today, aside from obviously website performance, we're also going to try to, if we can manage to cover some of a little bit about pre rendering, how to interpret the performance score that you get inside of Google Chrome and how to start actually addressing those problems. This is how much we're winging it. I'm typing it live on screen. For those who have not seen what pre rendering is, pre rendering is a unique thing, not entirely unique to HubSpot. Now other services are starting to do it like Next, JS, etc. But what we do is we will literally interpret all of your Hubble code. This also applies to the react code, like server side react if you're using that. And we will render the entire page, everything that's got to be on that page, we're going to render it and then we're going to push it out to cloudflare, our cdn. And then we're going to be able to serve website visitors from basically a cached copy of that page. Instead of needing to every single time hit the HubSpot servers directly for that response and have it actually do all of the steps to render again effectively. Website pages on HubSpot all load as if they are statically generated pages. They're just HTML, CSS and JavaScript to the browser. The server does not have to do a whole lot. We also have this.
I just want to point out there are some exceptions to that rule. We have that listed out in the documentation. But there are things that will break that pre rendering or prevent the pre rendering.
Absolutely, absolutely, positively. That is not something Maverick would ever say. But we Certainly do have some things. And this will make a little more sense if we're trying to create these static HTML, CSS and JavaScript files that we can then just serve immediately to the browser. What is something that kind of throws a wrench in that whole chain? It's any time where we have to dynamically change the content of the page server side in order to render that page for the person. Now we have some tricks. If you've ever been to the pre rendering document, you'll see there is a list of incompatible features. These are Hubble features. If you're ever referencing things from account, company contact, the local date, time, owner query request, all of the request items, and the year. Now that doesn't mean that we can't pre render entirely. We can partially pre render and severely underjust for the 80s theme. Love it, Jennifer. It's not a matrix theme, Brooke. These are. This is aviation headsets. Aviator. Literal aviator glasses. Ooh, Brooke, Brooke, Brooke. I. I'm gonna need you to adjust your attitude out there, but I'm more worried.
Are we this old now that like.
Movie references are going past? Well, the, the latest Top Gun movie literally came out like what was it, two years ago? So come on. Anyway, so you're not out of luck if you use these. There are some things that we can do on our end. We can partially pre render pages. What is partial pre rendering? Partial pre rendering basically enables us to do most of the pre rendering that we've already done for a static page, basically. But we know these are the portions of the page that are going to get modified. We can keep all of the parts that don't get modified static and then we inject all the other stuff. The features here are supported. Notice that request and account and company local date, time, etc. Those are supported with partial pre rendering. That's the bulk of all of the ones up here that we mentioned. So this part's more a legacy thing. So I won't get into that. But what I will do is I will show you on the developer's website that we've been building out how to actually test. Now again, we're talking website performance optimization. And my recommendation for you, the very first thing that you should do when you are optimizing a HubSpot site for speed is to check whether your site can be at least partially pre rendered. Now I'm going to. I've. I've already done some performance optimizations in another branch, but I kept everything broken in in this main branch so that you guys can See what, what we're talking about. So in order to test, we're going to actually, I'm going to open up a Google Chrome window. I have this. All right.
Increase the size of your window, just in case.
All right. I may have to zoom in on the dev tools and stuff. We'll see. All right, so the way you do it, there's a couple ways. So you can do HSdebug equals true and then you could inspect the page. And there is a comment that we inject at the bottom of your HTML that basically tells you a whole bunch of debug information. But we're actually going to do HSdebug only equals true. And what this will do is instead of injecting it into the page, it's going to actually give us only that debug information for this page. So what you can see right off the bat is it says this page cannot be pre rendered. To improve your site speed and user experience, address the following issues and the one that it's calling out that is preventing pre rendering. Man, that's a hard way. Hard thing to say. Preventing pre rendering. Request querydict is the main thing that's blocking it right now. Thank you for sharing that in the chat there, aj. I know that inside of my website project somewhere I'm using Request querydict now. I already have the file open, which I accidentally left open. But if you go to the little search tab here, you can search all of the files inside of your working directory for whatever string it is that is problematic. So in this case, I have request predict. And again, request is allowed in partial pre rendering, but I want to make it fully pre render so I can search and I can see that it's appearing in a few different places. I've got it in this module HTML, I've got it in header nav, which actually isn't in use. This is just for my own reference. See the slash reference there?
Hey, John.
So I don't know.
I know I'm a very, very old man and I was young when Top Gun came out, but I cannot see anything you're doing. Would you be able to zoom in on any of this? My gosh, yes. Now we're talking.
All right. Were you able to see the text here too?
Let me now I can. Yeah, I heard you say it. I was totally dependent upon your trusting you and your voice.
All good. All right. So I literally clicked the little. Just to recap, I clicked the little search icon inside of VS code. You, you can use a command palette. I'm just kind of bad at doing searches through there. I don't know why. But anyways, at least you're honest.
You're honest.
So if you do that, you can type in what the string is that it lists here, and then you can go, all right, it's in my module HTML, it's in this file. But I don't care about this one because it's in a slash reference folder, which literally I was just using for reference. And this search results module or page I'm not even using right now. So it doesn't matter. The only one that actually matters is this one, and I can click on it and I can be taken right to my code and see exactly where it is. So I will close that up. And all I need to do I can see is I created a macro called debug, and all I'm using this request for is so that I can print information to the screen when I do a debug. Here, I'll show you exactly what I'm doing with it. Okay, this is going to look a little bit janky, but. And if you use the Chrome extension, you can also just do this. All I'm doing is changing instead of HSdebuggy, HSdebug.
Did you just say debuggy? I think we need to change it to hsdebuggy.
Pretty sure I said that. Instead of using HSdebug only, I'm changing it to HSdebug equals true. And as you can see, what I've got here is I have a whole bunch of debug information that I am printing. When that query parameter is in. That's all this macro does. It goes, hey, if it's this in the URL, then print whatever is inside of these call statements. And I'm doing that a whole bunch in the header nav. Because the header nav on our site is really complicated on the back end. It's not so complicated on the front end. It's just because I'm rendering the whole nav using a custom HubDB script. Anyway, I don't need any of this to be in my actual page. I'm done doing all that debugging. So I can just get rid of all these call statements. Feel free to interject as I'm doing this, if anyone's got anything to call out. Call out is not a pun referring to the fact that these are call statements.
What does everybody else do for debugging? Because I know I've done the same thing where I've done just basically pretty.
Printing A lot of stuff.
Yeah, same. I'm a pretty printer myself. That and Jobs Console log is my never go to a site that I've done because there's going to be about 35 console logs probably that I forgot to get rid of that say various silly things.
Now if I do this, if I refresh now, it's no longer showing those. Now if I do hsdebug only again, this page can be pre rendered. Great success. The rest of these, if you didn't know, I might as well walk you through it. You can also see template errors. These are the things that would show up in the Design manager. So as you're viewing a template, they also show up in the inside of the files locally. If you have the HubSpot extension installed and you're viewing that file specifically, these are warnings. So warnings are things that won't prevent you from publishing the file on HubSpot, but they are things that ideally you should fix. And in my specific case, what's happening here is I have an icon cards module and a content promotion module on the homepage as well as the changelog listing module. What it's not liking about these is that I have a URL field and I'm not actually providing a default URL. Later in my code, I'm getting a warning because the value is null. That's all. This, these aren't critical to me. I'm not going to experience these in the production website because I'm going to have values for all of those fields. And just to give an illustration of what I'm actually talking about, it's literally these modules here. This looks better if I don't do that. There we go. I have like this text with learn more buttons and some more learn more buttons, some watch now buttons and those are the ones that we're getting flagged there down here. I don't know if you noticed this.
John, but did you notice the header on that page? The fade that you have on the bottom is overriding the button.
Oh yeah, yes, yes, I do see that. And we will address that. And there's also currently a bug. This is already fixed, but it has to do with. I am actually working on creating a flipped version of that module, the Morse code module, where the text will be on this side and the Morse code will be on the left. What I had to do is I had to modify the JavaScript that Anton created and I can get into that a little bit later maybe. But basically we had before all the JavaScript was in the HTML file of the module, and we were passing in some Hubble variables. Well, if I want to be able to reuse this module multiple times on a page, then I should move that JavaScript into its own file. I should also make it so that that one script and render all of the instances of this module Friday. Glasses. Yes, John?
Are you saying you're rewriting some of Anton's code? You're moving it around? I just want to say.
Sorry. I am.
Your ego is writing checks your body can't cash. Quote from Top Gun.
Boom. The. Those insults are coming like a great ball of fire. That's also a Top Gun reference. All right, Anyhow, so, yes, we did. I did do some rewriting of your code, Anton, and there may be some more that ends up happening later, but I think you'll be happy with how I implemented that. The question whether I should.
Do you mind if I interject one last time real quickly?
Anytime.
We've got this character, Nick Iceman James, up here right now. We were talking about. This guy reviews all kinds of templates for the marketplace, and I'm just curious to know what his thoughts are on pre rendering for templates that are going into the marketplace. What are you looking at there? Are you okay if it doesn't pre render, or is that like something you're checking for?
It would be great if people would do that.
It's not something that we're checking for heavily, but yeah, anything with performance or anything that can improve performance, Always looking for it. And we'll recommend it too. If we see something where like that it could be beneficial and they're not using it. We'll definitely recommend it and some of the feedbacks, but yeah, absolutely.
100% awesome aside. Done. No, it's good. I actually have an additional comment. So if you are a marketplace theme provider, you probably want to consider making sure that your theme works with pre rendering. Because if you think about it, you're building templates and modules for potentially thousands of websites. If there's thousands of websites that end up using your theme, if you're making them all able to pre render, then, holy cow, they are all getting really good scores in their Google Page, Speed, Insights, and the other performance tools that exists and it'll help those sites with their SEO. Nick laporte is here. Yes, he is. And if you are a marketplace provider. Yes. You want to make Nick happy. I'm not gonna. I'm not gonna read out that last bribery bit.
Fair enough.
All right, so we've done that. We've made that Change and it can be pre rendered. I do want to get into the other things that are in here. These are less important if your page can be pre rendered. If you notice here, after it starts saying summary, let me make this bigger. Thanks sir. Summary and it starts stating all of these different pieces that all have an amount of time here. That's all pretty darn fast. In milliseconds. These are the total requests. Then we've also got how long it takes for the page renderer to actually start rendering everything. And then you can see the different parts of your template, how long it takes for those little pieces to render. Based on the Hubble logic that you've got going on in there, you can even, you can even get into the data queries. If you are doing GraphQL queries, you can actually see one the complexity as well as I believe it shows the time that it took to do the request. Let's see where is that? Maybe it's further up render view. Maybe it's in here.
I did not know this GraphQL info is available.
Yeah. Okay, so you can actually see it in the render view part. So I have this header navigation module and you can see that it takes a total of 142 milliseconds to render the whole thing. And part of that 44 milliseconds of that.
Do we need to have the dial up modem sound going right now? Aj, is that available somewhere?
I think so. Let me see if we still have that one on there. I don't know. I think John may have crashed again.
A data query.
There he is.
Hey.
Hi John. You're back. You've been. You've been doing amazing things without us. Welcome back to our side.
I apologize. We've had some goofy Internet issues here lately. So I'm going to re. Explain. I don't know how. How long of a gap.
You're at the data queries. 44 milliseconds part of it. And then you were breaking that down, I believe.
All right, now that I'm done breaking the sound barrier and you can hear me again, basically you can identify the specific file graphql file that is making that query. And if it's a long query, maybe you want to adjust what data you're grabbing. But here we, we can see this is the header nav module. So header navigation and then it is calling this header nav query right here. And so this is the query itself. And so I'm grabbing. Like I mentioned, this is all a hub DB and I'm literally grabbing for the current language, I'm grabbing the URL, whether it's got dropdowns, some behind the scenes information, what language the link is for, the order of the links, the description, yada yada. Again, I'm using HubDB to store our menu. This is something that most people won't actually do, but we're doing it at HubSpot for a couple of reasons, most of which just has to do with how HubSpot specifically manages our own account. It's not a norm and not the recommended practice for everybody. So regardless, you can see your queries show up here. You can also see things like what it takes for your get asset, URL, queries, et cetera. All of the things that take time to render out. What's also cool, I didn't know that. You can see the amount of time it takes to process the macros that you have in your thing, which is really cool. Anyways, this is all super useful, but none of it matters in a way if your page cannot be prerequisite.
This is all great, but none of it matters.
It doesn't matter if your page can be pre rendered. The reason is because if the page is pre rendered, this query gets made once and it happens before the user ever hits the page. They haven't even requested the page. It's already done if it can't be pre rendered. If your page cannot pre render, then all of this has to happen before that page can be viewed. That adds a bit of a delay. So total request time here is 449 milliseconds. That's a big chunk. It's not a huge chunk. Like it's not in the seconds yet, but it is still a fair amount of time and same with the amount of time to render this. So again make sure your pages can be pre rendered or at least partially pre rendered. All right, now I think we should actually get into the how to make things like how to test. So there's a few ways of testing. You can absolutely go to Google Page Speed Insights. That's a great resource. You can also use inside of the browser tools. You can use Lighthouse. There is also a performance tab for getting more granular information. There's also. But I need to. I need to preface this. So let me actually show you that I will quick refresh with the performance tab just so you can see what this looks like. Normally it'll take a couple seconds, but it'll create this. This waterfall. This is hard for me to read and understand. The main thing I use it for is for the network side of it. The rest of it is a little bit. Let me bring this up so you can see more of it. Just so you know, 12 o'.
Clock, 12 o' clock again, every time.
Every time I've even said like I need to set an alarm to make sure that I mute so that way it doesn't keep doing that.
But you know, I forget a full pre render and cached queries are different, right? Yes. So, so if you make a. If you make a GraphQL query or even some of our API other API requests, we can cache that response if things have not changed. If the value is going to be the same, why would we do the entire thing over again when we can just send you the same response? That is totally separate, completely separate from pre rendering. They do intertwine a little bit in that the API side of it and giving you the cached query happens before the pre rendering. Inside joke. Yes, it is kind of an inside joke. All right. Anyway, so this performance view, if you're like me, is a little bit hard to interpret. I use it for a couple of different things personally though. So I like to view the waterfall network waterfall so you can see when things get loaded in the page. This makes things a lot more obvious as to the loading order of everything and when you're trying to make certain files load asynchronously, etc. I will also try to touch on that too, but so I like to use it for that. As you can see, we are loading the main style sheet first. Then we've got a theme overrides file and then we've got all of our modules loading up here and then way over here we've got our fonts loading. Now this is not efficient. I intentionally, as I said, this is not a good way of doing all of the performance. And I also want to call out while I'm here, the HubSpot theme boilerplate. Before you've done any of this typically always gets at least a 90 in Google page speed Insights and, and the Lighthouse tool. So anything that you are doing after that is what's causing your speed to be lower than the 90s. That means that you can kind of focus your attention on the things that you've implemented versus kind of the nitty gritty boilerplate stuff. Before we get into how I affected this loading order and I do want.
To recommend if you are going to submit things to the Template Marketplace, by all means start with the boilerplate. It is going to be one of your best friends from the onset all the way to the very end. So absolutely 100.
Just don't submit the boilerplate.
Yes.
Yeah, that's one.
Yeah, that's one where I've had to, I think someone did that once and I opened it up and I was. And I, I had to like look at the tabs I had open because I thought I was like looking at the book and I was like, wait, what's going on? I'm like this.
Okay, so yeah, you apologize for this. No, I'm just kidding. Yeah, I 100% agree. I'm going to quick show you one more thing in this Performance tab that is useful to me. So one of the things that you have to care about when you are optimizing your site for performance is called CLS Cumulative Layout Shift. And okay, now that I have the window like this, you can't actually see it super well. So let me just rerun this. What I do. The most important part of your page to load fast is the top part of the website, the part that people will see first. So what I typically will do is I will turn on the CPU slowdown. Sometimes I'll change the network throttling to mimic 3G. 3G in the US is probably not super common, but worldwide there are still some areas that 3G is the best you can get. So still worth checking. Anyhow, I'm going to reload the page now, now that you can see more of it. And then what I'm going to show you is there's one more tool inside of the Performance tab that I use and I use this to visually understand the Cumulative Layout Shift better. So you can see there's a few times where Cumulative Layout Shift kicks in. So we, we render the header, then all of a sudden this button appears and then all of a sudden we shift again to add the banner below and we've got another little shift there. And then this isn't seemingly affecting Cumulative Layout Shift, but then you can see the dots appear. And the reason that the dots are not immediate is because we're doing it through JavaScript. We can change this to make these dots be generated through Hubble. That may be a thing down the road, but I think right now my JavaScript solution is good enough. So the last tool that I want to call out, this is actually going away unfortunately. But hopefully Google will introduce a variation of it into the Performance tab. At least that's what they are claiming they're they're going to do. So this tool is hugely awesome. If you have a Hard time understanding that performance tab, where it's just a whole bunch of. It's a whole bunch of stuff thrown in your face. Like there's screenshots. There's this interesting graph at the top, which I can't find fully interpret, except for I know that it refers to these things. So you can kind of get what's happening and then you can see some more information here, the JavaScript heap, etc. It's too much information, It's a little noisy, and it doesn't necessarily help you get to the exact thing that you want to fix. So Google had come up with this little tool where you can. Maybe I should have turned on throttling. But what it does can't throttle you, John.
Can't throttle you.
We need to play that song again.
Legally, we cannot.
So. All right, so what you'll notice here is here it's actually outright stating the different metrics and when those events are happening. So the first contentful paint happens at one point, 15 seconds. Largest contentful paint is also at that time. And if you click on it, you can go, oh, this is slowed down by these things. And the element that is actually the largest contentful paint element. So just for context, the largest contentful paint is a measure of how long it takes to render the largest object that is basically the first element seen on the screen. It's not the first. It's the largest of the elements first seen on screen. So. So what it's pointing to here is this code creatively build brilliantly. This is huge. It's bigger than the logo, it's bigger than all of this. And like I mentioned before, the Morse code here does not show up immediately. So this is the thing that we want to make go fast. And if you actually. I've seen this happen before. If you actually optimize this really well, I've actually seen the browser go, okay, we're going to pick a new element to be the largest contentful paint element. Because you're perfect on that. I don't know why, like, that feels a little bit like this. This metric is a little dishonest in that sense. But anyways, the gist though is you also get that same network waterfall. You can see when the network requests are happening and you can click on each element and you can go, okay, this is that style sheet. The issue with the style sheet is it's blocking rendering. It's suggesting that you should inline some critical styles or load the CSS asynchronously. And I can show now how we would do such thing inside of HubSpot. Oh, before we do that though, you can also see the first contentful paint. Largest Contentful paint. Sorry, did I mispronounce first? Yeah, okay. I was mixing up words. All right. And then you can see the DOM content loaded and then time to interactive show up here so you can understand what those metrics are looking like on your site. They also do the screenshots like the other tool, but this is just a way more easy tool for me to personally understand. So I hope they incorporate it back.
I'm glad you showcased a tool that Google is going to take away from us. Yeah, again thank you Google.
Anyhow, this tool is not going away. The latest report. This is identical to the report that you would get inside of the Google PageSpeed insights. And again, I haven't. This is the site without any performance optimizations. And I also want to point out that we are loading the site on hssites.com so all sites loading from that do not have the full set of performance optimizations that HubSpot does for you specifically. It will call out. It'll call out use http2. I'm not sure why personally why that's not happening for these resources in HS sites, but it is just a thing. So this entire warning, which is the bulk of the performance issue, is going to completely go away and the server response time will also speed up drastically on the production site. And to prove this, I'm not just talking out of my butt.
So should I have at least 20 to 30 ads on my page? Does that help out with my site performance?
That's a minimum requirement. You should absolutely have as many ads and tracking scripts on your page as possible. You should have everything. And so a recommendation first off is to continually always keep checking your performance scores and keep optimizing. In this case, this is behind the scenes knowledge. This page has been updated by multiple teams over multiple years and not seen a whole lot of attention towards keeping it performant after it first launched. So it's not in its best state. But we, we can see that the HTTP 2 issue is gone. We've also got some other things that were reported on the other site here that are not an issue. So initial server response time was not even listed on the other report. And yeah, so and if you want to see how other sites compare, we can actually look at Amazon's. I can run a fresh report to be fair to them.
Do we still have that website grader thing that we.
Is that still a thing? We do have that so if you're a HubSpot partner, totally recommend checking that out because you can add to your own company website a website grading tool that will effectively do all of the Lighthouse tests, as well as a few, I believe, a few that are completely HubSpot specific. And we also add some HubSpot insights to the results as well. So you can allow your own customers to test their website through your website, which is pretty awesome. Yes, optimizing your images is a huge, huge part of making sure your site is fast. And Amazon is not going to get a good score here. I can just tell because it's taking forever. That's all I'm judging this based on. Yeah, so they have a bit to improve. If you are not aware of this, you can identify when you're doing performance optimization the way that the score works for Google Page Speed Insights and Google Lighthouse if they take these metrics. Oh, did someone try to interrupt or say something?
Nope, not you, ma'.
Am. Okay, so what these tools are doing is they are measuring some metrics that Google has defined as being representative of making a site feel fast. I have to emphasize the word feel because it is not necessarily that the website loads as fast as possible. It is what makes the site feel fast to the user. So technically you could have a site that continues loading long after the user feels like it's already loaded. An example would be if you're like asynchronously. Actually a perfect example is back in the day when we would do the infinite scrolling. So Google at one point I think did it for their Google search results. They would do infinite scrolling. You can do that in your own results or on your blog and just make it so that all of those links start appearing as the user scrolls down instead of paginating those results. Another example is lazy loading images. So those images only start to load just before the user is about to scroll to them or see them in a slider. That's a little bit tricky as to how that works, but you get the gist. So anyways, these are the metrics. If I expand this, you can see a description. I will increase the font size so you can read it.
What's the status with the background images these days? Lazy loading.
That there is still no way to lazy load background images. I wish there was. There is a trick you can do. I. Well first trick is if you have an image that is not a transparent image, something that I recommend to at least create the illusion that the page is loading faster. We'll give you an example. A Real time example. So say instead of generating this Morse code dynamically like we are on our site, say you're using an image. You're using a background image for that. Well, the rest of this is just this blue background. If you apply that blue color as just a background color and then you apply a background image over the top of that, it feels to the user like the page is loaded faster. If you noticed when we were doing the performance tab and we could see the screenshots, you could already read the text and click the button before those dots even appeared. You can create that exact same effect, but with background image and background color you can also. This is not maybe the wisest choice, but it is a trick that I've done in the past. There was a fad back before browsers had the native image lazy loading where you could actually make a. And it's worked especially well with HubSpot because we have. By the way, I will pull up the Hubble function. We have resize image URL. So highly recommend using this on your background images if the images are not already sized properly. But what I was able to do before, but it's no longer as necessary again, because lazy loading works, you could actually apply to the image element a background image. And you could use resize image URL to specify loading a version of that image at like 20 by 20 pixels. So the file itself that's loading is 20 tiny. But then as. And so as soon as the page loads, you get this blurred version of the image and then all of a sudden, boom, the im the real image loads and you get the real image.
Brilliant.
Yeah, that's a trick that. That's also nice in. In HTML emails, but be a little careful with that.
So you can be my co pilot anytime. John.
Welcome. Tune. Okay, where were we? We were talking about images. We were talking about. Oh, the score. Let me open. Where is our file? I guess we were looking at it on Amazon's site. So we have these metrics. These are the ones to care about. Speed index basically is more of a relative compared to other sites on the web. I forget exactly the. They're all of these metrics by the way. The whether they are green, red or yellow, they are judged based on the top. Was it 10,000 websites? It's a comparison of your pages speed index based on. They used to have the number here somewhere. Whatever. It's something along the lines of the top 10,000 websites. So this is a moving benchmark when you run a test on your website. Day one, launch day of your site, it's going to load really fast. You're going to have optimized it, put all this time and energy into it, and then hopefully a year from then it's going to fail. Not entirely. You're hoping it doesn't actually fail. But what I'm getting at is the benchmark, the actual number that you're, you're shooting for for all of these metrics is going to go down. You want to shorten this time even further because that top 10,000 websites, they're all doing the same thing as you. They're performance optimizing their sites. So that score has to go down. If we all got lazy, maybe it wouldn't move or it would get worse, but that's not going to happen when there's money behind it.
So John, what would you, what would you recommend tooling wise to kind of keep a pulse on that? Is there anything that you've done like I know, I believe Google Analytics offered they might still do it where you could like add in like page speed scores to some listings. But like what, what would you recommend somebody do to like kind of stay on top of it? Because I mean there's nothing that's similar to like a pingdom or something where it can like automatically notify you when.
Your score drops or something, something like that. That is an excellent question. I think it really depends on how important it is to you the amount of effort in tooling and costs you want to incur around it. So the Google Page speaker my Google homes just went off to tell me about Google PageSpeed Insights. Anyhow, we have an API. Well, not we. Google has an API that you can use to literally run their performance checks whenever you want against any websites that you want. It's easy to work with, it gives you everything in an object format and it's all of the exact same information you see in the Google PageSpeed Insights report. That's my recommendation. If you need to do it in automated fashion. If you don't need to do it in an automated fashion, I would just check like once a year or if you do a big redesign or you add, say you add a bunch of content to a page. An example is the HubSpot developer's website has had a ton of modifications to it over the years, changing all of the content on this page. If that's happening and things have changed significantly, then you should probably do another test and then just run through fix anything that's wrong because little things like images not being lazy, loaded, etc. Could completely change your results as well as images not being sized.
Well, this is what we call monthly maintenance costs when you're at an agency.
Yes. Bill that in your retainer. That's the recommendation. All right, now that we've talked about the actual, like, what these are, I didn't get into the details. We're kind of close to time, so I'm not going to completely go into all of these. But the hardest one to affect, in my opinion, is the total blocking time. This is mostly to do with your JavaScript on that page. So thankfully there isn't that much JavaScript actually loading on the new developer's website. The bulk of the JavaScript that's on this page, like the most complicated JavaScript that's happening, we can thank Anton for and start sending him some bandwidth bills or something.
Wow.
Wow. Geez.
You let the guy put some stuff.
Up there, then you start.
If the performance is bad, it's not us, it's Anton.
I'm just kidding. Anton, thank you for writing that code. And I already made it more efficient by doing this. I changed the Morse code module so that instead of having all of the code write here, I flip to our version with the performance optimizations. I will just.
That's a scary little.
It's only scary because I made some changes to demo something, so it's not a big deal. I can just toss them. All right, so if I change it to the performance optimizations. By the way, if you don't use this tool in VS code, I highly recommend it. It's not even a special extension. This is just built in and you can see my whole commit history in this branch right here. One of the things I did was I got rid of that script tag that was in here for calculating the all the things that's needed to make the Morse code. And I moved the. I moved the iterations into a data attribute, the headline text. So this is the text that's actually rendered in Morse code form. And then the colors, I added those as data attributes as well. And then I just did all of the JavaScript right here. So this is all of Anton's code. And the main thing that I had to do was I just made it so that instead of having a script tag in each of those modules, htmls, we're just going to loop over all of these Morse code wrappers throughout the page and we're going to convert the text based on the Morse text data, attribute the loop through it, the number of iterations, set the colors. This is one thing That I also did. That's wise. If you need to do something like we're doing, where we're rendering, these are a ton of span elements. So this is a bunch of divs and a bunch of spans. If you're doing something like this in your site, probably not exactly like this, but you're rendering a ton of HTML into the page. I highly, highly, highly recommend to use document fragments. Basically what we're doing here is instead of just rendering all that HTML one element at a time into the dom, which it would literally in the browser, it would add that element one at a time. We're instead creating a document fragment, which is basically saying to the browser, hey, I'm going to be creating some HTML, but it's not in the browser yet. You don't have to render it yet. Then we can add all. Just treating it like it's any other element in the page. We can append to that element, our HTML. In Anton's code, we're just going and creating all of those span elements and those div elements and we are adding them to this document fragment. Then at the very end we go, okay, cool, display it. Then we are literally just adding that element as a whole to the page all at once. And instead of adding all of them sequentially, which can cause cumulative layout shift, it's also very intensive for the browser otherwise, because not only with layout shift, but they have to repaint every single time you add an element.
I think the best thing for Anton here is that he donated code to this, which gives him props. But you modified it, so if anything goes wrong, as has been said, you own it, John.
Yep, yep, that's fair, that's fair. I. I do have a comment in here that maybe one day I'm going to change it so that this renders the. The Morse code using Hubble. I don't remember where I have that, but. Oh, I'm in the wrong module. That's why I'm not seeing it in there. But yeah, so I might do it all with Hubble one day. That way it's server side rendered. I don't know if that's actually going to be more performant because what I did do is I also made this JavaScript so that it loads asynchronously. I know that we are technically beyond time, but there's plenty of other interesting things to call out, so I'm happy to continue for a little bit. JavaScript. Well, it's not going to be in the head, but let's see. Morse header. Nope. It's going to be way down here, header. Now, where did that code load? Thought it was up at the top here. I might just be visually missing it. What are you looking for? Oh, you know what, I might have flipped to the branch without refreshing the browser. Morse or setter. Okay, so what you'll notice is I'm actually loading because I know that this code needs to appear like this banner needs to show up right away at the very beginning of the page loading because it's the first thing someone sees. I went, okay, I need to load this JavaScript asynchronously. And so what I'm actually doing is all of the code all the way up until here is already loaded by the browser and then it just waits until, well, it first checks if the page has already loaded and then it just runs it. If it hasn't already finished loading, it just waits until the DOM content is loaded. And we have to wait until the DOM content is loaded because we are grabbing those data attributes off of the HTML. So it's kind of a tricky way to be able to load everything at the same time asynchronously as the page is loading. In addition to making your JavaScript files well, actually, let me call this out. You can make your JavaScript files load asynchronously by adding to your meta JSON for your module a jsrender options object. You can specify the position head, which literally means the HTML hud, or footer, which means just above the end HTML tag. You can specify whether it's async. You can also add the type in case you're going to do type equals module. You can also add defer. So in some cases in this site, like the main js, let's see. Problem with naming a file main is that everything has main in it in the HTML. All right? So main js, this is set to defer, and you can do that in your templates. So main JS is just a JavaScript file that loads by default on every page of the site. And I'm doing that through require js. So you can use your require JS function to load it getasset URL to grab that specific file. We're doing the exact same object that you do in the the meta JSON. So position, footer, defer True. Amazing work. Thank you. Then you can also add some preconnect statements and preloads. Preload is recommended for font files. That's what I'm doing here. I may have to actually modify these URLs when I launch the site because the URLs might change. But that's a tip is your font files are something you need as soon as possible when you're loading your page, because any text is going to first, if you have font display swap set up, it's going to show the wrong font. It'll show a system font that the user already has and then it will load the the other font and that affects your largest contentful paint. If your biggest item is the text, it also will cause a flash. If you have display swap and you're not doing it fast enough, you're not preloading.
So so John, real quick, in the in the meta file you were just in prior to this.
Yeah.
Yeah, yeah. Where you have the JS render options, you can't do any of that via the Design Manager. You can only really set that via VS code or local development.
You're correct, this is not available to be set inside the Design Manager.
I just want to make sure to call that out in case anybody who doesn't use local development as much goes into Design Manager. It's not a variable that you're going to be able to tweak or do anything within the ui.
That's a great call out. This is one of the perks of working with the cli. Highly recommend. If you're not already building locally, do it. The Design Manager is great for fixing little tiny bugs or making small changes, but it does not compare to being able to use your preferred code editor with all of the tools, the GitHub copilot, et cetera that you want to use. You'll have probably noticed I don't tend to use GitHub Copilot or any of the AI assistance tools, mostly just because they kind of cause me to do a thing that is sort of known as the GitHub copilot. Pause. That's just a personal preference. I try to avoid that. It also causes me to over rely on it, so I just don't use it. I do use AI tools though for like if I'm like hey, I have this weird CSS thing I'm trying to figure out or this weird JavaScript thing I'm trying to figure out, how can I solve it? I'll type it into a tool like ChatGPT or Google Gemini or any of those tools, even GitHub Copilot Chat. So definitely don't feel afraid of AI tools, but you'll probably learn what things you prefer. I also find that when I do it, use it for code generation I don't usually like the code it generates. It's kind of like it tends to do AI generation tools, take the average of all of the data that is given to them and produce the average results. So you end up with average code and the average code you find on GitHub, etc.
Yeah.
Maybe it's the glasses, maybe it's the headset, maybe. Maybe it's the jacket. I don't know. It's a bullshit. Let's see if it plays out.
Anton did actually drop a comment real quick to call out something really good too. You can use the required JS function within a module to recreate what's not available in Design Manager. That's a really good call.
That is absolutely correct. I was trying to think of a situation where I'm might be doing that already. So I do want to call out. So I don't think. Okay, we are doing it here. So in our header that we're using on the site, I have a polyfill. In case CSS and HTML popovers are not supported, I load this polyfill. But if you have an asset that is shared across multiple modules. So one. One asset that we might end up using in multiple places is we have this slider. Here, let me. Oh, here we go. All right. So we have this slider and it's actually fully accessible. There's a reason I picked it. So let me close this and see the keyboard effects so you can go click to skip the carousel. It also has readouts so that the user can see when they are keyboard navigating what page of the slider they're on, etc. And it's just hard to do in just HTML and CSS might even be totally impossible, but the rest of the slider is actually just HTML and css. I'm not actually doing anything fancy with this slider. It's literally a really wide HTML element with an overflow hidden on it. And we are basically just scrolling that element from side to side and using CSS scroll snap to do it. I'm going to be reusing this JavaScript probably though, because on mobile in our mockups, let me see if I can pull that up fast. In our mockup, the mobile version of the site makes a lot of things into horizontal scrolling regions. So instead of stacking and so I am probably going to use that library specifically to make all of these different components be horizontal scrolling on mobile and still have a good experience. So anyways, to do that I'm going to literally do a require JS in each of the modules instead of putting the code for the sliders in the modules JS file. That way it only loads once, regardless of how many times that code is going to get used. Okay. We've kind of started rambling, I think, and getting into the weeds on some things. I could keep going a little bit or. Or we could call it a day. What do you guys think?
I mean, I've got a little extra.
Time.
But I'm comfortable with whatever. I'm comfortable with whatever.
Sounds good. Let me. I will just go back to the inspector here and we can open the lighthouse report back up.
And I gotta run, y', all, so. Goose, let's buzz that tower and talk to me.
Goose.
I'll catch you all later.
All right, well then let's close it up then. If we're all. Then we can just. We'll continue with this, of course, as usual, next Friday. So.
Yep, next Friday we're going to be talking as long as everything goes. Great accessibility, so stay tuned. Check. Go to the developers YouTube channel that you're already on. Go to the subscribe. Make sure you subscribe. You can also look at the live or streams category on our page on YouTube and you can click the notify button so that you get a notification from YouTube in your browser when it's time for another coding with John, which was named by Dennis Edson. I did not come up with that name, but it's still fun. Anyway, thank you all. I'm glad my voice is soothing. Have a great weekend. Happy Friday. See y' all. Our page on YouTube. And you can click the notify button so that you get a notification from YouTube in your browser when it's time for another coding with John, which was named by Dennis Edson. I did not come up with that.










