Countdown: June, 2016

5 years ago, I took this photo in Terre de Haut, Guadeloupe

Thirty-one years ago, my parents bought an Apple IIc, and shortly thereafter, two games: Where in the World is Carmen San Diego? and Rocky’s Boots. The former taught me a love of problem solving, reading, and probably travel. The latter taught me the fundamentals of programming and logic — I often wonder why it hasn’t been updated for the iOS-set.

Twenty-nine years ago, I sat down in front of Mac in a classroom and met Logo’s turtle for the very first time. In some ways I’ve never really stood back up from that.

Twenty-four years ago, my high school computer science teacher convinced the school to let him teach a senior-level programming class for myself and 2 other students, so I could continue pursuing my passion. I owe much of my life to that act of attention and kindness.

Twenty-one years ago, I built my very first website, a simple little thing to help me keep notes, and provide the players a recap, for my Vampire: The Masquerade campaign. It didn’t do much, but it represented my first web-based programming, in Perl.

Twenty years ago, I was hired at Envolve Communications, and wrote my first professional website — a Vancouver handyman finder (waaaaay before it’s time), IIRC.

Seventeen years ago, I joined a startup called Up In Front, and got my first taste of dot-com insanity, hours, pressure, success and failure. It was an amazing 15 months before the crash.

Fifteen years ago, I wrote the first version of a CMS, The Pencilcase, with, at the time, an important distinction: it spat out (mostly) standards-compliant and accessible markup. It also had a rudimentary templating language to let my non-programmer design partners pull in dynamic content.

Fourteen years ago, I met Jeff Schafer, a good developer with an excellent business sense. We quickly realized that our skill-sets were complimentary, and we sought to work together.

Thirteen years ago, Jeff & I founded Pencilneck Software. From the start, we had a set of core goals that served us well:

  • Be high-touch: Technology is scary, and we can change that. Always listen to the customer’s needs, not their wants. Sweat the small stuff
  • Respect Expertise: We never set out to be a full-service shop. We wanted to provide excellent back-end code, and partner with experts to provide design, copy, etc.
  • Be a plumber: We prided ourselves on long-lived, excellent code that served our clients, not our egos. We built every website on the goal of a minimum five-year lifespan.
  • Stay nimble: We actively chose to not grow large, but to stay small, and able to shift focus as needed. Hire only when workload dictates — we embraced the agency model.

Eleven years ago, we released version 3 of the CMS, now renamed the The Pencilneck CMS. This project became the basis of all sorts of related platforms, as well as powering some 100+ websites. Several sites still happily use it today. It was modular, extensible, accessible and standards-compliant: From the beginning, we abandoned table-based templates in favour for the still-emerging CSS & standards-based layouts

Eight years ago, in a shift for the company, we were hired to build an entirely new platform for a client. It was the start of Pencilneck as “the version 2.0” company, specializing both building prototypes for clients, and scaling existing codebases to new versions, new levels.

Seven years ago, we became a distributed company when Jeff moved to Texas, and we ran two offices. This trend would continue to expand as we hired new contractors and staff. This transition forced us to confront how technology & tools can both build and break culture. It started a long internal conversation about the importance of the human on the other end of the interface.

Five years ago, we took stock of how poorly the websites we built for our clients were managed post-launch, how many problems our design partners had with dealing with technical requests, and launched a high-touch managed hosting service, specifically aimed at helping design firms and non-technical site owners have worry-free hosting. This move felt directly in line with our renewed focus on customer experience – both in the websites we built, but also in how we worked with our partners.

One year ago, I knew it was time for me to move on: I’d done more than I’d ever imagined possible with this company, with my partner, with my staff and with my clients. I was listless and no longer loving the work that I did. After long discussion, the decision was made to try and sell Pencilneck’s core services: managed hosting and top-shelf development. I would also leave at the same time.

One month ago, we completed the sale of Pencilneck to Pantek, a Cincinnati-based hosting firm whose approaches to caring for their clients closely matched our own philosophies, and who was looking to build out an in-house development arm. Jeff and the Pencilneck staff are all moving on to Pantek, which is an excellent turn of events. I can move forward on my own knowing that my team, my clients are all in good hands moving forwards.

Today, I have left Pencilneck. I’m thinking about what’s next for me — what’s my next focus? It’ll be something new. I’m doing some freelance work as a CTO-for-hire, taking what I’ve learned over the past thirteen years at Pencilneck helping clients build new companies, and scale existing platforms. I’m taking courses, learning new tools and languages in realms that are new to me. I’m thinking a lot about the process & tools of site management, both from an agency/contractor’s perspective and the site owner.

I’m excited to explore the future!

Optimizing site speed: a case study

