December 3, 2024
Lighthouse - Optimize your website, Part 3: Best practices
So how did 3 weeks just pass by like that? My original plan was to post every Tuesday but sometimes work and life just gets in the way. Time flies! đ
But now Iâve got part 3 in the âLighthouse â Optimize your websiteâ ready for you. Today itâs time to take a look at the âBest practicesâ part â a great mix of UX and security.
For the sake of this post Iâve created a very bad test page for you right here: http://test.frontenddesigner.dk/lighthouse_best-practices.html. The score speaks for it self:

On the page I created Iâve got issues in these 4 categories:
Trust and Safety
General
User Experience
Browser Compatibility
Letâs take a look at why my page performs so badly in the âBest practicesâ category.
Trust and Safety
This is a very important part of your website. If your website isnât safe â and if user donât trust your site â you site will likely never be performing at itâs best. Iâve got three issues on my test page:
Does not use HTTPS
Does not redirect HTTP traffic to HTTPS
Requests the notification permission on page load
Does not use HTTPs and does not redirect HTTP traffic to HTTPS
The first two is related, but not exactly the same. You can use HTTPS, but still don't redirect traffic from HTTP to HTTPs.
To fix the issue with HTTPS all you have to do is install a SSL certificate on your server and attached it to your site. I often host small and simple sites at simply.com where you can easily setup a free Letâs Encrypt certificate on your site: https://www.simply.com/dk/support/faq/1/123/ (article in Danish).
If you want to use Letâs Encrypt on a server you have access to, you can install https://www.win-acme.com/ which allows you to create certificates for sites on your server.
To make sure your site redirects traffic from HTTP to HTTPS you most likely have an option in your CMS (if you use one) to redirect the traffic. If not, it can easily be set in a web.config file:
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="RedirectToHTTPS" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern='"ocalhost" negate="true" />
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
</rule>
<!-- Any other rules here. -->
</rules>
</rewrite>
</system.webServer>
</configuration>
If youâre on a PHP platform you can do the same in a .htaccess file. I havenât worked much with PHP, so Iâll lead you in another direction here đ Here's a Google search for HTTPS redirect in .htaccess.
Requests the notification permission on page load
Last item in the Trust and Safety part is the âRequests the notification permission on page loadâ. This is quite simple to fix. Just donât ask for permissions for notifications on page load đ
I see a lot of pages doing this as the first thing when you enter their website. To me itâs just annoys me â thereâs no way I would accept notifications at this point. Maybe later, if i find the page relevant and useful to me. But asking for the permissions right away just leaves me with a bad first impression. And I guess thatâs exactly what Lighthouse means, when they tell us:
Users are mistrustful of or confused by sites that request to send notifications without context. Consider tying the request to user gestures instead.
My code to request permission for notifications looks like this:
Notification.requestPermission().then(function(result) {
console.log('Notification permission:', result);
});
Donât do that! Wait for the user to interact with your site â and ask them in other ways if they would like notifications about news on your site. You can do it with regular content, that triggers the requestPermission() when clicking on a button instead:
<button id="notifyMe">Notify me!</button>
<script>
const button = document.getElementById('notifyMe');
button.addEventListener('click', function() {
Notification.requestPermission().then(function(result) {
console.log('Notification permission:', result);
});
});
</script>
General
In this part Iâve got to issues to fix on my test page:
Uses deprecated APIâs
Browser errors were logged to the console
Uses deprecated APIâs
Deprecated APIs is APIs that might be removed in newer versions of the browsers â or APIâs that are no longer available on an insecure origin (a page without a SSL Certificate). In my example I actually have to issues related to this:
Iâm trying to use the Notification API (as shown above in the Trust and Safety part) on an insecure origin (I donât use HTTPS on my test site)
Iâm trying to use âgetCurrentPosition()â from the navigator.geolocation
For both of these I need to be on a secure origin and as with the Notification API it also goes for the Geolocation API. Donât ask right away â ask when it makes sense for the user. It could be on a page where youâd like the user to interact with a Google Map.
Browser errors were logged to the console
This indicates that youâve probably got some code not working like supposed to. In my example Iâve got this code:
console.log(testObject.testValue);
The problem with this is that I havenât declared my âtestObjectâ anywhere â it doesnât exist â but still Iâm trying to read the âtestValueâ of the object. Naturally this gives me an error in the console:
Uncaught ReferenceError: testObject is not defined
To fix this issue, remember to always make sure that what you are trying to read from â in this case the âtestObjectâ â exists:
if (typeof testObject !== 'undefined') {
console.log(testObject.testValue);
}
In this case, the property testValue might be null or undefined, but you know that testObject exists before trying to read from it.
User Experience
Iâve just got a single issue in this part:
Does not have a tag with âwidthâ or initial-scale
If you donât have this meta tag â or if you have it with an initial-scale with a value less than 1, youâll end up having a website with a 300 ms. tap-delay for users.
To prevent this from happening, you just have to add this inside the elements:
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
Browser Compatibility
Letâs have a look at the issues Iâve got in the Browser Compatibility part:
Page lacks the HTML doctype, thus triggering quicks-mode
Charset declaration is missing or occurs too late in the HTML
Page lacks the HTML doctype, thus triggering quicks-mode
What-mode? Quirks-mode! We really have to travel way back in internet-time to find the origin of the âQuirks-modeâ. Itâs from way back in the day where there was no standard and sites was developed in two versions; one for Netscape Navigator and one for Internet Explorer.
To fix this issue, nowadays we simply just put this doctype declaration at the top of out document:
<!DOCTYPE html>
<!-- THE REST OF THE DOCUMENT -->
Charset declaration is missing or occurs too late in the HTML
Itâs all about character(s)! Without a charset the browsers wonât always now what each byte represents and you might have issues with ÊÞÄ (in Danish) and a lot of other special characters.
You fix it by putting a charset inside the head tags:
<meta charset="UTF-8" />
Note that a charset declaration that appears to late in the HTML might cause some issues. Google says:
Note: Theoretically, a late element (one that is not fully contained in the first 1024 bytes of the document) can also significantly affect load performance. See Issue #10023.
Final result
Letâs have a look at the final result. Iâve created another test page where everything from the report is fixed. You can have a look here: https://test.frontenddesigner.dk/lighthouse_best-practices-fixed.html
The score is now 100 / 100. Accomplished by doing a few simple things:
Install a SSL Certificate
Redirect traffic from HTTP to HTTPS
Remove code that asks for permissions to the Notification API instantly on page load
Remove use of deprecated APIâs (actually fixed by installing a SSL Certificate and changing requests to the Notification API and the Geolocation to be triggered on a button click instead of on page load)
Making sure objects exists in JavaScript, before trying to read from them
Adding a tag to the head element
Adding a doctype to the HTML
Adding a charset declaration to the head element

Thatâs it for today. Reach out at [email protected] if you have any input to this post or if youâd like me to dig into a specific area of frontend development.