|February 2nd, 2018|
|amp, tech [html]|
Things I ran into:
The hand-rolled software that builds these posts was in terrible shape, with over a decade of hacks on top of hacks. This made it very hard to make the small changes I needed in order to generate AMP versions of pages. I rewrote it to work more sensibly (parsing html with a parser instead of linebreaks and regexps, to start with) which was a surprising amount of work. 
The comments were the hardest part. This page is served statically, and then it fetches the comments in the background. The original version uses JS for this, making requests in parallel for the different services, and then uses JS to build the HTML to display the comments.
In AMP you can't use custom JS, so I needed to build this out of an existing component (or, in theory, write a new component). It looked like amp-list was the closest to right, but it doesn't seem to support nesting. I gave up on nesting, and decided to use '→' to mark reply comments.
This meant creating a new endpoint on my comment server for AMP pages, and having it serve JSON in a form that AMP would be able to work with.
AMP uses amp-img tags instead of standard image tags. They're pretty similar, except that in AMP everything needs to have a deterministic size. Luckily I'd already sorted out a system of automatically injecting the sizes of my images a few months ago, or this would have been much more work.
I needed to convert my embedded youtube videos to amp-youtube, which wasn't too bad. This got me to fix some of my very old flash embeds that I still had kicking around.
AMP doesn't let you use style attributes, so I wrote something that automatically hoists these to a style block at the top of the page.
On my pages I expect AMP to slow things down a bit in general by adding a blocking script load, but it could make up for this on long pages with a bunch of images because AMP is able to better prioritize visible content. Example WebPageTest runs, all on a simulated Moto G on simulated bad 3G internet:
Update 2018-02-06: I went to check how this experiment was doing, and I realized I didn't set up the custom dimension properly in google analytics. In addition to making sure I'm sending it on each pageview (which I did) I also need to configure it server-side. I've done that now; hopefully I'll be able to look at this tomorrow. I had also set this up as a content experiment, but content experiments don't seem to let you analyze speed, only high level metrics like pageviews/session (which doesn't make sense with a random-per-pageview experiment) or bounce rate (which does, but is noisy).
 It's still a lot slower than the old version, around 25s instead of 5s. I looked at in with a profiler and nothing jumps out nuts. I could rewrite it in something faster, or look more into speeding it up, but for now I just figured out how to run it in the background from emacs instead of having it block my workflow:
(require 'subr-x) (defun process-sentinel (process event_type) (message (format "%s: %s%s" process (string-trim event_type) (if (string= event_type "finished\n") "" " (see buffer make-rss)")))) (defun publish-news-entries () (interactive) (message "publishing news entries in the background...") (start-process "make-rss" "make-rss" "~/bin/makerss-and-reverserss.sh") (set-process-sentinel (get-process "make-rss") 'process-sentinel))