spotifyovercastrssapple-podcasts

Lighthouse Scores

Lighthouse can show you a lot of low-hanging fruit to improve your site's performance. It also points out ways to make your site more accessible, follow best practices, and perform better with SEO.
November 30, 2020
#18

Performance metrics

Best practices

Performance best practices

  • CDN
  • Netlify

Image Optimization

  • Cloudinary
  • loading=lazy
  • SVG

Icons

PWAs

Performance

SEO

Resources

Transcript

[00:00:00]
Hello, Jeroen.
[00:00:01]
Hello, Dillon.
[00:00:03]
I think today we're going to eat our vegetables a little and instead of talking about opaque
[00:00:08]
types and fun stuff like that, we're going to talk about something that maybe not everybody
[00:00:13]
wants to talk about, but I think it's important.
[00:00:16]
I don't want to talk about vegetables.
[00:00:20]
Well, do you want to talk about lighthouse scores?
[00:00:24]
Oh, that's one.
[00:00:25]
Okay, yeah, yeah, sure.
[00:00:28]
Lighthouse sounds good.
[00:00:31]
Now that I talked about vegetables, doesn't lighthouse scores sound a lot more fun?
[00:00:35]
Well, it's good when they're green.
[00:00:40]
If you saute a lighthouse score, it's really crispy and nice.
[00:00:45]
Okay.
[00:00:46]
So, what is lighthouse, Dillon?
[00:00:49]
Well, lighthouse is a tool that is built into Chrome and it gives you some metrics
[00:01:00]
around your site performance and best practices and accessibility.
[00:01:05]
If you haven't tried it, then you should open up Chrome, go to the dev tools, click on the
[00:01:11]
lighthouse tab and generate a report and see how your site's looking.
[00:01:18]
It gives a lot of interesting information and lots of little low hanging fruit improvements
[00:01:24]
that you can make to your site.
[00:01:26]
Yeah.
[00:01:27]
So, this episode will be about tips around performance, right?
[00:01:30]
We'll get into performance.
[00:01:32]
We'll talk about some of the other things for having an Elm application or site that
[00:01:39]
uses best practices.
[00:01:42]
There's a lot to dig into.
[00:01:44]
Some of the things are more Elm specific and some of them are more general web practices.
[00:01:48]
Okay.
[00:01:49]
So, maybe let's go over what kind of metrics a lighthouse gives you.
[00:01:54]
Yeah.
[00:01:55]
Well, the thing that people see first and foremost when they open up a lighthouse report
[00:01:59]
is everybody wants to see the score.
[00:02:01]
Everybody wants to see a green number, not an orange or a red number.
[00:02:05]
Yeah.
[00:02:06]
Ideally, a hundred.
[00:02:07]
A hundred would be nice.
[00:02:10]
Yeah.
[00:02:11]
So, basically the way this works is it gives weight to certain...
[00:02:16]
So sometimes you can pretty drastically boost that number just by you were missing an alt
[00:02:22]
tag on an image and you add an alt tag and it dings you quite a bit for that.
[00:02:29]
There are some little low hanging fruit things that you can do to improve things.
[00:02:33]
So there's a performance metric and I believe the performance metric gives the most weight
[00:02:40]
to first contentful paint, cumulative layout shift and time to interactive.
[00:02:46]
Those are metrics that Google who maintain Lighthouse have been sort of tweaking over
[00:02:52]
the years to try to get more meaningful heuristics that better reflect a good user experience.
[00:03:02]
It's worth noting, we're often testing out our sites.
[00:03:07]
First of all, probably served locally.
[00:03:10]
Well, that gives me the best experience.
[00:03:12]
So why should I try it somewhere else?
[00:03:15]
Right.
[00:03:16]
It's served locally.
[00:03:17]
It's on a desktop computer.
[00:03:18]
It's on a multi thousand dollar machine.
[00:03:22]
Many people are accessing these things on a mobile device, maybe not even a high powered
[00:03:27]
mobile device depending on your user base.
[00:03:32]
It's going to be on a small screen.
[00:03:35]
Yeah, and not necessarily with a high quality, with a fast network.
[00:03:39]
Exactly.
[00:03:40]
They might be loading it with 3G.
[00:03:42]
And that's one of the things that Lighthouse does is it will throttle your network speed
[00:03:46]
to simulate a slow 3G network, which you can do in Chrome.
[00:03:52]
You can just go to Chrome or a Chrome based browser and you can go to the network tab
[00:03:58]
and you can turn on network throttling and see how that feels to use that simulated throttling.
[00:04:04]
So yeah, I think they've sort of arrived at these key metrics of first contentful paint,
[00:04:10]
cumulative layout shift and time to interactive as good measures of how users are going to
[00:04:15]
experience the performance of your site.
[00:04:18]
So first contentful paint would be if you get a loading screen to the user as fast as
[00:04:27]
possible or like the skeleton of your app, users perceive that as much faster than, for
[00:04:33]
example, if you had a blank screen that is clearly loading for a long period of time.
[00:04:43]
You prefer to see something rather than nothing.
[00:04:46]
Yes.
[00:04:47]
Users are extremely impatient, which is totally understandable if they don't have any indication
[00:04:51]
that things are happening.
[00:04:53]
And so first contentful paint is a measure that helps you sort of understand how quickly
[00:04:59]
do I get something on the screen that indicates that things are happening.
[00:05:03]
And these things have been studied quite a bit like in the ecommerce space in particular
[00:05:08]
where you can draw a direct connection between these types of metrics.
[00:05:14]
You know, your sales numbers and what's the term for people quickly backing out of a site?
[00:05:21]
I can't remember the bounce rate.
[00:05:24]
Bounce rate.
[00:05:25]
Exactly.
[00:05:26]
Exactly.
[00:05:27]
So sales are directly connected to these performance indicators.
[00:05:31]
So that's been well studied that you can have, you know, I don't know, a 10% increase in
[00:05:37]
sales on an ecommerce site for every however many, you know, 500 milliseconds or less.
[00:05:45]
I don't remember the exact numbers, but it's significant.
[00:05:48]
Yeah.
[00:05:49]
It almost feels absurd.
[00:05:50]
Like how much difference there is with such a small difference in speed.
[00:05:56]
Yeah, that just feels unreal to me.
[00:05:58]
Yeah, it is.
[00:05:59]
It is pretty amazing.
[00:06:00]
But also, you know, as a user, you can relate to it that you're waiting for a site to load
[00:06:07]
and you're just staring at a blank screen and you're just like, you know what?
[00:06:11]
I don't really need to do this right now.
[00:06:14]
Yeah.
[00:06:15]
Yeah.
[00:06:16]
In those five seconds where you have to wait for the page loading, you can revisit your
[00:06:19]
life's choices.
[00:06:20]
Do I really need to buy this?
[00:06:23]
Yeah, no.
[00:06:24]
Exactly.
[00:06:25]
Do I really want to buy this person a gift?
[00:06:29]
Maybe not.
[00:06:31]
Do I really like them that much?
[00:06:34]
Oh, it's loaded.
[00:06:36]
Okay, I guess I'll do it.
[00:06:37]
They didn't get me a gift for my birthday this year.
[00:06:41]
Yeah.
[00:06:43]
Yeah.
[00:06:44]
So that's first Contentful Paint.
[00:06:46]
And you know, you can do certain things like preloading or having a skeleton, you know,
[00:06:52]
that can help with that.
[00:06:53]
And you can see in Chrome when you do like performance benchmarks in the performance
[00:06:58]
tab, you can actually see the snapshots of the loading time.
[00:07:02]
So you can, which is pretty helpful.
[00:07:06]
Then we've got Cumulative Layout Shift.
[00:07:08]
That's like a more recent one that they've started to emphasize in these metrics.
[00:07:15]
And they used to call it Page Jank.
[00:07:19]
Oh, yeah.
[00:07:20]
There's like a classic example.
[00:07:22]
I actually have a Chase credit card.
[00:07:24]
So I've seen this many times that you go to like the Chase online like credit card site
[00:07:29]
to like redeem your rewards points.
[00:07:32]
And there's, you know, there are like 10 different spinners.
[00:07:36]
And little by little, each spinner is loading and the page is shifting around, you know?
[00:07:42]
Yeah, well, at least their first Contentful Paint is probably fast.
[00:07:46]
Exactly.
[00:07:47]
They got it fast.
[00:07:48]
Maybe they were looking at those lighthouse metrics and optimizing for the wrong thing.
[00:07:54]
And that's probably the kind of thing that was happening that Google's like, okay, people
[00:07:58]
started doing better on this one score, but how do we capture this thing that feels really
[00:08:04]
bad now in the user experience?
[00:08:06]
You know, there are certain things you can do to reduce that, you know, Cumulative Layout
[00:08:10]
Shift.
[00:08:12]
And we'll get into some of those.
[00:08:13]
But that's one that will make the site feel snappier and just less janky, less glitchy.
[00:08:20]
Yeah.
[00:08:21]
I looked up the documentation for Cumulative Layout Shift because I didn't understand the
[00:08:24]
term at first.
[00:08:26]
In the docs, they have a GIF, where someone wants to click on, don't buy this item instead
[00:08:34]
of buying.
[00:08:35]
So you got two buttons right on the right above each other.
[00:08:42]
And then right when they're about to click, no, there's a banner at the top popping up
[00:08:50]
which moves the button.
[00:08:52]
And so the person clicks on pay.
[00:08:54]
And then you see the mouse saying, oh no, oh no, it's moving all around and clicking.
[00:09:00]
No, no, no, no, no, no.
[00:09:01]
That's amazing.
[00:09:02]
That made me laugh so much.
[00:09:04]
It's in the official Google docs.
[00:09:10]
Sounds like something that Jake Archibald would do.
[00:09:14]
So that explained it to me very well.
[00:09:17]
There you go.
[00:09:18]
That's a perfect, perfect summary.
[00:09:19]
Yeah.
[00:09:20]
Love it.
[00:09:21]
The last big one that's, I think, heavily weighted in the performance metrics is the
[00:09:25]
time to interactive.
[00:09:27]
So first Contentful Paint captures how long it takes to initially get something on the
[00:09:32]
screen.
[00:09:33]
Time to interactive captures, and again, these scores have gotten better and better at reflecting
[00:09:39]
sort of real things that you feel as a user that make things feel more responsive and
[00:09:45]
snappy.
[00:09:46]
So time to interactive is one of those things that, you know, you go to a site, it initially
[00:09:51]
loaded something really quickly.
[00:09:53]
You know, maybe it doesn't have lots of layout jank, so it's got a good cumulative layout
[00:09:57]
shift score.
[00:09:58]
And then you go to click on a form field to type something in and nothing happens.
[00:10:03]
That's time to interactive.
[00:10:04]
So it's the amount of time until all of the sort of execution for initially setting up
[00:10:10]
the page have settled.
[00:10:13]
I have a hard time figuring out when that is a problem.
[00:10:17]
I mean, in practice, I've not seen pages where the page loads fast, but then it takes five
[00:10:24]
seconds for it to be interactive.
[00:10:26]
It actually can be.
[00:10:27]
So I mean, because, you know, JavaScript is a single threaded environment.
[00:10:31]
And so you've got all this work competing on the UI thread.
[00:10:37]
So what will happen quite often is you scroll and it's very shaky and it doesn't feel responsive.
[00:10:46]
That happens quite a bit.
[00:10:48]
It's one of those things that when you sort of have the term to describe it, you realize
[00:10:53]
how ubiquitous it is.
[00:10:54]
But when you don't have the term, you just feel somewhat frustrated and you don't know
[00:10:59]
why.
[00:11:00]
I really wonder how they test that.
[00:11:04]
I think it's like they wait until the latest large JavaScript execution has settled for
[00:11:12]
at least 100 milliseconds or something like that.
[00:11:15]
Okay.
[00:11:16]
Yeah.
[00:11:17]
I was expecting them to find a button or a text field and interacting with it.
[00:11:21]
Right.
[00:11:22]
Right.
[00:11:23]
Yeah.
[00:11:24]
Yeah.
[00:11:25]
And I think your metrics like pretty well capture things that are very much going to
[00:11:30]
give the user a better experience.
[00:11:32]
So I like the metrics they've arrived at.
[00:11:36]
And I think these are good terms to sort of keep in mind when you're trying to make these
[00:11:41]
improvements.
[00:11:42]
Yeah.
[00:11:43]
So who should be doing these optimizations and be paying attention to these things, Jeroen?
[00:11:48]
What do you think?
[00:11:49]
Well, the developers.
[00:11:51]
If there's only developers in your team, then I would say developers.
[00:11:55]
Like where is this relevant?
[00:11:56]
Where is it not relevant?
[00:11:57]
You know, is it relevant if we have a, you know, back office internal tool?
[00:12:03]
Is it less relevant there than other places?
[00:12:06]
Like who should care about this and who should care more, who should care less?
[00:12:11]
I would say the closer you are to the customer, the more you should care about it.
[00:12:15]
You probably shouldn't care too much about it for back office or internal tooling unless
[00:12:21]
it's very slow.
[00:12:23]
Which can happen.
[00:12:24]
Yeah.
[00:12:25]
Because you have not put any effort in the performance of the tool.
[00:12:30]
So yeah, then if your internal users are complaining, then yeah, do something about it.
[00:12:37]
Maybe Lighthouse could shed some lights on it.
[00:12:40]
Yeah.
[00:12:41]
And I agree that for back office tools, you don't need to get too crazy about optimizing
[00:12:47]
things.
[00:12:48]
But also if there's low hanging fruit, why not?
[00:12:52]
So I think that it's worth running Lighthouse.
[00:12:55]
I think just being aware of where things stand is a really great idea for any application.
[00:13:01]
And then I mean, certainly for, you know, as we talked about eCommerce, you can directly
[00:13:07]
connect that to your bottom line.
[00:13:09]
And you know, you should really be at that point, if you're an eCommerce company, then
[00:13:15]
you should really be taking this seriously and tracking it over time.
[00:13:19]
And you know, maybe keeping a performance budget and tracking big features and how they
[00:13:24]
affect that.
[00:13:25]
And aiming for that 100 score.
[00:13:27]
Yeah.
[00:13:28]
Yeah.
[00:13:29]
As far as that's possible, there may be limitations.
[00:13:32]
But at least being aware, I think everyone in every situation, you may as well be aware,
[00:13:38]
you may as well run Lighthouse and see what you find and see if there's low hanging fruit.
[00:13:42]
And you know, Lighthouse, you know, we talked about some sort of some of these metrics that
[00:13:47]
indicate a good user experience.
[00:13:49]
And that's one piece of it.
[00:13:50]
But Lighthouse will also, you know, I mean, if there are, you know, if you're not serving
[00:13:55]
things over HTTPS, they'll ding you for that.
[00:14:00]
Another
[00:14:01]
Incorrectly so.
[00:14:02]
Yeah, exactly.
[00:14:03]
Those are the kinds of things that I mean, whether it's back office or not, that's probably
[00:14:07]
a good thing that you should be aware of if there are issues like that.
[00:14:12]
Or if you have like SEO, if SEO is important, especially like on a marketing page and things
[00:14:17]
like that.
[00:14:18]
Lighthouse is going to tell you some basic SEO things that it's not going to give you
[00:14:23]
a comprehensive analysis of your SEO, but it'll give you some basic best practices.
[00:14:28]
Yeah.
[00:14:29]
All right.
[00:14:30]
Should we dive into some some specifics here?
[00:14:31]
Our performance?
[00:14:32]
Yeah, sure.
[00:14:33]
Yeah.
[00:14:34]
So, you know, one one low hanging fruit thing is just using a hosting provider.
[00:14:41]
Ideally, a CDN.
[00:14:42]
What is it?
[00:14:43]
Content Distribution Network?
[00:14:45]
Content delivery?
[00:14:46]
Content delivery network.
[00:14:47]
Yes.
[00:14:48]
Yeah, that sounds right.
[00:14:49]
You know, so something like, you know, I mean, I use Netlify quite a bit, and I've been very
[00:14:54]
pleased, you know, with their with their free tiers.
[00:14:57]
People say a lot of good things about Netlify, but there are there are other options as well.
[00:15:00]
But that's something that I think is a low hanging fruit performance improvement for
[00:15:05]
a lot of people.
[00:15:06]
Like one of the reasons that a CDN helps is that it it serves up your, you know, static
[00:15:12]
assets, your, you know, compiled Elm code and, you know, if you have your entry point
[00:15:18]
HTML, and it serves those assets at the edge.
[00:15:22]
So at the at the nearest location, rather than having to request something to a server
[00:15:29]
and send it back from AWS East or something like that, it's going to serve it at the nearest
[00:15:35]
servers, because it's just a static file.
[00:15:38]
So it doesn't need to hit a specific server in a specific location.
[00:15:42]
Yeah, it acts as a cache proxy, right?
[00:15:45]
Mm hmm.
[00:15:46]
Mm hmm.
[00:15:47]
Yeah, exactly.
[00:15:48]
CDN is effectively your everything is just cached because they're static files.
[00:15:53]
So there's no sort of intelligent caching to do for serving static files.
[00:15:58]
I mean, I'm sure there is plenty of optimizing they do around that.
[00:16:01]
But it's pretty simple, just put the files a bunch of places and serve them as fast as
[00:16:06]
you can.
[00:16:08]
And that'll take care of HTTPS and give you certificates.
[00:16:11]
And it's quite nice.
[00:16:12]
So I recommend taking a look at Netlify or similar CDN services.
[00:16:16]
Yeah, I think Netlify serves your your website.
[00:16:20]
But if you if you if you don't need it to serve your your server, you can use other
[00:16:26]
CDNs, which just acts as a proxy between your server and the user's computer, which Netlify
[00:16:35]
probably also does.
[00:16:36]
But I'm not aware of that.
[00:16:37]
Are you thinking of like, what is it cloud flare?
[00:16:40]
Or I haven't used those myself.
[00:16:42]
But that's the kind of thing we did at some of my previous workplaces.
[00:16:46]
Mm hmm.
[00:16:47]
Yeah, yeah, nice.
[00:16:48]
Yeah.
[00:16:49]
So those are some, you know, I mean, those are some things that don't require a ton of
[00:16:53]
engineering effort, but they'll give give you some performance gains that'll make Lighthouse
[00:16:57]
a little happier and make your users happier.
[00:17:00]
How do you make that work?
[00:17:02]
Because as you said, like, you just put a static file on a CDN, or you have it serve
[00:17:08]
your file.
[00:17:09]
But what if your file changes?
[00:17:10]
Like what if my index.html has changed since I since it was last served on a CDN?
[00:17:18]
Well, for like an index.html, it's, it's not going to do file based hashing, because that's
[00:17:25]
the entry point.
[00:17:26]
That might be a bad example.
[00:17:28]
But for something like an image, you can certainly, you know, use tools, you know, have a webpack
[00:17:32]
config that uses file based hashing and sets like a long cache period and uses the file
[00:17:39]
name for cache busting.
[00:17:41]
Yeah, there's a whole set of practices around that.
[00:17:44]
Yeah, so adding the hash to the file name, and replacing every occurrence of that in
[00:17:49]
your source files, CSS, HTML, JavaScript files, right?
[00:17:55]
So that whenever your file changes, you get a new hash or version number for that file.
[00:18:02]
So you don't request the old file anymore.
[00:18:07]
For images.
[00:18:08]
So one of the, you know, one of the biggest areas of low hanging fruit for these performance
[00:18:14]
improvements on a lot of on a lot of websites is images because yeah, you know, if you're
[00:18:20]
serving like a big one megabyte image, which is not uncommon that you know, some somebody
[00:18:25]
doesn't really think about that, and they just put the image there.
[00:18:28]
Okay, it is really important that our JavaScript files are less than 100 kilobytes, right?
[00:18:35]
Big, right, right, and then you do a lot of work to make that work.
[00:18:39]
And then someone puts very big images on your website.
[00:18:45]
Now actually, that said, there is a much greater cost to, you know, per kilobyte of JavaScript
[00:18:52]
versus images because images, yeah, they're just rendering them.
[00:18:55]
Whereas JavaScript, you know, when when the JavaScript comes down the wire, you decompress
[00:19:01]
the asset that just loaded.
[00:19:02]
So even if it's, you know, whatever, it's like 100 kilobytes, compressed and 200 kilobytes
[00:19:09]
uncompressed.
[00:19:10]
Well, now that that's computation that needs to be done to decompress it.
[00:19:16]
So sure, you saved some, you know, bandwidth over the wire, which is great, but there's
[00:19:20]
computation to be done.
[00:19:22]
Now once it, you know, decompresses that it needs to, it needs to exactly it needs to
[00:19:28]
parse it and then execute it.
[00:19:31]
So it's extremely expensive per kilobyte of JavaScript.
[00:19:34]
Yeah.
[00:19:35]
And until it has all been decompressed, read, parsed, executed, you don't have anything
[00:19:43]
to show.
[00:19:44]
Yeah, well, that's yes.
[00:19:46]
Yes.
[00:19:47]
And at least in Elmland.
[00:19:49]
So that impacts the first contentful paint, right?
[00:19:53]
Right.
[00:19:54]
Unless you're doing some sort of pre rendering.
[00:19:55]
And that's that's another that's another topic.
[00:19:58]
But and we'll get into some of those things a bit.
[00:20:00]
Yeah, you can have a big size gains for images at least.
[00:20:05]
Yes.
[00:20:06]
So for images, what what I've started doing that I've been really happy with is using
[00:20:13]
Cloudinary and there are other similar services.
[00:20:16]
I haven't used other ones, but I've been very happy with Cloudinary.
[00:20:19]
You just, you know, upload your image assets there and it takes care of serving up a performant
[00:20:27]
optimized image.
[00:20:28]
And so like the way that it works with Cloudinary, you upload the image and then they have like
[00:20:34]
a URL based API for saying I want it at this width.
[00:20:38]
I wanted it this height.
[00:20:39]
I want it at this quality, this format.
[00:20:42]
And on their servers, they'll take care of doing it.
[00:20:45]
And it's I mean, that's what they do.
[00:20:46]
So they're able to optimize these images extremely quickly.
[00:20:50]
Do they also cache it through a CDN for you?
[00:20:54]
Yeah, I mean, I think the the serving is all they they take care of all of that for you.
[00:20:59]
So it's served up as efficiently as possible.
[00:21:02]
And not only that, but like you can set automatic quality, which is quite handy.
[00:21:09]
So you can say, I'm going to serve it at these dimensions, this width and this height.
[00:21:13]
But you pick the best quality that basically, you know, if you can compress it to 20% quality
[00:21:21]
and it's going to not deteriorate the quality noticeably, then fine, like I'll leave that
[00:21:26]
to you instead of just picking a quality number and going for that.
[00:21:30]
It will it also gives you the ability to do auto format.
[00:21:35]
So to automatically pick an image format.
[00:21:38]
And so what that will do is based on the incoming request, it can tell the agent, the user agent.
[00:21:46]
So it can tell if it's loading from Chrome or Safari.
[00:21:49]
And then it's going to, you know, if it's on a browser that doesn't support WebP, then
[00:21:54]
it's going to serve a JPEG.
[00:21:57]
If it's coming from Chrome, which supports WebP, then it'll use WebP, which, you know,
[00:22:02]
compresses down a lot smaller.
[00:22:03]
Okay.
[00:22:04]
I think we should say that this was not paid advertiser.
[00:22:10]
Unless you want to Cloudinary.
[00:22:13]
Unless they want to pay us.
[00:22:14]
Yeah, feel free.
[00:22:16]
And until they do, there are probably alternatives to this.
[00:22:21]
Right.
[00:22:22]
Yeah, I haven't played around with alternative solutions, but I've been very happy with Cloudinary
[00:22:28]
and just in general, this approach of offloading that work to, you know, some service that
[00:22:34]
just does that very well.
[00:22:36]
I think it makes a lot of sense.
[00:22:38]
I recently, you know, with Elm pages, I was doing a lot of like sketching for an API to
[00:22:46]
allow you to sort of specify image optimizations to perform a lot like Gatsby's image optimization
[00:22:52]
API.
[00:22:53]
I had this realization, you know, some like Chris Biscardi, who's worked on some Gatsby
[00:22:59]
features and has his own static site generator tool now influenced my thinking on this a
[00:23:04]
lot with talking about like this bloat that comes from doing image optimization during
[00:23:10]
your build step.
[00:23:12]
It adds a lot of time to your build step.
[00:23:14]
So I mean, there are other ways to do this.
[00:23:15]
There are like you can wire up a GitHub action to go into your GitHub repository and optimize
[00:23:21]
images.
[00:23:22]
But in general, like just optimizing some an image during your build step is going to
[00:23:28]
bloat your build quite a bit.
[00:23:31]
And it's probably not going to do as good a job as something like Cloudinary or a similar
[00:23:36]
service, especially if you're trying to load it at, you know, 10 different responsive breakpoints.
[00:23:42]
And that's like sort of another area that can really give you some like serious wins
[00:23:47]
is like if you're on I mean, let's say you have like a I don't know, a photography portfolio
[00:23:53]
site, right?
[00:23:54]
And you want like really crisp, clean photos, but somebody's viewing it on a tiny phone.
[00:24:01]
You don't want to serve the, you know, 4000 pixel wide, ultra HD, high res version, right?
[00:24:09]
Maybe they're missing out if you don't do that.
[00:24:15]
In many cases, they're going to have a worse experience, you know, waiting for it.
[00:24:20]
And you know, the size may not even be perfectly suited to display properly because there aren't
[00:24:27]
enough pixels to display.
[00:24:28]
So it's better to have the correct number of, you know, correct width.
[00:24:33]
So just, I mean, I just felt a big relief giving up on the idea of doing that in my
[00:24:39]
build process and just making that someone else's problem.
[00:24:43]
And like for the elmradio.com website, I actually made a change recently where I moved the assets
[00:24:49]
over to Cloudinary and I made like a little responsive image helper.
[00:24:53]
So it sets the source set, SRC, SET to give you all these different breakpoints for the
[00:25:01]
image.
[00:25:02]
So it's going to, and then it just tells Cloudinary like, all right, like if it's a device with
[00:25:07]
at least this width, then serve it at this Cloudinary URL, which specifies the width.
[00:25:13]
And it says automatically pick a quality for me, automatically pick an image format for
[00:25:18]
me.
[00:25:19]
It just says, this is the width.
[00:25:20]
It's super easy to write a little elm function that does that for you.
[00:25:23]
And you're just like, you're going to end up with way better performance and it's going
[00:25:30]
to be way easier than trying to like set up all these scripts to optimize images for you
[00:25:35]
and stuff.
[00:25:36]
So I was very happy to like just give up on the idea of having my own build tasks to do
[00:25:43]
that work.
[00:25:44]
Yeah.
[00:25:45]
And now you deploy much faster too.
[00:25:46]
Well that's, yes.
[00:25:47]
Oh man, that was an interesting, I still have not solved the mystery of this one line change
[00:25:54]
I made in the Elm pages source code that took our Elmradio.com builds from like 15 minutes
[00:26:03]
to under two minutes.
[00:26:07]
Still have not solved that mystery, but it's faster.
[00:26:10]
So I'm happy.
[00:26:11]
And then on the topic of images.
[00:26:13]
So another sort of low hanging fruit thing you can do is this lazy image loading.
[00:26:19]
So I think you just say like lazy equals true or something, right?
[00:26:24]
On the image attribute.
[00:26:25]
I actually don't know what that does.
[00:26:29]
Oh, you're not familiar with it.
[00:26:31]
Okay.
[00:26:32]
And I looked up the syntax to refresh my memory and it's, so in your IMG tag, you say loading
[00:26:38]
equals lazy.
[00:26:40]
And that's supported in Chrome, Edge, Opera, Firefox, and the Safari implementation is
[00:26:47]
in progress.
[00:26:48]
It's going to degrade gracefully and just not do anything on browsers that don't support
[00:26:52]
it.
[00:26:53]
So what it does is if an image is scrolled into the viewport that you're currently viewing
[00:27:00]
on the page, then it will make sure to load it.
[00:27:03]
If it's not, then you scroll down and it starts to load it.
[00:27:07]
So it doesn't, so if you know.
[00:27:09]
That's how it's done.
[00:27:10]
Okay.
[00:27:11]
Oh, that's much simpler than I thought.
[00:27:13]
It's extremely simple.
[00:27:14]
I mean, for the most part, there's not really a reason to not do that.
[00:27:21]
There may be some cases where you, you know, maybe you don't have a ton of image assets.
[00:27:25]
There's just like one extra image and it's not worth that small savings to, you know,
[00:27:31]
scroll and then see it pop into appearance.
[00:27:35]
But you may as well play around with it and see how it feels.
[00:27:39]
And on the topic of image optimization, a really big win is if you can use an SVG instead
[00:27:46]
of a JPEG or PNG.
[00:27:49]
It's just going to give you, it's purely a win.
[00:27:52]
It gives you the best quality and performance.
[00:27:56]
Is it smaller in size always?
[00:27:58]
Generally it's going to be smaller in size.
[00:28:00]
I mean, perhaps if you have like an extremely complex shape, there could be certain instances
[00:28:07]
where it's not going to be as optimal.
[00:28:10]
But for the most part, and especially with like more simple shapes and logos, it's overall
[00:28:16]
going to be a big win in most cases.
[00:28:18]
Yeah.
[00:28:19]
Especially if you try to make the image very big.
[00:28:21]
Then you don't have to download the big image.
[00:28:25]
You just have to download, well, the same thing as for a small icon or the small image.
[00:28:32]
Sometimes I look at the HTML files of websites and I see some icons for Mac, I think, with
[00:28:39]
a lot of...
[00:28:40]
Like 40 of them?
[00:28:41]
Yeah, 40 of them with different sizes and all.
[00:28:44]
Do you know what that is all about?
[00:28:46]
I do.
[00:28:47]
I know it all too well.
[00:28:51]
You say with such enthusiasm.
[00:28:56]
Good times.
[00:28:57]
Andrew, I know about these icons just as well as I know ISO 8601.
[00:29:02]
I love when you say that.
[00:29:08]
These icons, it's one of these things that's gotten a little bit unwieldy where you have
[00:29:12]
an Apple touch icon and you have an icon for a Microsoft phone and for whatever device.
[00:29:23]
It's a lot like these vendor prefixes in browsers where you start having your CSS be like, oh,
[00:29:31]
Firefox has this one CSS feature and Chrome implemented it differently so you can fine
[00:29:38]
tune it based on these slightly different implementations and things like that.
[00:29:42]
It's very similar to that.
[00:29:43]
It's the kind of thing where a lot of the tags that are put on there are for iOS 5 and
[00:29:50]
iOS 5 has certain requirements that the icon that it would use if you create a bookmark.
[00:29:58]
You create a bookmark and now it's on your home screen and that's the icon it's going
[00:30:03]
to use for that.
[00:30:04]
Then if you create a bookmark on a Microsoft computer, then it's going to use a different
[00:30:11]
asset.
[00:30:12]
There are these services that will just generate those for you.
[00:30:17]
That's for an older version of iOS?
[00:30:19]
There are ones for older versions and then there are ones for newer versions.
[00:30:24]
It is still recommended and Lighthouse will ding you if you don't include certain ones.
[00:30:29]
You may be shocked, Jeroen, but I used Cloudinary to generate those for the elmradio.com site.
[00:30:38]
I'm so shocked.
[00:30:44]
It's just one of those things that you just get the right ones and get them on there and
[00:30:51]
it makes Lighthouse happy.
[00:30:53]
Who knows, maybe nobody will add your site as a bookmark and it will never make a difference,
[00:30:59]
but at least Lighthouse will be happy about it.
[00:31:03]
I imagine that I would add them until Lighthouse stops letting me know about problems.
[00:31:10]
That's a reasonable way to go.
[00:31:12]
I've been trying to encapsulate that in a little helper function and as something that
[00:31:17]
can be shared for Elm pages sites.
[00:31:22]
There's another set of icons that Lighthouse will tell you about.
[00:31:27]
Retina?
[00:31:28]
Yes.
[00:31:29]
You've got in the manifest.json.
[00:31:34]
The manifest.json is just a JSON file with a specific format of data that it expects.
[00:31:44]
That data is to tell it about a so called progressive web app.
[00:31:51]
What that means is if your website meets certain criteria, served over HTTPS, has a service
[00:31:59]
worker, I think it may even need to meet certain performance attributes, but it certainly needs
[00:32:07]
to be secure.
[00:32:09]
You can't run a service worker on a page if it's not served over HTTPS because it's a
[00:32:17]
man in the middle.
[00:32:18]
It can intercept HTTP requests and change them.
[00:32:24]
It acts as a proxy, the service worker.
[00:32:25]
It can intercept those and tweak them and give its own responses.
[00:32:30]
It needs to be served over HTTPS.
[00:32:33]
If you have a website that meets those criteria enough to be deemed a progressive web app
[00:32:40]
by the browser that your user is loading your site in, then they will be presented with
[00:32:47]
an option to install your site as an app.
[00:32:52]
Or they can just go in and manually save it on an iPhone.
[00:32:58]
In Safari you say save to home screen.
[00:33:01]
I think the same thing on Android.
[00:33:05]
If you do that, then there are a few things that are going to feel more like a native
[00:33:11]
app.
[00:33:12]
It's going to have a splash screen when you load the app, just like a native app would.
[00:33:16]
It's going to have an icon that's supposed to look like a regular app icon.
[00:33:22]
So you need that set of icons that you specify.
[00:33:25]
The manifest.json has a set of icons.
[00:33:27]
You can set certain things like does it have a URL bar or not.
[00:33:33]
If you want it to feel more like a native app, you can opt out of the URL bar so you
[00:33:37]
can configure certain things like that.
[00:33:39]
You can set categories for listing it in certain app stores.
[00:33:44]
Microsoft has, I think, gone all in on making progressive web apps installable.
[00:33:51]
So I think the official Windows Twitter app is just a progressive web app.
[00:33:59]
It's just their twitter.com.
[00:34:03]
It's pretty cool.
[00:34:04]
There's varying support for progressive web apps, but it's quite a neat approach.
[00:34:10]
The Twitter web app is the only one that I've used until now.
[00:34:13]
I find it much better than the native application.
[00:34:18]
So that's a good example.
[00:34:19]
Yeah, I mean it makes sense.
[00:34:22]
Just this concept of a progressive web app makes sense because you go to a site, maybe
[00:34:27]
you're not going to use it forever.
[00:34:29]
Maybe it's like a conference page or some event.
[00:34:36]
You don't want to install a whole app or create a whole app for that, but you can have a service
[00:34:40]
worker and set it to make certain assets available offline.
[00:34:45]
So that's a whole other can of worms of how you approach caching those assets for offline.
[00:34:55]
I'm working on an API for Elm pages where you can sort of specify which pages should
[00:35:01]
be available with which cache policies.
[00:35:04]
Available upon install, cached as soon as they're loaded, and then available offline
[00:35:10]
after that.
[00:35:12]
You can do stale while revalidate, which means every time you request the asset, you immediately
[00:35:19]
request the fresh copy of that, but then you serve up the old copy that you have cached
[00:35:25]
if you have one.
[00:35:26]
Yeah, in the meantime.
[00:35:28]
So there are all these different cache strategies.
[00:35:31]
There are tools like Workbox is this Google tool that gives you a more high level way
[00:35:36]
of working with the service worker API and specifying specific assets to be cached and
[00:35:43]
generating a sort of manifest that tells you which files need to be cache busted in the
[00:35:52]
latest service worker and maintaining things like that.
[00:35:56]
It's complex and it's very difficult to get a service worker right to get that caching
[00:36:02]
done right for an offline experience.
[00:36:04]
I mean, I think it's a really exciting space, this area of progressive web apps.
[00:36:09]
Yeah, definitely.
[00:36:11]
So Lighthouse actually tries to run your website as a progressive web app.
[00:36:15]
It will tell you when it does and when it doesn't.
[00:36:18]
So I tried running it on Elm Radio and it is not a progressive web app and tells you
[00:36:24]
it is not because it does not do this, it does not do this.
[00:36:29]
So essentially, yeah, it doesn't give you a 200 response when it loads the main landing
[00:36:34]
page, if it's offline.
[00:36:38]
And yeah, on Elm pages, so elmradio.com is built with Elm pages and I don't have any
[00:36:45]
service worker stuff right now because I want to sort of create a really good service worker
[00:36:50]
API.
[00:36:52]
It's an inherently complex problem to figure out the cache policies for things.
[00:36:58]
It's not getting an offline ready web application is not like a drop in thing.
[00:37:05]
What if you're making dynamic HTTP requests to some real time data?
[00:37:12]
What you do not be cached to.
[00:37:13]
Yeah, exactly.
[00:37:14]
You can't cache that.
[00:37:16]
So you can go as far as having a local database and sending and syncing data.
[00:37:26]
There's like a service worker API for syncing data.
[00:37:29]
So the service worker will sort of store that data.
[00:37:35]
If you add something to your shopping cart and then you're offline and then you get online
[00:37:42]
again and it notices that there's something that's not been synced and it makes that request
[00:37:48]
to get it in sync.
[00:37:50]
That's not a drop in feature that you just say, please make this a service, please make
[00:37:56]
this an offline ready progressive web app.
[00:37:58]
That's something that requires a thoughtful design to make these sort of user experience
[00:38:04]
and technical decisions.
[00:38:08]
So I'd like to give a good API for doing that sort of thing with Elm pages, but I want to
[00:38:15]
do it right and I want to give that the attention it deserves.
[00:38:19]
So once that's done, I think it would be super cool to have the ability to make a little
[00:38:25]
offline ready page that you can install as an app.
[00:38:27]
Yeah, definitely.
[00:38:28]
What I really like with Lighthouse is that it tells you about all those things that are
[00:38:32]
missing or that are not great.
[00:38:36]
Now I know just by reading that what I need to do to make it a progressive web app and
[00:38:42]
there are links to documentation and all that.
[00:38:44]
I found that really helpful.
[00:38:46]
It's almost like static analysis tool.
[00:38:48]
Right.
[00:38:49]
Yeah.
[00:38:50]
You like static analysis tools?
[00:38:54]
I think they can be useful, but you shouldn't overdo them.
[00:38:58]
You shouldn't spend too much time working on those, I think.
[00:39:02]
Probably.
[00:39:03]
Yeah.
[00:39:04]
Yeah.
[00:39:05]
So on this topic of progressive web apps and offline ready, Luca Mugg has this Elm starter
[00:39:15]
project that he's built and it takes care of that.
[00:39:21]
The idea is to make it a lightweight wrapper around a plain Elmap that you don't build
[00:39:28]
it to this frameworks API, but you just drop in a few things and connect it to an Elmap.
[00:39:34]
So that's something to look into if you want to just take a landing page that's an Elmap
[00:39:39]
and it's not going to help you sort of set up syncing your offline transactions and stuff
[00:39:46]
in the background and things like that.
[00:39:48]
That's not the intention, but it's more like here's an Elmap and I want you to be able
[00:39:52]
to install this and load it offline.
[00:39:55]
Yeah.
[00:39:56]
It's a great tool for helping you do that.
[00:39:59]
Yeah.
[00:40:00]
Or a good resource if you need to go further.
[00:40:02]
Right.
[00:40:03]
Definitely.
[00:40:04]
Do you want to go over what else Linus gives us?
[00:40:09]
So what I see is that it gives information about multiple topics.
[00:40:14]
So one of them is performance, which we've covered already.
[00:40:18]
Maybe not in full, but we've covered it.
[00:40:19]
There's a lot.
[00:40:20]
You can go down a lot of rabbit holes with performance.
[00:40:24]
Yeah, I think so.
[00:40:26]
Three others are accessibility, SEO and best practices.
[00:40:32]
I have no clue, but best practices actually.
[00:40:35]
Right.
[00:40:36]
Maybe before we move on from performance, it's worth just noting a couple of last things.
[00:40:42]
One is make sure that you're using dash dash optimize when you build your Elm bundle.
[00:40:50]
And also make sure that you're using Terser to do the minification and dead code removal.
[00:40:57]
Is there any difference between Terser and Uglify or Uglify JS?
[00:41:02]
Terser is like the new way of doing it.
[00:41:06]
Uglify has since been deprecated, but it's effectively the same.
[00:41:10]
Yeah.
[00:41:11]
And I think Terser worked with ES6 or ES2015, which we don't care about for Elm, but yeah.
[00:41:18]
So that's like a low hanging fruit.
[00:41:20]
If you're not doing that, you really should.
[00:41:24]
If you try to use the dash dash optimize flag in your Elm app and it's complaining, then
[00:41:29]
remove those debug.logs and those debug.todos from your production app.
[00:41:37]
It's worth taking the time to do that.
[00:41:39]
Help your Elm code not crash.
[00:41:41]
Yeah.
[00:41:42]
Also Matt Griffith and Simon Twop have done this really cool project, Elm Optimize Level
[00:41:49]
2.
[00:41:50]
And that's worth checking out.
[00:41:54]
You could try it out, see how it affects your performance score.
[00:41:56]
It's just something that you use to compile your Elm app and it runs some sort of static
[00:42:02]
optimizations on the JavaScript output that make it run better in the JavaScript runtime.
[00:42:07]
Pretty cool project.
[00:42:08]
I think it tries to optimize for speed, but not necessarily size.
[00:42:13]
Am I correct?
[00:42:15]
That might be correct.
[00:42:16]
Yeah.
[00:42:17]
It's definitely worth looking at what numbers it gives you.
[00:42:22]
Like most things when you do work with performance, run benchmarks.
[00:42:25]
Exactly.
[00:42:26]
Exactly.
[00:42:27]
That's right.
[00:42:28]
Yeah.
[00:42:29]
And a really good tool too for performance benchmarking is if you go to the performance
[00:42:33]
tab in your dev tools, you can...
[00:42:37]
In your browser?
[00:42:39]
Yes.
[00:42:40]
Right.
[00:42:41]
Then you can go to hit this little record button and it will capture the JavaScript
[00:42:46]
execution and which functions are taking the longest.
[00:42:52]
We can link...Julu has a really great blog post that talks about how to analyze performance
[00:42:58]
bottlenecks in Elm.
[00:43:00]
I've used that technique many times and if you're finding that you have some performance
[00:43:05]
bottleneck somewhere, that's quite a useful technique.
[00:43:07]
And then one last point about performance.
[00:43:13]
If you have...HTTP2 kind of had this HTTP push concept of you request a certain page
[00:43:21]
and your server is able to say, oh, you requested this page, but since it's that page you requested,
[00:43:27]
I know some other assets you're going to need, so let me send those over to you.
[00:43:31]
Now that has sort of failed.
[00:43:34]
That spec has had some failures and it's turned out, I think essentially the bottom line is
[00:43:41]
technically it was extremely difficult on the server side.
[00:43:45]
It was difficult to implement that consistently serving up the correct assets.
[00:43:50]
And now the recommended practice is...like Netlify, for example, used to have support
[00:43:55]
for HTTP to push and they dropped that some time ago.
[00:44:00]
The recommended practice these days is to use preload tags.
[00:44:04]
And so preload tag is just a link tag that you put in your head of your HTML.
[00:44:10]
It's link rel="preload", href="something.js", as script.
[00:44:16]
We'll put a link to something with more information about that.
[00:44:20]
But that's another thing that can sort of help.
[00:44:24]
So what that does is you don't need to execute all this code to know what assets are going
[00:44:30]
to need to be fetched because what the browser is doing is it's parsing everything in order
[00:44:38]
to figure out what it needs to fetch.
[00:44:39]
But if it sees a preload tag before it parses it and figures out the dependency tree, you're
[00:44:44]
giving it a hint that says, hey, by the way, as soon as you see this in the head tag, go
[00:44:49]
and fetch this asset, you're going to need it.
[00:44:52]
So that's a helpful thing.
[00:44:53]
So does it fetch it before other things that are more urgent or does it wait until everything
[00:44:59]
else has been downloaded?
[00:45:02]
There are different priorities for the fetches and I think it'll give it some sort of medium
[00:45:09]
priority, not necessarily the highest priority, but it will do its best to squeeze that in
[00:45:14]
there so it's ready when it needs it.
[00:45:16]
But the way that rendering an HTML page works is there are certain things that need to be
[00:45:23]
done before it can continue with execution.
[00:45:26]
So if you put a script tag in your head tag, then what it's going to do, so you say script
[00:45:32]
and then you link to some source for the script.
[00:45:36]
So you fetch the HTML, it has that script tag, so now it's parsing the HTML because
[00:45:44]
it doesn't understand it yet, it needs to parse it.
[00:45:47]
And it gets to that script and then it says, uh oh, I can't do anything else until I've
[00:45:53]
fetched, decompressed and evaluated this JavaScript code because the JavaScript code could modify
[00:46:04]
the HTML page that it's going to render.
[00:46:07]
And that JavaScript code also, the next script that's in there could also be dependent on
[00:46:13]
the previous one.
[00:46:14]
You have to load jQuery before you load the main script.
[00:46:18]
So in order to prevent that, you can use the defer tag on scripts and we'll link to a resource
[00:46:28]
about the Google web performance team's recommendations on that.
[00:46:34]
There are a lot of different resources that talk about how to do this, but in a nutshell,
[00:46:40]
it tends to work pretty well if you added a defer tag to the script, because what that's
[00:46:44]
going to do is it's just going to say, you know what, you don't need to block rendering
[00:46:49]
the rest of the HTML and continuing to fetch all of the images and scripts and assets that
[00:46:56]
you determine need to be fetched.
[00:46:58]
You can just come back to this JavaScript when you get there and load it when you're
[00:47:04]
done showing the page initially.
[00:47:06]
Please do my first contentful paint first.
[00:47:10]
Now if that's just like an empty HTML page, then you might want to prioritize that differently.
[00:47:17]
So I mean, pre rendering Elm starter, it does some pre rendering and Elm pages does pre
[00:47:23]
rendering.
[00:47:24]
So if you are doing some sort of pre rendering Elm pages just does this script defer for
[00:47:31]
you.
[00:47:32]
So it will give you a faster first contentful paint.
[00:47:35]
Okay, so that's good for performance.
[00:47:38]
Yeah.
[00:47:40]
So maybe let's talk about SEO then.
[00:47:43]
From what I can tell from the latter's report, SEO tells you more about things like user
[00:47:50]
experience, especially with regards to mobile, for instance, like making sure that your page
[00:47:59]
shows up correctly on a smaller device than if it was on a desktop device.
[00:48:04]
I think that would be under best practices.
[00:48:06]
Really?
[00:48:07]
I see it under SEO like the meta name viewport.
[00:48:12]
I don't know.
[00:48:13]
Oh, you're right.
[00:48:14]
It is under SEO.
[00:48:15]
Interesting.
[00:48:16]
I guess I did know then.
[00:48:18]
Great.
[00:48:19]
I do see that one under there.
[00:48:21]
That's interesting.
[00:48:22]
I'm not sure why.
[00:48:24]
But yeah, so I guess yeah, it's saying to do to make it mobile friendly under SEO.
[00:48:29]
Oh, you know what?
[00:48:30]
You know why it's under there?
[00:48:32]
Because otherwise Google will declassify you in search results, I'm guessing.
[00:48:38]
Exactly.
[00:48:39]
Yeah, exactly.
[00:48:40]
Yep, that's right.
[00:48:41]
It will ding you in your page ranking if you violate these certain basic mobile friendly
[00:48:48]
metrics.
[00:48:49]
Yeah.
[00:48:50]
So if you care about SEO, you really want a good score on this.
[00:48:53]
And is it possible to get 100?
[00:48:55]
I don't know if it's easy.
[00:48:57]
I'm guessing you just mostly...
[00:49:00]
It's fairly easy.
[00:49:01]
Yeah, it's fairly easy.
[00:49:03]
Yeah.
[00:49:04]
And one thing like with, you know, responsive pages.
[00:49:08]
So yeah, there's that little magic incantation, that tag that you put in there that just makes
[00:49:15]
Google happy.
[00:49:16]
The metaname viewport and the, you know, initial scale and all that.
[00:49:22]
Which I know nothing about, but there is a link.
[00:49:24]
So I'm guessing that I could learn more under the learn more link.
[00:49:29]
Yeah.
[00:49:30]
We'll include a link to that.
[00:49:32]
It's just one of those things you do that...
[00:49:34]
So sometimes what will happen, people used to do things like disabling zooming in on
[00:49:43]
a page.
[00:49:44]
Have you ever gotten to pinch to zoom on a web page on your mobile browser and it won't
[00:49:50]
let you zoom?
[00:49:51]
That's a good point.
[00:49:53]
It's really, it's bad.
[00:49:55]
It's also bad for accessibility.
[00:49:57]
So if somebody, you know, doesn't have perfect vision, you know, if they're visually impaired,
[00:50:03]
then they may need to zoom.
[00:50:04]
Also if you're not visually impaired, you may need to zoom.
[00:50:07]
It's just like, you know, accessibility is something that's good for everybody.
[00:50:13]
And some of these basic things that Lighthouse tells you about are good ideas in general.
[00:50:18]
So that's, yeah, you just put that magic incantation and it's going to set aside that full width
[00:50:25]
on mobile and look good there.
[00:50:27]
And for making responsive web apps.
[00:50:29]
So like if you're using Elm UI, you want to be careful about making sure you're wrapping
[00:50:33]
things in paragraphs as needed because a paragraph is going to not overflow, but it's going to
[00:50:40]
wrap.
[00:50:41]
So basically anytime you load your mobile app and there's an overflow where you like
[00:50:47]
have to scroll to the side and like part of the text hangs off of the page, that's a bug,
[00:50:53]
right?
[00:50:54]
So Lighthouse will tell you about that.
[00:50:56]
Nice.
[00:50:57]
Under SEO or under accessibility?
[00:51:00]
Maybe under SEO.
[00:51:01]
Yeah.
[00:51:02]
Those are important ones to get right.
[00:51:03]
And then some of the more, you know, what we think of as more typical SEO things like
[00:51:09]
getting the right metadata on your page.
[00:51:12]
You know, there are some basic ones like, you know, you're supposed to put a language
[00:51:15]
on your document.
[00:51:18]
So put that in your HTML.
[00:51:20]
You're supposed to put a canonical URL.
[00:51:22]
So what a canonical URL is, this is actually important to get right.
[00:51:28]
You can be penalized quite severely if you get this wrong.
[00:51:32]
If you have your site hosted in multiple pages or if you have like any duplicate, you know,
[00:51:37]
pages or places where you serve up a site, Google will flag that as potentially being
[00:51:43]
spam and it can be really bad for your search rankings.
[00:51:48]
Like they can put you, they can punish you for that.
[00:51:52]
And so you need to, if you have duplicate content and duplicate places where you host
[00:52:00]
the same site, you need to have a canonical URL.
[00:52:03]
And what that's saying is, yes, this page is in two different places, but this is the
[00:52:08]
main one.
[00:52:09]
Like if somebody searches on Google, show them this one because this is like the proper
[00:52:14]
URL for this.
[00:52:16]
Gotcha.
[00:52:17]
Yeah.
[00:52:18]
So that makes me think about, that makes me wonder, should I run Lighthouse on a single
[00:52:24]
page of the website or should I run it on several pages?
[00:52:28]
Because it can, like my homepage could be great, but when I go to the about page or
[00:52:33]
contact page, whatever, it might tell me there are plenty of problems.
[00:52:39]
That's a good question.
[00:52:40]
Does Lighthouse even try to crawl your website or?
[00:52:43]
I don't believe it does.
[00:52:44]
I don't think so either, but.
[00:52:45]
I'm not sure if webpagetest.org does either.
[00:52:49]
Webpagetest.org like runs these Lighthouse metrics, but it actually will perform them
[00:52:54]
on like mobile devices.
[00:52:56]
And there are some different tools like this that I don't think they do that, but it's
[00:53:00]
not a bad idea.
[00:53:01]
Yeah.
[00:53:02]
I think of this as like an art more than a science that, you know, it's just like the
[00:53:07]
more information, the better.
[00:53:08]
And you know, yeah, you may as well run it, run it on multiple pages.
[00:53:13]
So I've thought a lot about like these sort of open graph SEO things and that sort of
[00:53:20]
thing.
[00:53:21]
So we can talk a little bit about that.
[00:53:22]
In a nutshell, I think that if you have a marketing page, a conference website, a portfolio
[00:53:29]
page, a blog, you know, if I send you a link to a blog post that I wrote, you know, or
[00:53:36]
I send you a link to my resume site or something like that, I don't want to send you the link
[00:53:41]
and then in Slack it like doesn't unfold properly or on Twitter it like gives you an anti climactic
[00:53:50]
preview.
[00:53:51]
Yeah.
[00:53:52]
That it just, it feels unprofessional to me.
[00:53:56]
And if I put in time and effort to make a polished site or blog post or whatever, I
[00:54:02]
want a nice preview because previews like previews just make things look more official
[00:54:08]
and authoritative.
[00:54:12]
To me, I don't trust links if they don't have a good preview.
[00:54:17]
So you don't trust any links to my blog site?
[00:54:22]
Do they not have?
[00:54:23]
I did not put any effort into that.
[00:54:27]
It may have it.
[00:54:28]
It may have it.
[00:54:29]
I think it does, but the logo.
[00:54:31]
It might have the Gatsby logo on it.
[00:54:33]
Yeah.
[00:54:34]
It has the Gatsby logo.
[00:54:35]
Definitely.
[00:54:36]
Yeah.
[00:54:37]
So I think it's because it's not an Elm pages website yet.
[00:54:42]
Yet.
[00:54:43]
Yeah.
[00:54:44]
So I think it's worth putting a little bit of love into those things.
[00:54:47]
And I mean that, you know, as we've talked about, that was one thing I felt was really
[00:54:51]
important in Elm pages was to make that a good experience and to use type safe API to
[00:54:57]
guide you towards doing that with confidence rather than like reading, having a hundred
[00:55:02]
tabs open and finding blog posts that tell you what, you know, head tags you should put
[00:55:08]
in your page or whatever, you know?
[00:55:10]
So I think it's worth getting the Open Graph tags right, putting a little effort into that
[00:55:17]
or using Elm pages, another option.
[00:55:21]
And yeah, and you can, I mean, that's the basics.
[00:55:25]
Just getting the Open Graph tags, which are going to give you the previews in Slack, Twitter,
[00:55:31]
various social networks, which I shall not name.
[00:55:37]
You already mentioned a few.
[00:55:39]
Yeah.
[00:55:40]
Yeah.
[00:55:41]
And like if you send a text message, it's going to unfold properly and things like that.
[00:55:43]
So I think it's really nice to have, if you preload your pages, it's going to tend to
[00:55:52]
do that, you know, more reliably because not all services will execute JavaScript in order
[00:55:59]
to get a preview.
[00:56:00]
Yeah.
[00:56:01]
Scan for those meta tags to give you a preview.
[00:56:04]
So that's definitely worth doing.
[00:56:05]
And I don't know that Lighthouse will tell you about Open Graph tags actually.
[00:56:10]
I think it will just tell you, you know, your page should have a description and a title
[00:56:16]
to make search engines happy and some basic things like that.
[00:56:20]
So I mean, and just in general, like having a good Lighthouse score, perhaps it's necessary,
[00:56:27]
but not sufficient.
[00:56:28]
Yeah.
[00:56:29]
I was wondering, like, when you get to a very good score, like 96 to 100 on every metric,
[00:56:35]
do you stop or do you continue somehow?
[00:56:37]
Oh, definitely.
[00:56:39]
You definitely continue.
[00:56:40]
It's just the starting point.
[00:56:42]
And in fact, there are several places where Lighthouse will give you a manual set of audits
[00:56:49]
to perform.
[00:56:50]
And it says like, these aren't automated, but you should run through this checklist.
[00:56:53]
Oh, cool.
[00:56:55]
Yeah.
[00:56:56]
We'll link to that.
[00:56:57]
I don't think we'll be able to go through best practices and accessibility at this point.
[00:57:04]
There's so much.
[00:57:07]
We actually talked about several best practices already.
[00:57:10]
We talked about serving things up with HTTP2.
[00:57:14]
And if you use a CDN, it's going to give you the proper compression and things like that.
[00:57:20]
I mean, a lot of these things are really just run Lighthouse, see what it tells you.
[00:57:29]
If you can just do it, do it.
[00:57:30]
If you need to research it a little bit, spend a little time, see if you can do it and make
[00:57:35]
Lighthouse happy.
[00:57:36]
It's a useful tool.
[00:57:38]
Yeah.
[00:57:39]
I think you will find quite a lot of low hanging fruit.
[00:57:43]
Yeah.
[00:57:44]
To get you started.
[00:57:46]
Right.
[00:57:47]
For accessibility.
[00:57:48]
So I'm certainly not an expert in accessibility.
[00:57:52]
Lighthouse is also not an expert in accessibility.
[00:57:54]
It's only going to tell you about some basic violations.
[00:58:00]
I mean, there are some useful things.
[00:58:01]
It's going to tell you if your contrast ratio isn't high enough.
[00:58:06]
If you have, you know, if you have a yellow font over an orange background, then it's
[00:58:13]
going to tell you.
[00:58:14]
People might have a hard time reading that.
[00:58:16]
If you don't have an alt tag on images, it's going to be unhappy about that.
[00:58:20]
And as it should be, you know, there's some basic things like that that are just really,
[00:58:25]
it's not rocket science.
[00:58:27]
You should definitely do it.
[00:58:28]
But it's definitely not like, oh, I get a perfect accessibility score on Lighthouse.
[00:58:34]
Therefore, somebody can, you know, use a, you know, a voice, a text reader to navigate
[00:58:42]
my site.
[00:58:43]
No, not at all.
[00:58:44]
There are more robust tools for analyzing that.
[00:58:47]
Like Axe is a popular accessibility tool.
[00:58:50]
It's worth looking at.
[00:58:52]
So essentially, but some of the wisdom that I've heard about accessibility is that people
[00:59:00]
talk a lot about ARIA tags and there's a lot in Lighthouse about ARIA tags.
[00:59:04]
And one of the things I've heard is that, so Lighthouse is going to complain if you
[00:59:09]
improperly use certain ARIA tags, but in general, ARIA tags should be your last resort.
[00:59:17]
If you can make something accessible without using ARIA tags, then it's better to do that.
[00:59:22]
Using proper HTML tags, for instance.
[00:59:25]
Right, exactly.
[00:59:26]
Yeah.
[00:59:27]
Because it's not, you know, ARIA tags are really designed if you're doing like very
[00:59:33]
nuanced things with JavaScript and, you know, JavaScript carousels and things like that.
[00:59:38]
And you need to announce changes and things like that, then ARIA can help you there.
[00:59:43]
But for basic things on just a static website, usually you won't need ARIA to specify those
[00:59:50]
things and make them accessible.
[00:59:52]
So you want to reach first for, you know, semantic HTML, you know, having real buttons,
[00:59:59]
headers, footers.
[01:00:01]
Exactly.
[01:00:02]
Exactly.
[01:00:03]
Yep.
[01:00:04]
And then there at the bottom of the accessibility, we'll link to this.
[01:00:07]
There's additional items to manually check.
[01:00:09]
So again, you know, it's the starting point for accessibility, not the be all end all.
[01:00:17]
But if you don't have perfect score, then start with that.
[01:00:21]
Exactly.
[01:00:22]
Yeah.
[01:00:23]
All right.
[01:00:24]
Well, I think we've given people a lot to chew on.
[01:00:28]
Any last things we want to hit on?
[01:00:30]
Yeah.
[01:00:31]
I was wondering how to run Lighthouse to start with.
[01:00:34]
So what I did was search for Lighthouse on Google and then gave me a website to run it.
[01:00:41]
So that's what I tried.
[01:00:42]
And then at the beginning of this episode, you reminded me that it was inside the browser
[01:00:47]
to start with.
[01:00:48]
Yes.
[01:00:49]
I knew that, but I totally forgot about it.
[01:00:52]
Oh, okay.
[01:00:54]
Okay.
[01:00:55]
Then we should definitely repeat that here.
[01:00:57]
Yeah.
[01:00:58]
If you want to get started, I actually use Brave as my browser, which is based on Chromium.
[01:01:03]
Now Lighthouse seems to have trouble running in Brave.
[01:01:08]
So what I do, maybe that's different in the latest version.
[01:01:13]
I just open Chrome.
[01:01:14]
I just go to Chrome and I...
[01:01:19]
You don't have all your extensions that impact performance, for instance.
[01:01:23]
I'm not sure if it takes that into account or not.
[01:01:26]
But yeah, it's not a bad thing to have like a sort of vanilla plain browser and have it
[01:01:32]
use that for that benchmarking and stuff.
[01:01:34]
Yeah.
[01:01:35]
Just open up the Chrome DevTools, click the Lighthouse tab and say, generate report.
[01:01:41]
Yeah.
[01:01:42]
So while researching that, I am someone who really likes to work in things and then making
[01:01:49]
sure that they do not regress.
[01:01:53]
So I looked at whether you could run Lighthouse in your CI and there is a Lighthouse NPM package.
[01:02:01]
So you can just run Lighthouse in your CI or in a custom application that you make,
[01:02:12]
if you want to.
[01:02:13]
Right.
[01:02:14]
And you can create a history if you want to get clever with it.
[01:02:16]
You can set a threshold.
[01:02:19]
And then you can configure your CI with a custom script that checks whether things have
[01:02:25]
gotten worse or compared to a history or, I don't know, compared to a budget.
[01:02:31]
So I'm not trying that out, obviously, but I thought that was interesting.
[01:02:36]
So you can use it to get analytics and find out where you can improve, but you can also
[01:02:42]
use it as a regression tool.
[01:02:44]
Probably not the best one.
[01:02:46]
I'm guessing they're most specialized tools, but if you have CI workers to spare, then
[01:02:54]
maybe it's useful.
[01:02:55]
Yeah, yeah, definitely.
[01:02:56]
Yeah, it's not a bad idea to run a tool like Axe as well for checking accessibility in
[01:03:01]
a more robust way.
[01:03:03]
Netlify has a plugin for Lighthouse as well.
[01:03:06]
I haven't used it yet.
[01:03:08]
It was created pretty recently, I think.
[01:03:11]
That's something I want to check out.
[01:03:12]
It seems like a good way to do it.
[01:03:14]
All right.
[01:03:15]
Yeah, I think there are plenty of things to talk about about Lighthouse performance, accessibility,
[01:03:23]
and maybe we'll talk about that in other episodes, but I think we covered quite a lot already.
[01:03:30]
I think that should give people a good deal to think about.
[01:03:33]
And also, if you want to get started with this stuff, again, just run Lighthouse, see
[01:03:39]
what happens.
[01:03:40]
Yeah.
[01:03:41]
There's also web.dev, which is this website that the Google dev rel team maintains.
[01:03:51]
They do a really good job giving you these resources on these best practices and modern
[01:03:55]
web practices.
[01:03:57]
There's a whole section that talks about Lighthouse audits.
[01:04:01]
When you run Lighthouse and it flags an issue, it does a really good job linking you to a
[01:04:07]
thoughtful article that gives you resources and reasoning behind these things.
[01:04:14]
Lots of good resources to help with these basic practices.
[01:04:18]
It's just a basic, you know, basic hygiene, you know, web app hygiene sort of thing that
[01:04:23]
I think any Elm app should be looking at these basics and at least aware of issues.
[01:04:29]
Yeah, definitely.
[01:04:30]
All right.
[01:04:31]
Well, thanks for listening and give us a rating on Apple podcasts.
[01:04:37]
Check us out on Twitter and ask us a question.
[01:04:39]
Elm dash radio dot com slash question.
[01:04:41]
Let us know what you'd like to hear about next.
[01:04:44]
All right.
[01:04:45]
See you next time.
[01:04:46]
See you next time.
[01:04:47]
Happy performance tuning.