Skip to content

Daniel Lamb Byte–size Bits & Bobs

Moving to AMP

5 minute read.

Accelerated Mobile Pages Migration

I have experimented with AMP HTML1 on my home page, and am pleased with the performance. The next thing I want to try is migrating this blog over to AMP as well.

No Custom JavaScript

The first road block I hit was the JavaScript I wrote to automate injecting section headings links into blog posts. Why would a tiny 0.1 kb script be a problem? To answer that we have to step back a bit.

Why No JS Love?

The goal behind AMP is more than simply a set of standards to deliver content as quickly as possible. It is also designed to automate validation that a page conforms to those standards. Since JavaScript is extremely volatile when it comes to performance, no custom JavaScript is allowed. This restriction guarantees more deterministic page performance. Therefore, if a page validates as AMP compatible, then it will be fast.

Pre-Processing HTML

While I do not advocate parsing HTML using regular expressions, that is what I chose to do as it was expedient and I have 100% control over my own content.

Because I still wanted the ability to automatically link section headings, I leveraged the plugin grunt-text-replace to pre-process my blog post HTML.

// ... 
  replace: {
    dist: {
      src: 'dist/blog/*.html',
      overwrite: true,
      replacements: [{
        from: /<h(\d) id="([^"]*)">((?:.|\r\n*?)*)<\/h\1>/g,
        to: '<h$1 id="$2"><a href="#$2" class="anchor"></a>$3</h$1>'
// ...

The above configuration uses a regular expression to find all headings on the page with an id. Then the headings are modified using the values captured in the backreferences.

The following diagram breaks down what the matching rules are. One interesting optimization I’ve done is to use a backreference inside the regex itself. This makes matching more robust by ensuring the start tag will only match a paired ending tag.

If railroad diagrams are not your thing, Regex Buddy2 also provides a nice plain-English explanation of how the regular expression is constructed.

No <img> Tags

Now that I’ve removed the need for JavaScript in my blog posts, it is time to address the next modification. Instead of a standard <img> tag, AMP HTML provides a custom element <amp-img>. This is necessary so it can optimize the image size as well as when images are downloaded and rendered.

For images I could just change the Markdown source to use an <amp-img> HTML tag. But I wanted to avoid AMP spesific markup as much as possible and continue to use Markdown to write my blog.

We can’t use regular expressions again because the HTML for various images is too complex. You’d have to do something crazy like this, and even then it would be very brittle.


In stark contrast to the disaster above, creating a custom Jekyll filter to replace images is very clean and simple!

# ...
doc.css('img').each do |image| = 'amp-img'
# ...

By extending the Jekyll build process I can leverage powerful gem modules to do the heavy lifting while keeping the process unobtrusive. This means when AMP inevitably falls out of favor as the web evolves, my source files don’t need to change in the next migration.

The only downside to this is that I need to define the image sizes in the HTML. I could try to leverage something like FastImage3 to automate this process. But that seems like more trouble than it’s worth since the Kramdown parser supports manually doing it with the following syntax:

![alt text](/url.png){: height="50" width="100" }


Things look pretty good on the blog for the most part, and it wasn’t too difficult to switch over.

Next Steps

I think that’s enough for now, next I’d like to add in BlogPosting annotations. There are also some SVG diagrams that use <ellipse> which is currently disallowed by AMP HTML.

  1. AMP HTML is a way of building web pages that consistently render quickly.

  2. Regex Buddy is an awesome tool for creating, debugging and testing regular expressions. My only complaint is that they don’t have Mac OS X support.

  3. FastImage finds the size and type of an image given its uri.

Give Feedback via my AMA (ask me anything) project on GitHub. Published on by Daniel Lamb.
You may also enjoy these posts