One of our clients runs an eCommerce site selling workout videos on behalf of George St.Pierre, the UFC Fighter, called GSPRushfit. The videos sell well, but they’re quite rightly always looking at ways to increase sales. A few weeks ago, we ran a study to see how fast the site loaded, and how that affected conversion rates (sales). I wrote a post about how we measure that a couple of weeks ago. The result of this was that we could see that page loaded reasonably well, but not fantastically. Across all pages, the average load speed was 3.2 seconds. What was eye-opening was that pages that loaded in 1.5 seconds or less converted at about twice the rate of pages loading 1.5-5 seconds. There was  a further dip between 5-10 seconds. So with this data in-hand, I started to look for ways to increase page load speed. I came up with a laundry list of things to do. Most of these are suggested by YSlow:

  1. Remove inline JS/CSS: We didn’t have a lot, but there was some unnecessary inline scripting. These were moved into the existing CSS & JS files. I think I added about 50 lines of code. Not a lot, but helpful. There’s still some inline JS & CSS that’s being written dynamically by coldfusion, but all the ‘static’ code was moved into one.
  2. Minify Files: This doesn’t do a lot, but does compress files slightly. I think I was able to reduce our JS file by 30% & our CSS by 15%. Not a lot, but still helpful. I use an app called Smaller, which I’m a big fan of. While YSlow suggests you combine files, I chose not to – the reduction in requests didn’t offset the problems for us in doing this.
  3. Reduce Image Size. The site is fairly graphically intensive – large background images & lots of alpha-transparency PNGs. When I started, the homepage was loading just under 1.2MB in images, either as CSS backgrounds or inline. Without (to my eye) any noticeable loss of quality I was able to re-cut those same images to about 700KB in size.
  4. Use a CDN: The site loads video, which we call from a CDN. But the static assets (CSS, JS, Images) weren’t being pulled. This was originally because the CDN doesn’t support being called over SSL. But it only took a little scripting to have every image load from the CDN while not on SSL, from the local server while over SSL. This, as you’d expect, greatly improved the response time – by about 0.2 seconds on average.
  5. Query Caching: this one is likely a no-brainer, but the effects were stunning. All the content is query-driven, generated by our CMS. But it doesn’t change terribly often. So I started caching all the queries. This alone dropped our page load time by nearly a full second on some pages. And to maintain the usefulness of a CMS, I wrote an update to clear specific queries in the cache when new content was published.
  6. GZip: Again, likely something I should have already been doing, but to be honest, I had no idea how to accomplish this on IIS. So I figured that out and requested that the server gzip static assets (JS, CSS & HTML files).
  7. Far-future expires headers. Because very few of our images change frequently, I set an expiry date of 1 year in the future. I likewise set a cache-control variable of the same time frame. Which, should, in theory, reduce requests and allow clients revisiting to just use their local cache more. I of course added a programmatic way to clear that cache as well for when we change content or edit the JS or whatever.
  8. Clean up markup: While I was doing all the rest, I also cleaned up the markup somewhat – not a lot, but again, we were aiming to eliminate every extraneous byte.

So, as you can see, we sort of threw the kitchen sink at it to see what stuck. In retrospect, I wish I had made these updates one at a time to measure what sort of an impact (if any) each one had. There’s only a couple I can see clear before & after differences, which were mentioned above. So for everyone out there, which of these were the most effective?

  1. Caching Dynamic Content: Even on a CMS-driven site, most content doesn’t change constantly. But if you can eliminate trips to the DB server to make a call, that’s time saved. Even if you cache a recordset for a few minutes or even just a few seconds, on a high-traffic site you can see some real impressive gains. We cache queries on this site for 10 days – but can selectively update specific queries if a user makes an edit in the CMS – sort of a best of both worlds right now. This somewhat depends on having a powerful server – but hosting hardware & memory are pretty cheap these days. There’s no reason not to make use of it.
  2. Crushing images: When building the site, I did my best to optimize file size as I exported out of Photoshop. but with a few hours in Fireworks I was able to essentially cut the size of the images in half with no real visual impact. A hat-tip to Dave Shea for the suggestion of using Fireworks.
  3. Pushing Content to a CDN: this is the head-smacking no-brainer that I don’t know why wasn’t already part of our standard workflow on all sites. As I wrote above, we gained about 0.2 seconds by doing this – which doesn’t sound like a lot, but it’s noticeable in practice.

The nice thing about this exercise was that it shook up how I built sites, how our internal CMS runs and how I configure both our IIS and Apache servers to all run slightly more efficiently. I suspect that I could eke out a few more milliseconds by playing more with the server settings itself, but I’m satisfied for now with how this worked out.

Better redirection

For sites powered by the Pencilneck CMS, we’ve for ages and ages had what we called “Friendly URLs”. These are common across CMS’s, blogs, etc (some ironically, I don’t use them on Tannock.net because I’m too lazy to reconfigure my config & htaccess files). Back in the day, we did this by physically writing a folder to the server. Which was not ideal. So we then switched to redirected using ColdFusions onMissingTemplate() handler. In this instance, we have the IIS server trigger a 404 error, which calls a custom CFM file, which does not, in fact, exist. This triggers the sites onMissingTemplate() handler to actually read the URL and load up the appropriate page from the DB. This works well, but there’s a fair amount of overhead. Vs. the physical stub option, it added between 400-600 ms – not a huge amount, but enough to cause a noticeable overhead on busy sites.

But a while back for a larger project, we installed the Helicon ISAPI rewrite module for IIS. I’ve been using this for a variety of things on sites, such as locking down directories for documents, redirecting particular scripts elsewhere, etc. But I hadn’t set it up to handle our friendly URL system.

This past weekend, I finally spent the time to test out the difference – and it’s impressive. Despite running exactly the same script as the current OnMissingTemplate() handler calls, it runs much faster – on average, 80-100 ms (vs. 400-600 previously) – a significant decrease – I’m guessing because there’s overhead from IIS to generate the 404, hand that off to the custom 404 page, which doesn’t exist, so hands it off to the onMissingTemplate() handler which then calls this script. Now, the the ISAPI rewrite condition kicks in and it calls the script directly.

And now all of our sites are slightly more responsive, which is better for everyone!