Adding a CDN to WordPress

A CDN can significantly improve site performance. I’ve home-spun a few in the past (using spare servers), but that’s not going to give the distributed performance boost of a truly localised CDN service.

Step 1

We’ll be using KeyCDN for our CDN services. There are plenty of these services to choose from, but keyCDN offers a relatively inexpensive service and decent geolocation, and more importantly the ability to use on-demand SSL certificates for free via LetsEncrypt—which is critical if your site is already using SSL and you want to make use of a CDN.

First we create a Zone, and point this our primary domain (mydomain.com). Ensure that SSL is enabled. No site should be running without SSL these days.

Now we can create a Zone Alias, which configures the subdomain we’ll be using on our site. Once created, this will provide us with the “real” domain (mydomain-7b2b.kxcdn.com). We’ll need to add this to a CNAME record in our DNS in the next step.

Note, on KeyCDN, you can generate an SSL certificate for your domain (for free) by selecting LetsEncrypt from the SSL options.

Step 2, creating a subdomain

To avoid mixed content warnings (and future-proof our setup) we need to use SSL on our CDN because our main domain is also using SSL. We enabled SSL in step 1, but to make use of this, we’ll need to create an alias for it on our own DNS.

Via your DNS provider (in this case, Digital Ocean), create a new CNAME record cdn.mydomain.com and point it at mydomain-7b2b.kxcdn.com

It’ll take a while for this to propagate before the CDN will correctly be associated with your domain.

Step 3, configure WordPress

We’ll be using the WordPress Super Cache plugin here to do the work for us. Basically, it can rewrite the URLs of any assets you upload to WordPress to our newly created CDN.

All you have to do is enter the subdomain in the CDN tab.

Now we can test that it’s all working. Browse to the site and take a look at the networking tools. We should see our assets now being served via cdn.mydomain.com.

Animating SVG (CSS vs. GreenSock GSAP)

Inline SVGs (not those loaded as images) can be styled like any other collection of DOM elements. But there appear to be a few limitations. Primarily, due to the way transforms (coordinates) are handled within SVG relative positioning is hard.

I really wanted to explore animating SVG elements with purse CSS, and to an extent this went swimmingly… until I started trying to animate the SVGs child elements.

CSS animation on CodePen 

Screenshot of CSS animated SVG
Animated via CSS (CodePen)

As the coordinates inside an SVG are relative to the grouped elements inside the SVG definition (rather than the HTML DOM, or the window), when we start trying to position child elements I quickly hit a wall.

GreenSock

Defeated (for now) I picked up the oddly named GreenSock animation library (GSAP). It’s shockingly easy to get up and running. Once we have the GSAP library referenced in our code,

var myElementHandle = new TweenMax.to(
  document.getElementById("mySVGElement"), 160, 
    rotation: 360, transformOrigin:"center center", ease: Linear.easeNone, repeat:-1
  }
);

GSAP animation on CodePen

Screenshot of SVG animated with GSAP
Animated via GSAP (CodePen)

Now we can target anything we want using names or class and GSAP will do the heavy lifting. A passive function of GSAP is how it handles changing animations (for example, triggering a new animation on mouseover on an element that is already animating). GSAP will blend any active animations to ensure a smooth interaction—something not possible in CSS.

As we’re relying on JS, it’s really easy for us to start manipulating our SVG in other ways too, such as generating new elements and handling interaction. For example, I added a couple of experimental functions:

// Creates a new svg element [id] attached to [parentID]
function createSVGElement(id, cssClass, x, y, parentID) {
  var svg = document.createElementNS("http://www.w3.org/2000/svg","circle");
  svg.setAttributeNS(null, "class", cssClass);
  document.getElementById(parentID).appendChild(svg);
}

And this…

// Creates a clone of svg element [id] as [newID]
function cloneSVG(id, newID, x, y, parentID) {
  var node = document.getElementById(id);
  var newNode = node.cloneNode("true");
  newNode.id = newID;
  newNode.setAttributeNS(null, "cx", x);
  newNode.setAttributeNS(null, "cy", y);
  document.getElementById(parentID).appendChild(newNode);
}

Dev Notes

I’ve used SVG shapes generated from Sketch here, so had to make sure any elements / groups I wanted to target with JS had names. Sketch will slugify the names if you don’t add something JS-safe yourself.

Reference:

Live-blogging and Micro-blogging

Exploring microblogging directly from WordPress. I’ve found this style of blogging really useful when working through a problem; a worklog/devlog of sorts so I can retrace my steps (those not covered by git commits).

This looks promising: https://wordpress.org/plugins/wp-to-twitter/

For live blogging I also found this free (open source) project.

Screenshot of LiveBlog splash page

My only fear with introducing yet another 3rd party service is over-all reliability.

 

Renewing SSL with crontab failed

LetsEncrypt SSL certificates expire every 90 days.

