Problem
As an engineer at Peakflo, I had the opportunity to work on improving the overall performance and SEO scores of the website that was previously built on WordPress.
One of the main challenges with the previous website was that it took a long time to load, which was hurting its search engine rankings and user experience.
WordPress is a popular content management system (CMS), but it can be resource-intensive and slow, especially for large websites with multiple languages. This was the case with the website we were working on, which had a significant amount of content and was available in multiple languages.
I would like to share some statistics from our WordPress site. As you can see, our mobile performance score was only 20 and a majority (78%) of our Indonesian user base comes from mobile devices. We were determined not to give our mobile users a poor experience and thus, decided to make necessary improvements regardless of the cost.
Pre Astro Scores (https://pagespeed.web.dev)
Choosing the new stack
There are mainly two approaches, server-side rendering (SSR) and client-side rendering (CSR), for rendering the content on a website. We chose SSR because it generates the content of a page on the server and sends it to the client as a fully-formed HTML document, allowing search engine crawlers to easily index and understand the content.
At this point, one thing is clear: we must transition from WordPress to another technology that supports Server Side Rendering, have a faster load time, and is SEO friendly.
Now there is a number of SSR technologies available in the ecosystem and the popular ones are Next.js, Nuxt.js, Angular Universal, Rails Server-Side Rendering .
The only thing preventing us from using any of these is that we only need a static website with multi-language support and does not require the power of large-size packages that they come in by default. Also, we're not going to dive into those frameworks because they're largely designed to enable websites with more dynamic server-side rendering capabilities.
After doing some more research on the tech stack for static site generation we discovered various SSGs like Jekyll, Docusaurus, Gatsby, Astro, etc. Finally, we decided to go with Astro after doing some successful POCs and achieving performance scores of more than 95%
There were other factors that influenced our decision to choose Astro. First and foremost, Astro is a static site generator that was created with SEO in mind, which means that it creates clean and semantic HTML files at build-time rather than dynamically on the fly. This leads to faster page load time and better performance, thus making it easier for search engines to read and index the website's content.
In addition to its performance benefits, Astro has a large community of users and developers, which means that there are plenty of resources, documentation, and support available for the platform. The first stable version of this framework was released some time ago, which is also very important for the long-term stability and viability of a project.
How was the migration to Astro executed?
After finalizing our tech stack, now it's time to migrate our landing page from WordPress to Astro. The first challenge in carrying out this migration is there are more than 100 web pages on our site, including the product page, the pricing page, blog posts, and case studies that we published over a period of time.
To start, we have decided to choose only the web pages which generate the highest recurring traffic. With the help of our amazing Marketing team, we have the list of all the pages that generate the most traffic and leads.
For this migration, we decided to code the exact layout based on what was there on WordPress on the Astro pages. Before start writing code, we tried creating as many reusable components as possible so that we can later easily nullify all the redundancy, improving performance.
Now, let’s talk about some hurdles we encountered when building the Astro version.
IMAGES
On our landing page there were lots of images and one of the common reasons for site performance issues is that the assets are missing a proper and scalable mechanism to load higher-size images.
To tackle the same problem in our website we used two tools, i.e. AstroImages, for compressing the images into WebP for build-time optimization and Cloudfare CDN for faster delivery of images to users around the world. In addition to these two tools, we tried lazy loading to reduce the amount of data that needs to be downloaded from the images, resulting in faster page load time.
Basic Dynamic Functionality
If you look into our website, you’ll find some pages and components that need to be dynamic and some user interaction to work, i.e. pricing slider, savings calculator, accordions, nav dropdowns, etc.
The main challenge with Astro in handling dynamic functionality is by default, Astro creates every webpage without client-side JavaScript. When we render a component (island in the lang of Astro), Astro automatically converts it to HTML ahead of time and then takes away all the JavaScript, making the website snappy. However, if there is no JavaScript, there will be no dynamic functionality.
To tackle this issue, Astro introduced rehydration or partial hydration. It means we have to explicitly make some of the islands and components rehydrated if we wanna achieve some dynamic functionality.
One of the key advantages of using Astro is the ability to load islands in parallel. Islands are essentially self-contained modules that can be loaded independently of each other, which allows for more efficient loading and better performance.
To support this rehydration we used Preact instead of React because it's very much lighter and faster.
Multi-language Support
In Peakflo, we wanted to support multiple languages on our landing pages, but keeping translations in sync was a challenge due to the frequent updates to the content.
To solve this issue, we decided to use AstroI18Next to generate the webpages in different languages at build-time. To use astroi18next in our project, we have created the JSON file for each language we want to support. These files contain translations for the keys used in our codebase.
Once we have created these JSON files, we used astroi18next to load and use the translations by referencing the keys in the JSON files. For example, if we have a file called **en.json
**with a key called greeting
, we can use the **t('greeting')
**function provided by astroi18next to access the translated string.
With this approach, we only had to update the JSON files to keep the translations in sync instead of making changes to the codebase every time. To make it easier for our content team to manage the translations, we decided to store the JSON files in a Google Sheet and import them into the codebase at regular intervals.
Results
SEO Improvements
To improve the SEO of our landing page, our SEO specialist recommended starting with the fundamentals, such as using proper HTML semantics, providing detailed alt texts, and avoiding content redundancy.
Apart from all these suggestions, we also tried using some Astro plugins for SEO and followed open graph protocols in meta tags to generate the sitemaps and robots.txt files. We tried to give detailed descriptions and titles on our website to make it easier for SEO crawlers to understand and rank our website.
Results of the migration
Post Astro Scores
As you can see, the results of the migration to Astro have been impressive. The page load time has decreased significantly with the website now taking only a few milliseconds to load. This has a positive impact on search engine rankings, as faster page load time is a ranking factor for Google.
However, there is one twist to these amazing scores. If you go on our current landing and try to examine the scores, they won’t be as good as the results above! Let’s talk about that as well!
Hard time with third-party scripts
Post Astro Post GTM Scripts Scores
For data collection on user insights, we use Google tag manager which serves as a mediator between our website and the various tracking tools we’re using.
The worst part of using these scripts is they add additional HTTP requests to the page, which can slow down the page load time and negatively impact the performance of the website. In addition, these scripts can sometimes add unnecessary HTML to the page, making it more difficult for search engines to understand and index the content of the page.
While researching how to solve this problem, we stumbled upon an Astro plugin, Partytown, ****which basically runs third-party scripts on a secondary thread rather than the main thread. It gave us hope to improve our performance scores, but after doing several POCs, we couldn’t embed the plugin with our Astro landing page due to its constraints with GTM.
We are constantly looking for a solution to overcome this and hope in near future we will achieve a perfect performance score both for mobile and desktop.
So, if we look into the overall result of our migration, it has significantly improved our page load time and SEO scores. This resulted in an overall increase in user retention, traffic, and leads coming to our website!! Kudos to our team to pull this migration successfully! 🎉
If you're keen on joining our team, be sure to check out our careers page for current openings.