Dipping below the magical 1 second page load time

A couple of weeks ago I started looking into data-uri’s as a way to further optimize the performance of this personal playground of mine. Testing was easy enough; Autoptimize, the javascript/ css/ html opitimizing plugin I now use in conjunction with WP Super Cache, comes with support for data-uri’s in CSS and switching that option on indeed immediately resulted in less requests being made.
While testing I did find a small bug in Autoptimize (in /wp-content/autoptimize/classes/autoptimizeStyles.php) which caused jpeg images not to be taken into account. The regular expression in the code was ‘jpe?j’, while just below in a switch/case block ‘jpej’ and ‘jpg’ were referenced, resulting in neither ‘.jpg’ nor .’jpeg’ files ever being turned into data-uri’s. While reading the code I also noticed that the upper filesize limit for images to be turned into data-uri’s was set at 5120 bytes, but as base64-encoding does come with overhead, I decided to lower that limit to 2560 bytes.
So I made some minor changes in autoptimizeStyles.php on lines 207 and following:

if($path != false && preg_match('#\.(jpe?g|png|gif|bmp)$#',$path) && file_exists($path) && is_readable($path) && filesize($path) <= 2560) {
   switch(end(explode('.',$path))) {
      case 'jpeg':
         $dataurihead = 'data:image/jpeg;base64,';
         break;
      case 'jpg':
         $dataurihead = 'data:image/jpeg;base64,';
         break;
      case 'gif':
...

I also  switched my “subscribe” widget from a paragraph- to a bulleted list-approach with the rss- and mail-icons as background images and defined the adfreeblog and creative commons badges as background-images as well. And then I was ready to test the real impact of using data-uri’s on webpagetest.org. Behold the results for my current blog homepage (i.e. the one just before this post got published) with and without the use of data-uri’s (but excluding those dog-slow calls to stats.wordpress.com):

 No data-uri’sWith data-uri’s
webpagetest results URLhttp://www.webpagetest.org/result/121106_12_6FZ/http://www.webpagetest.org/result/121106_4H_71R/
#requests (full page)2619
Bytes in (full page)116KB114KB
Start render (median)0.615s0.634s
Doc Complete time (median)0.969s0.870s
Full page load time (median)1.932s1.332s

Let it be clear that the use of data-uri’s for background-images is not a silver bullet, but if you have images that are on every page of your site and they’re small in file-size, migrating those into your CSS as background-images with data-uri’s can result in an important performance improvement for your site.

Jetpack Notifications puts Quantcast tracking in your WordPress Admin

WP DoNotTrack user Marco Donati asked why the plugin did not stop Quantcast from being included in the WordPress admin pages. After some research (with the kind assistance of Marco), I discovered not one but two problems;
WP DoNotTrack relies on “output buffering” in WordPress to filter/ modify the HTML when in “Forced (default)” or “SuperClean” mode. Apparently WordPress does not use output buffering in the admin-pages, so WP DoNotTrack did not get triggered. My bad! I’ve updated the code to fallback to “Normal” mode when in admin and will push out a new version with this fix soon.
But then it got slightly ugly; even with this fix in place, the Quantcast-tracker kept on appearing! It was being called from within an iFrame, outside the reach of WP DoNotTrack. The culprit turned out to be the brand new “Jetpack Notifications” feature which -as most of Jetpack- is activated by default. As from Jetpack 1.9, you’ll see a small icon next to the greeting text on the right side of the admin-bar. When you click that icon a drop-down appears which contains the iFrame and the tracking code. To disable, in “Notifications” click on “Learn more” to reveal the “Disable”-button. Click that one and the icon, iFrame and tracker code are gone. Good riddance!
My advice to Jetpack users; explicitly disable any feature you do not use. Jetpack might offer some nice functionality, but of that is available in other plugins as well and being tied in that heavily into wordpress.com does come at a price. Moreover it seems there are some security concerns; as an user with author permissions I had access to the Jetpack overview page and I was able to activate the “Jetpack Comments” feature on Marco’s blog, but I couldn’t disable it. Call me a paranoid security-zealot, but non-administrator users should not really be able to do that, should they?

Learning from my Apache/ CDN mistakes

Earlier this year I configured this here little blog to offload static resources to MaxCDN. I made some mistakes in the process, which I documented in a blogpost that has been in my drafts for too long. So here’s the gist;

  1. Etags misconfiguration:
    • Problem: By default Apache uses the file’s inode to calculate the Etag, but that inode is unknown to the CDN, so Etags can never match.
    • Solution: change the Apache config not to use inode, e.g. “FileETag MTime Size”
  2. Cookies & domains issues:
    • Problem: I created my CDN-domain as a sub-domain of my main one, which led to (small) performance and (potentially huge) security issues.
    • Solution: Make sure your CDN-domain is different from the domain on which your cookies are set. So for example for main domain blog.futtta.be don’t use static-cdn.blog.futtta.be, but rather blog-cdn.futtta.be (except if cookies would be set on futtta.be, in which case I would need cdn-futtta.be).
    • Todo: it might make sense to add some Apache magic to make sure that for requests from the CDN:

My take on “Web design in a Retina world”

I read an interesting article on Johan Ronse’s blog about how to design (or is it “develop”?) for a Retina world (Retina being Apple’s marketing speak for high pixel density screens, but you guys knew that). I’ll be honest, I’ve not followed up on all the Retina-buzz, if only because this performance-nut isn’t particularly happy about the sudden need for higher quality images being shoved down people’s data-throat (same with webfonts actually). Because, after all, 14Mb really isn’t “nothing” Johan, given the average webpage is around 1.1Mb.
What seems to be missing in the few articles I did read up until now is this; why do we want to deliver high resolution images to high pixel density screens to users on a broadband connection (assuming we can keep others safe from these high fidelity images, but that is doable)? Because it looks better? Maybe, but what purpose does that serve? What purpose does your site serve? Do you want people to stick around and return, reading your stuff for a long as possible? Or are you in the ad displaying business? Maybe you sell products or services? The question is; how are Retina-ready images going to impact your KPI’s?
Let’s assume those nice crisp images will have a positive impact on your site’s usage and/or ad views and/or sales and let’s also assume (although it is a proven fact rather than an assumption) that the longer download time will have a negative effect on your business. Given these two assumptions; which one will have the biggest impact? My hunch would be the negative impact of longer download time, but I’m biased. The answer to that question really depends on your KPI’s, on your business and on the technical implementation.
The only sound advice anyone could give: do multi-variate testing, compare your KPI’s for your site with and without Retina. Going Retina might help your business, it might harm it. I for one am not switching to Retina any time soon, I don’t see the need for it from the safety of my ivory performance-tower. I’m biased, you know.

Join the Internet Defense League

Member of The Internet Defense LeagueYesterday I added a notification bar to this blog which invites visitors to join the Internet Defense League.
The notification bar is one of the several ways to participate with your own site or blog. I really liked the modal version better but that one seemed a tad too disruptive (I’m not 100% sure visitors would immediately understand this being an overlay with the actual blogpost underneath) and based on some tests on webpagetest.org (after adding internetdefenseleague.org and internetdefenseleague.s3.amazonaws.com to my WP DoNotTrack whitelist) it turned out to be significantly slower as well. The notification-bar variant has a more limited impact on page load time; only one extra 4.9KB request before document complete and a total of 5 requests at 14.1KB, which is … acceptable for this performance-nut.
So if you, like me, believe that we as internet-users should unite to take action against any law that goes against our interest (think SOPA, PIPA, ACTA, HADOPI, …), then joining the Internet Defense League might be a good idea.

Speed matters: re-evaluating WP YouTube Lyte’s performance

So stupid me made a (smallish) mistake when working on 1.1.0, which caused WP YouTube Lyte (rapidly approaching 80.000 downloads, thanks guys & girls) to load immediately instead of waiting for the “document loaded” event (lazy loading). That got fixed in 1.1.2 (which also loads the CSS differently, resulting in 1 file less to request), but the mistake did get me to re-investigate performance.
Exactly how fast is WP YouTube Lyte nowadays? I fired up some webpagetest.org IE9-instances in the Amsterdam node to compare this WP YouTube Lyte powered post on my test-blog with an identical blogpost with default YouTube embedded video. These are the jury’s results for the fastest of 10 runs in both cases (click on the image to actually see the details):

The main figures to compare (normal YouTube embed vs WP YouTube Lyte):

  • time till document complete: 1.612s vs 1.047s
  • time till fully loaded: 4.358s vs 1.385s
  • total number of requests: 13 vs 9
  • combined size of requests: 446 KB vs 77 KB

So using WP YouTube Lyte instead of normal YouTube embeds results in less files to download, less data to transport, the page being ready for interaction quicker and having everything loaded a whole lot faster. These figures are for a single YouTube on a page, but the impact is all the more important if you have multiple video’s on one page (e.g. a category or tag-page for “music” or “videos”) off course.
The full comparison based on 10 tests on both pages:

YouTube embed (full results)Lite YouTube Embed (full results)
doc completefully loadeddoc completefully loaded
min:1612380810471385
median:1918463111911524
max:3221511020782881

So there you go. When in doubt, check these stats and then go install WP YouTube Lyte, because after all speed matters!

Going against the reflow

You can do great things in JavaScript; accessing the DOM and adding, changing or removing nodes as you please. It is exactly that technology that WP YouTube Lyte is based upon; the PHP-part writes out an almost empty div’s with className “lyte” and with as id the YouTube ID, which the JS-part finds after the main document has loaded to render the “LYTE player”. Great for performance, so I was pretty surprised when DerTux, one of WP YouTube Lyte users wrote;

BTW, Google Page Speed dislikes Lyte:
“The following JavaScript call stack (executed 4 times) caused reflows that took 52 milliseconds: @wp-content/plugins/wp-youtube-lyte/lyte/lyte-min.:1:0

Although 52ms for a page with 3 “LYTE players” is minimal when compared to loading the same page with the full embedded YouTube player, the above statement bugged me enough to search the web for information about reflows and how to prevent them. Some of the more interesting articles:

And this video by Paul Irish does a great job explaining reflows:

HTML5, CSS3, and DOM Performance

Based on these pointers I started reworking lyte.js while testing on Google’s Page Speed Online (as far as I can tell the only tool that can detect reflows and then only as an experimental feature) to minimize reflows. I ended up:

  • adding the pL div, which contains the LYTE player UI (play-button, controls & YouTube thumbnail), only after all styles have been applied
  • adding the tC div, which contains the title, only after the tT div (with the title as received in the YouTUbe jsonp-call) has been added to it
  • replaced el.clientWidth (and el.clientHeight) with el.style.width.match(/\d+/g)[0]
  • some widths and heights did not have a unit specified in the dynamically generated CSS and this sloppy coding apparently also (indirectly) caused reflow

WP YouTube Lyte 1.1.1 will get pushed out in a couple of days (Thursday, probably) and will ship with these performance optimizations (and a fix for a regression which causes some styles not to be applied any more).

CDN to the Max

It was time to put my money where my mouth is, or at least to give the use of a CDN a try. Based on previous tests MaxCDN seemed like a decent, dirt-cheap solution, so that’s what the js, css & images for this blog are served from now.
Setting this up was very easy:

  1. log into MaxCDN and set up a pull zone on static-cdn.blog.futtta.be with origin blog.futtta.be
  2. create static-cdn.blog.futtta.be in the web interface of my DNS-provider (as a CNAME to the domain-name provided)
  3. configure WP Super Cache to use static-cdn.blog.futtta.be instead of the non-cdn static.blog.futtta.be)

The speed difference can be huge, especially when routing to my origin VPS-server in Germany isn’t great. I’m sure my 2 overseas users and Google will approve!
Bandwidth-wise, with 10MB/day, I seem to be far from the 1TB/year I’m allowed, so if you’d like me to setup a (temporary) pull zone for your blog so you can check out if this would work for you then just drop me a line.

Fiesta: WP YouTube Lyte reaches 1.0.0

I just released the one dot ohhhh dot ohhhhhhhhhh version of WP YouTube Lyte!
From the changelog:

  • new: also works on (manual) excerpts; just add a httpv link to the “excerpt” field on the post/page admin (based on feedback from Ruben@tuttingegneri)
  • new: if youtube-url contains “start” or “showinfo” parameters, these are used when playing the actual video. This means that you can now jump to a specific time in the YouTube video or stop the title/ author from being displayed (based on feedback from a.o. Miguel and Josh D)
  • update: javascript now initiates either after full page load or after 1 second (whatever comes first), thus avoiding video not showing due to other requests taking too long
  • update: bonus feature stops lockerz.com tracking by addtoany (you’ll still want to hide the “earn pointz” tab though)
  • bugfix: prevent the playing video to be in front of e.g. a dropdown-menu or lightbox (thanks to Matt Whittingham)
  • bugfix: solve overlap between player and text when option was set not to show links (reported by Josh D)

And an appropriate vid to go with this new release:

Toolbox: BrowserMob

A month ago I added BrowserMob to my toolbox. I’m sure I’m the last web-guy in the world to discover BrowserMob (or “Neustar Web Performance”, as of yesterday), but just in case you don’t know them either, it is an online service that provides availability- and performance-monitoring for websites and -applications.
Great stuff, really; create a simple script by providing a URL, choose what datacenters you want the test to run from, set the interval and there you go. After a couple of minutes you can start gazing at charts & reports or check your mailbox for alerts. You can create more complex tests using a JavaScript-based syntax or you can import Selenium-scripts (hello Selenium IDE for FireFox). The free account I started out with offers a substantial amount of pageviews/ month (40.000) that tests can generate.