Improving performance, security, accessibility, SEO and more
I want to share with you how I dramatically improved some key aspects of my personal website, including performance, accessibility and more. Performance increased by more than 300%! And I did it in the Agile way, using one secret of Agile many times forgotten: I hope it becomes clear throughout this article.
I'm curious by nature, maybe due to my deep and intrinsic "test nature" :) but I also have some bits of a "crazy scientist": I like to experiment by myself, watch, taste and learn.
Last year, I launched this blog. I told to my self: "It's time to do it... so let's do it in an Agile way!". I looked at different SaaS (e.g. Wordpress, Wix) and choosed Wix. As I started adding some content and working with the site backoffice, I realized it was getting really slow and full of bloatware. I confirmed this qualitative feeling with some metrics(obtained using Lighthouse) that made me even more upset.
There were many problems showing up in the report besides performance. How could I solve this? Well, sometimes you have to take a step back; it will hurt a bit but it will provide you so many benefits on the run.
Time go back to the basics
I asked myself:
What do I really need?
And the answer was:
- share some blog posts, once in a while, in a very easy way
- provide great experience for visitors, in terms of readability, accessibility, performance
Some nices-to-have would be:
- ability to move the blog easily to another host
- easily track and revert changes
- ability to easily make experiments, safely
After applying the changes herein detailed, some things I got besides the basics:
- on-demand live environments, per commit and per PR (pull request)
- easy backups (it's Git so...)
- ability to switch hosting provider (e.g. Vercel, Heroku)
- automated checks, per branch/PR using Checkly
- ability to easily bring in another contributor
Things I got rid of:
- low-speed
- accessibility issues
- bloatware
- lock-in on Wix
- Wix banner at top
- Wix cost
Let's see how I dit it.
How it started
I was reading about JAMstack; (more info on JAMstack WTF) and I ended up in this blog about E2E testing. Suddenly I discovered Next.js, Vercel and Checkly.
The idea behind JAMstack is to provide a development environment for web sites, using Javascript, APIs and Markup, where the latter is served as static, generated files without requiring explicitly a web server. Even though this has some constraints that limit its broader usage, it provides many benefits in terms of performance and security that can be applied in many cases. In case you've worked with blog kind of sites, you may have crossed with tools, such as (Jekyll)[https://jekyllrb.com/), that generate static sites. What makes JAMstack fun is that you can add dynamic behaviour to your static sites, using Javascript.
My experiment
From the Next.js documentation, I could try out some live examples of this framework and also have access to their respective source. It was really quite straightforward to create a blog and deploy it to Vercel in no time, either by cloning one of the repos or from the command-line.
git clone https://github.com/vercel/next.js/tree/canary/examples/blog-starter.git
# or ...
yarn create next-app --example blog-starter blog-starter-app
Then I could do some changes, evaluate the results with Lighthouse and also try the tools by myself. Let me take the opportunity to introduce them at a glance.
Lighthouse
Lighthouse is a tool that looks at certain quality aspects of your site, including performance, accessibility, SEO, PWA (Progressive Web Applications) support. It can be run from the command-line, CI or directly from within Chrome dev tools.
Lighthouse provides a score for each high-level item and then allows you to drill-down and look at the individidual checks where you may find additional information and recommendations, so that you can improve your site. It's quite simple and effective, for testers and developers; it makes easier to track some quality aspects from the start.
Some care though:
- score will depend on how and where you execute it from; if you're using Chrome, then it is highly recommended using an anonymized window so it doesn't get affected by any extensions that you may have
- if use a tool such as Lighthouse Keeper or other one that integrates with your toolchain, than results may be slightly distinct
Vercel
Vercel is a cloud-based orchestrator platform, tailored for "building" and deploying/hosting static sites; Vercel is also the team behind Next.js. As a developer, you can write the code, push it and Vercel will do the rest:
- watch a given branch and checkout the code from the Git source control provider
- build the site static files
- create a temporary environment and deploy static files there
- assign a custom DNS entry to the environment
Vercel has several integrations, including with GitHub; thus, one can also track the deployment on GitHub pull-requests.
Checkly
Checkly is a simple, yet powerful tool for DevOps teams; it can "accelerate" the delivery of software by providing feedback about your site based on browser (or API) checks, implemented using Puppeteer scripts. The checks can run from multiple locations and besides tracking the assertion results, one can also take screenshots and track historical assertion results and response times. On top of this, we can be alerted upon failures.
Checkly also integrates with GitHub, which is awesome; thus, we can also automatically run check and track their results whenever doing pull-requests. This provides valuable information before merging.
Implemented workflow
My workflow will be mostly based on git-flow but without the "develop" branch; I'll use branches to implement fixes/new features on my site. I will then create PRs and merge then if appropriate.
My website will be hosted on GitHub; I will also enable integrations with Vercel and Checkly, to ease deployments and have almost real-time feedback on my pull-requests.
In Checkly, I can quickly track my site status and performance.
I've created a check that goes over the main pages. This can be split into distinct checks but in this case I don't see the need for it as I don't aim to grow these.
const assert = require("chai").assert;
const puppeteer = require("puppeteer");
const browser = await puppeteer.launch();
const page = await browser.newPage();
const baseUrl = process.env.ENVIRONMENT_URL || "https://myblog.bitcoder.vercel.app"
var url = baseUrl
await page.goto(url);
var title = await page.title();
await page.screenshot({ path: "homepage.png" })
assert.equal(title, 'Sergio Freire\'s personal blog on software testing, agile');
var url = baseUrl + "/about"
await page.goto(url);
title = await page.title();
assert.equal(title, 'About');
await page.screenshot({ path: "about.png" })
var url = baseUrl + "/contact"
await page.goto(url);
title = await page.title();
await page.screenshot({ path: "contact.png" })
assert.equal(title, 'Contact');
var url = baseUrl + "/articles"
await page.goto(url);
title = await page.title();
await page.screenshot({ path: "articles.png" })
assert.equal(title, 'Articles');
await browser.close();
We can run the check manually right away.
Additionally, we may integrate it with GitHub so our check(s) is/are run automatically in PRs.
I've also implemented another check that will transverse my blog posts. In this iteration, the blog post URLs are hardcoded. But I aim to automate this properly.
![checkly](/assets/blog/improving-performance-security-accessibility-and-more/checkly_posts_script.jpg
Example
Imagine that I wanted to add a new feature on my website, or to fix something, or to make an improvement in general.. I would start by creating a branch.
git checkout -b fake_improvement
Then I would make all the code changes I wish and commit them.
git add ...
git commit -m "my changes"
git push -u origin fake_improvement
In GitHub I could see the new branch and decide to create a PR for it. Whenever looking at the pull-request, we can can see a section from Vercel giving us a link to the "build logs# and also to a preview environment having our branch code deployed. We can then go to that environment and see how our web looks like and perform some exploratory testing on it. But we can also have immediate feedback about the automated checks implemented using Checkly. In the following screenshot we can see that our two "automated tests" failed; this happened on purpose as I deleted one post and changed the title of the website.
We can also see the details (and re-run) of the test.
By having near real-time environments and test results, it eases me performing changes in the future. After fixing the problems, I can finally merge my branch (as easy as clicking on merge on GitHub) and if deployed successfully it gets assigned to my domain automatically (by Vercel).
Further improvements for the future
Checkly
- explore its potential further
- automate obtaining all blog posts
- check all site references for dead links
Lighthouse
- evaluate how to integrate Lighthouse in GitHub, to have information on the PRs
- evaluate how to have checks based on some criteria for the Lighthouse provided metrics
Blog
- review styles (e.g. cover, code blocks)
- review image sizes/formats
Key learnings
- don't be stuck in the past
- don't be afraid to try, especially if you can make a quick experiment and obtain some quick results
- Lighthouse is a great audit tool for web sites/apps (mobile/desktop), essential for testers and developers
- there are some tools (e.g. Vercel, Checkly, etc) that can easily integrate with your (source-code) versioning control provider and your delivery pipeline
Conclusion
Your project is never complete; it won't ever have all the things you wished for, nor the ones you didn't even think about.
Sometimes, you just have to start. You cannot wait for a ton of evaluations that will provide you all the things you need to decide; no evaluation is ever complete, IMO.
If you're working in a project from the start, then you can keep your eyes open and use tools such as Lighthouse to provide some quality insights. If your project is already alive, then a tool such as Lighthouse is also valuable for your team; as a tester you can look at some improvement opportunities and discuss them within the team and developers can also proactively fix.
After I've implemented my blog site, I realized that it was not meeting its ultimate purpose: being accessible, readable, high-performing, clean. If you leave a bad impression, it will be hard for visitors to return.
Choosing the mix GitHub + Verce + Next.js + Checkly + Lighthouse provided me the necessary bits to overcome my and my reader needs. This doesn't mean it's the best mix or that I won't change it in the future. But now I know that I've simplified what I had, improving key quality metrics, removing lock-ins and making it less expensive.
At the start of this article I've mentioned one secret of Agile, remember? Well, the secret is that, IMO, being Agile is not about adding more features, in an incremental way. Instead, it's about incrementally adding value. In other words, this means that sometimes it's about reducing what you have, making it cleaner, focused. And this may imply putting most (if not all) of what you have into the garbage and start it from scratch. Actually, you never start from scratch because your previous experience can help you get where you want, faster.
Some other curious stuff
- Vercel also integrates with Lighthouse. I actually discovered it whenever I was having a coffee, using my smartphone. I added it and obtained the results right away in few seconds. How impressive is that?
- Migrating my posts from Wix to Next.js took me a bit as I had to rewrite them in markdown. But now I'm getting used to it :)
Useful references
Thanks for reading this article; as always, this represents one point in time of my evolving view :) Feedback is always welcome. Feel free to leave comments, share, retweet or contact me. If you can and wish to support this and additional contents, you may buy me a coffee ☕