Looks like something not quite working with the auto renewal of SSL certs for my person domains. Caught an email from LetsEncrypt warning me that various domains were about to lose their certificates, despite a cron job running on the server.

To edit the crontab (Ubuntu):

 sudo crontab -e

Which now reads:

0 4 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log

Updated cron to run on Mondays at 4am (using this handy cron calculator).

For reference…

sudo /usr/bin/letsencrypt renew

…will manually renew any certificates that are about to expire.

 

React: WordStack (part 1)

This is the first part of a series of blogs as I explore building a small web app in React, with a modern workflow.

Background: WordStack is based on a really simple user story: Tracking daily writing progress via writing sprints. The idea of writing sprints comes from NaNoWriMo—the annual writing challenge where writers across the world attempt to first-draft an entire novel (each) in a month. It sounds like madness. It is (I’m one of those writers). To hit the goal (50,000 words, 1 month) you need to write 1600 words a day, or more if you skip days or miss targets.

One great way to achieve these is to set micro-targets and write in sprint. That is, set a small arbitrary time and write uninterrupted until that time expires. Tracking this is somewhat random. Via FaceBook chat, or the NaNoWriMo forums, or Slack. Many writers use a similar process outside the intensity of November. There is a very simple tracking tool on the NaNoWriMo web site, but it’s only really useful during the competition. This led me to thinking:

Wouldn’t it be cool if there was a tool to help with this?

Wires

First pass of this app needs to be really simple. First, because it’s part a experiment in learning to build production-level React code, part because I want to follow good agile practice and release small and often (MVP).

Screenshot of wireframe for initial application
Early wires in Sketch

I’m not too worried about the desktop layout for this version, so here we have the most basic process: Select your sprint style > visualise the sprint countdown > complete sprint > view progress. I’m not concerned with storing this yet.

Workflow

As this is much an experiment with workflow as React, I’m tracking progress of the project through a GitHub Project.

Screenshot of Kanban tracking for project on GitHub
GitHub project Kanban

The project itself follows standard Gitflow practice (develop branch with feature and release branches) and committed to GitHub.

Screenshot of GitHub
GitHub

IDE

To go with the new technology stack, I’ve switched out my usual dev tools for a fresher, more modern stack set: Atom (with some customisation, plus plugins), Hyper (a very nice, customisable terminal) and Chrome. As I’m focused on mobile for the prototype, it all fits nicely on a MacBook screen.

Screenshot of development environment
Atom, Chrome and Hyper, a great dev combination.

Getting started

Screenshot of directory structure
Directory structure

To get out the door, I started with Create React App and followed the basic setup. It was great for getting a bare-bones React app running. I quickly adapted this to use SCSS (via node-sass) and implemented a folder structure for components that more closely matched the in-house pattern library at my day-job.

Well, it doesn’t look great right now. But that’s not the point. Start small, see what works (and how it could work), iterate:

Screenshot of WordStack

Dev Notes

I’ve been spending a little time with React, and I like it. I’m not a fan of jsx… Mixing JS and markup and CSS into an unholy pot of mystery code just didn’t feel right. Surely this thing would taste awful. I persisted. It tastes pretty good.

Installing HTTP/2 on Ubuntu

The why?

HTTP/2 is a modern protocol that offers big improvement performances over HTTP/1.1. A binary protocol, it effectively streams the data, circumventing the age-old problem of slow sites due to many small assets. This means we can (in many circumstances) remove the necessity of concatenating scripts/CSS or fuss with sprite sheets. HTTP/2 provides potentially faster performance by interleaving the files as they are served. Secondly, HTTP/2 allows for the server to “push” files to the browser that it thinks the browser will need next. This can work in tandem with a new preload attribute in your page markup.

Enabling HTTP/2 on Ubuntu

  • First we need to update our Ubuntu install and tell it where to find HTTP
sudo add-apt-repository -y ppa:ondrej/apache2
sudo add-apt-repository -y ppa:ondrej/php5
sudo apt-get update && sudo apt-get dist-upgrade
  • Now we can install HTTP/2
sudo a2enmod http2

Note that for HTTP/2 to work, we need to have previously setup SSL certificates for any domains we want to serve. I covered that here.

  • Next we’ll need to tell Apache that we want to let sites be served over the new protocol:
sudo nano /etc/apache2/apache2.conf

Add a section:

# HTTP Protocols
Protocols h2 http/1.1
  • Save the file. Now we’ll need to restart Apache for the change to stick:
sudo service apache2 restart

You shouldn’t need to do anything else. Browsers will automatically try the newer protocol and the server should serve up files with no changes to your codebase.

To test whether HTTP/2 is working, you can check in Chrome’s dev tools under networking. If the Protocol column is missing, right-click the columns to add it. H2 is HTTP/2.

Screenshot of networking tool in Chrome

Dev Notes

As ever, when playing with stuff like this, take a snapshot of your machine first…