Constructing a blog engine using Ember - Part 1a

7 min read • 28th February 2020
Image of a Lighthouse

In the previous post, I had mentioned that I wanted to build a blog engine that is green on Lighthouse. It implies, the scores of Performance, SEO, Accessibility, and Best practices are above 80. This post resonates that idea and we will get to every bit in detail.

Image of a Lighthouse tab on Chrome browser
Lighthouse tab on Chrome browser

Link to this sectionLighthouse: Performance

At the closing summary of my blog engine's asset validations, it was around 250ish Kb. That is quite high for a blog post that contains minimal Javascript codebase.

That led me to the understanding that, there could be unwanted addons that I might have added. Few plugins that I wanted to use on the page but not required as part of vendor.js.

This was a huge efforts in itself and I compiled them as a separate post in here.

Image of a Lighthouse Performance metrics
Lighthouse performance metrics


Link to this sectionLighthouse: Best practices

When I was rendering pages there was one common suggestion from Lighthouse to optimise the images that I used on a post. It also gave insights on how much of bytes could be saved if I had done a better compression or loaded responsive images.

Link to this sectionGenerating images that are responsive

For mobile devices or devices that have widths smaller than that of a regular desktop, images of the blog needn't download large images. Especially, this is a collection of blogs that show up images captured on my DSLR. The average size of each JPEG file is in the order of 10 MB. In order to make sure, that the images that the post displays is not too huge, I had to make sure to:

  • Convert JPEGs to WebPs so that modern browsers use webp that has higher compression order.
  • Compress with quality that is not easily identifiable by the naked eye.
  • Utilise img tag's srcset to use different images based on screen resolution.
  • Cached on the server using Cloudflare with a higher cache-expires header.

Link to this sectionConvert JPEGs to WEBPs

There are many tools for this conversion. The reason for using webp is size. webp has proven compression strategies over jpegs and there are an average 30% reduction in file size. In order to convert a set of JPEGs to WEBPs, I use the same "Sharp" library and run a script in node. This converts all the non-converted JPEGs to WEBPs with a quality of 60.

Link to this sectionCompression and multiple image sizes

There are many good tools for this purpose in node, php, rails, and what not. Since, the blog engine was totally built ground up from Ember, I chose node for this purpose as it is easy to hook onto any of the EmberCLI's hooks. I use a library called "Sharp". Perhaps, an ember addon called ember-responsive-image gets this job done where it converts a list of files in a specific path to a different path with multiple image sizes. This solves 2 and 3 for me. The next step to this process is to use ember-responsive-lazy-image which loads images, while showing a low quality image placeholder until the image loads.

Link to this sectionCaching on the server

I signed up for Cloudflare which gives free CDN and caching in front of my assets. This makes fetching of assets really fast and almost instantaneous.

Image of a Lighthouse Best practices metrics
Lighthouse best practices


Link to this sectionLighthouse: Accessibility

Link to this sectionMaking a11y part of dev cycle

Now that most of content was ready, it was time to improve on the accessibility aspect of the blog engine. Ember's addon ecosystem has got me covered with many addons.

Link to this sectionStep 1: Installing ember-a11y-testing

To simply install ember-a11y-testing, I did the following

ember install ember-a11y-testing

This helps me in catching accessibilty issues upfront during a dev build. And fixing them were so easy!

Link to this sectionStep 2: Disable application wrapper

As per the ember guides to enabling accessible web apps, I had to disable application wrapper. So here's how I did it

ember feature:disable application-template-wrapper

Link to this sectionStep 3: Linting markdown files

Oh yes! This was a very quick way for me to find out if I had made mistakes while writing content in my editor itself. I use VSCode for coding and added the markdownlint extension to capture for header rules mismatch. Though this is a minor addition, this made life easier for me to worry one less thing about my test case failure reporting that there was an error.

Image of a Lighthouse Accessibility metrics
Lighthouse accessibility metrics


Link to this sectionLighthouse: SEO

For any public content to be searchable on the web by search engines, it is important that our content contains the right set of meta tags and the values for each of them. As this blog post was built with ember, ember's ecosystem got me covered for taking care of this.

So the idea behind SEO was to generate a nice snippet around the content whose URL was shared on social media platforms like Twitter, Facebook, etc.

There are many tools in the ember ecosystem that does the job of adding the SEO tags dynamically. I used ember-cli-meta-tags which had the power of setting the head tags at the route level. So any model's name could be set as the <title> tag's textnode. It is easy to install as well:

ember install ember-cli-meta-tags

Image of a Lighthouse SEO metrics
Lighthouse SEO metrics


Link to this sectionResults

Since the blog is built using Ember,

  1. The vendor size of production build with gzip, minification and fingerprinting is of the order of 246.95 KB gzipped.

Note
This number might be quite high considering static assets. But, if you are interested, you can read more about optimising performance for Ember apps from this blog post.

  1. The app size of production build is of the order of 6.65 KB gzipped
  2. The total app CSS is of the order of 1.91 KB gzipped.

Note
Since I did not use external addons that use css, vendor.css was unnecessary. So this was also removed from index.html so that would save one network request.

The following are the Lighthouse metrics screenshot of the index page taken on May 30, 2020. The left holds the mobile metrics while the right holds the desktop metrics.

This was about how I got started. Apparently, over time, I had changed some parts of the blog engine to adopt more exciting strategies. You can read about it here.

Enjoyed this article? Tweet it.

I guess you might be looking to add your comments? Glad to tell you that this section is under construction. But don't hold on to your thoughts! DM them to me on Twitter