Attention and immediacy are critical in digital media.
As the team building out Fusion.net, our primary job is making the on-site experience enjoyable. In a mobile world, this ultimately comes down to speed. In order for Fusion’s journalistic work to be most effective, our audience has to be able to read and share the content they want fast. Otherwise, it doesn’t spread.
For the past couple of weeks, we’ve focused on making this site faster. We wanted to make the experience of opening our links — especially on mobile devices — as painless and seamless as possible; to make it so that when you see a lil’ Fusion infusion in your newsfeed, you don’t hesitate to tap that story.
Here’s how we decided to move the needle forward.
Responsive images: We’re happy to say that we are now following the WHATWG spec for responsive images using the image
srcset attribute. This is a fully browser-based syntax for specifying alternate sources to load for images based on browser viewport dimensions. With this improvement, mobile users can load only the images pre-sized for their device, while desktop users can still appreciate all the work our art department puts into making huge animated hero images for posts.
We’ve also been monitoring image size and formats for all of our images. Large animated gifs or resolution-critical images that are saved in lossless formats like .pngs will eat up our bandwidth budget really fast, and the need to improve page speed has to always be balanced against the goal of eye-catching artwork to illustrate our stories. We’ve begun a discussion with our art department about these issues and are exploring possible solutions.
Preventing browser repaint events: Through profiling of our site, we found that the fixed position elements on our site (the sticky header at the top, and the forward/backward links on the left and right) were causing extremely heavy CPU load on some browsers when scrolling through the page. The issue is caused by Webkit (and other browsers) “doing a union of damaged regions” to repaint on scrolling. Because the header and left/right navigation are on the same compositing layer and the browser thinks they need to be handled together, it repaints a rectangle which contains all three of those elements – which is an area almost the size of the entire viewport! – on every scroll event. We found that adding the otherwise-meaningless
backface-visibility: hidden property to these elements forced the browser to treat them separately by marking them as having 3d transforms applied.
Improving liveblog load performance: Some of the most compelling content our Soccer Gods writers produce is their match-time liveblogs, which are a solidly curated mix of commentary, videos, pictures, and discussion from around Twitter and elsewhere. We’ve been using WordPress.com VIP’s Liveblog Add-On, which is conveniently available as an open source plugin. One weakness of this plugin is that, because it had no pagination features, long liveblogs with large number of embeds can take a while load. Joining a liveblog in progress in the second half of a match meant waiting up to ten seconds for the page to become responsive while scripts from Twitter and Vine marked up content all over the page.
We improved performance here by instituting lazy-loading on all liveblogs. When you visit a liveblog page, only enough entries to fill up one screen will be fetched at first, and additional posts will be processed as system resources become available, using the
window.requestAnimationFrame method, which works in most modern browsers (we fall back to using
setTimeout, which does a similar thing, in other browsers). Our work is available as a plugin on Github and will be released in the WordPress.org plugin repository soon.
Loading scripts and iframes asynchronously: Web page rendering is a long process with many milestones – when the first content is received, when the text is visible, when styling is rendered, and finally when page load is complete. A typical page with interactivity will depend on the window’s
Most of the ads we display are served as iframes which, compared to other techniques, are really easy to embed on the page, and to isolate styling and context so that they aren’t affected by our stylesheet—or worse, that styling from the ads doesn’t break our page. However, the downside of iframes are that they block the `onload` event of the page while building and setting up an entirely new DOM context and rendering it. We switched to using dynamic asynchronous iframes – substituting the
Between these and a few smaller issues, we’ve made solid performance gains that make fusion.net substantially more pleasant to visit and read content on. Some takeaways we found:
- Profile continuously. We’ve begun to introduce performance budgets, and are experimenting with monitoring tools like Speedcurve to make sure that we keep within our “budget” for page load time, asset weight, and more. But each component also need to be monitored in more detail, so we’re working on choosing the best way to do that.
- Question everything. There are a lot of performance-related “best practices” and commonly held wisdom that might not apply in your case. Your site’s performance bottleneck today might not be the same as it was in the past, or as it will be in the future. Before making any changes, make a hypothesis and test it by measuring and comparing relevant performance metrics.