JavaScript

FastClick Drupal module removes 300ms tap delay

Howdy perfers! This week is just a quick note to let you know about a new release for the FastClick Drupal module which provides integration for the FastClick JS library by FTLabs. Drop it on your sites and feel the difference on touch phones!

300ms tap delay makes for slower browsing

Have you ever noticed a delay between when you tap a link or other UI element and when it finally reacts? This is a solution to remove that delay! It is natively removed in newer versions of Chrome on Android, but for all browsers in iOS this library provides a very noticeable improvement. You might have noticed that tapping around our own site feels faster than it used to. We’re already running this module in production.

You can read about the history, watch a video that demonstrates the effect, and read the rationale for iOS’s continued use of 300ms delay in this HTML5 Rocks article.

Drupal module provides integration

The Drupal module is slim, but it makes for easy integration by downloading a copy of the library to sites/all/libraries/fastclick and adding the script into the footer area instead of up top in the <head>. The maintainer, Pere Orga, is very responsive to issues and open to discussion for improvements.

Code can be found at https://drupal.org/project/fastclick

Theme it once

The popularity of front-end JavaScript frameworks, driven largely by improvements in JavaScript performance, is skyrocketing. One of their strongest features is allowing developers to build extremely rich applications that will work the same way on most modern platforms. So it comes as no surprise that backbone.js found its way into Drupal 8 as a core JavaScript library. If you haven’t worked with a rich JavaScript application yet, you can be certain you will soon.

A key component of any rich JavaScript application, be it built on a framework or not, is templating. Each templating engine behaves slightly differntly but there’s one thing that they, and in fact all templating engines, have in common: scaffolding markup has placeholders which are later replaced with variables, like this:

That should look relatively familiar, in Drupal we’re used to seeing things like this:

Front end templating is great – it’s flexible and allows you to offload some of the processing power required to render a page to the client. There are some gotchas though, users without JavaScript support (or minimal JavaScript support) is an obvious one. A less obvious case that front end templating isn’t ideal is when you need to be able to render a page both on the client and server side. Dan Webb (@danwrong) from Twitter wrote extensively about Twitter’s move from an exclusively front-end rendered site to a mix of front-end and back-end rendered pages. In their case, and in many cases, a webpage can be delivered and ready for user interaction much faster when it’s been rendered on the server.

So, what am I getting at, and how does it relate to Drupal? Using either of the front-end templating gotchas from above, you can see that we’d need to have a template for both the frontend and backend source. That obviously sucks because now we have twice the markup that we need to deal with.

It doesn’t have to be that way though. By relying on Drupal’s rendering pipeline we can use one set of markup for both our front-end and back-end templates. Consider this simple module. In the theme_it_once() function we’re constructing an array of items to theme. Simple enough, but there’s something different about this page callback:

return array(
   'items' => array(
     '#theme' => 'item_list',
     '#items' => $items
   ),
   'template' => array(
     '#theme' => 'example_item',
     '#name' => '{name}',
     '#description' => '{description}',
     '#prefix' => '<script id="example-template" type="text/template"><li>',
     '#suffix' => '</li></script>',
   ),
 );

This render array has an additional element – template – which adds the markup from our PHP template to the page, wrapped in a script tag so it won’t be displayed. The resulting markup, which should look very familiar, will look like this (with some extra whitespace added for readability):

<script id="example-template" type="text/template">
  <li>
   <h4 class="item-name">{name}</h4>
   <p>{description}</p>
  </li>
</script>

Now let’s move to the front end and see how we can take advantage of this. In our example we’re going to use dust.js for the front-end templating engine, but the concept will be the same regardless of what you choose. Consider this script:

Notice that we’re grabbing the HTML from our template and compiling it into dust. We’re then rendering the template with a name and description variable and appending the result to the list generated by Drupal. Yes, it really is that simple to write your markup once and use it everywhere!

Beyond Examples

One of the biggest problems with this example for a rich application is the overhead associated with compiling the templates and the access to the DOM to fetch the template in the first place. In our example we only have one template, so the hit we take isn’t that great, but if we had many templates we’d want to precompile them. This obviously means adding a build task to create the generated templates file as needed. A drush command would be a great way to still keep everything in PHP templates. Your command would pass the front-end placeholders into your theme function in exactly the same way as I’ve shown here, but would then pass the resulting markup off to a child process – possibly grunt.js – to compile that markup.

A functional example of this code can be downloaded from the gist.

Automated Frontend Tools

Howdy, perfers! This week I’ve got some awesome resources for those of you looking to automate ALL the things! While you don’t have to use automation to achieve great performance on your website or webapp, it sure does help to keep things running smoothly and consistently. So have a look!

Frontend Ops

Back in June Alex Sexton wrote a great piece on how he perceives the not-yet-common position of frontend operations. He goes in depth about what he envisions when he says this, touching on deployment, builds, page load performance, rendering performance, developer workflows, and (of course) automating all of this stuff when possible. It’s a great, inspirational article that should get you thinking about how to handle the complex world of modern frontend development.

Automating Frontend Workflow

Addy Osmani recently posted this excellent, comprehensive overview of automated frontend workflows. It is jam-packed with tools, and even if you’re used to following this area of web development, there’s sure to be a few tool combos that you haven’t seen yet. Definitely worth a read for everyone who does frontend development. It goes from the basics of Grunt to scaffolding generators like Yeoman, and includes everything in between. While there aren’t as many in-depth examples, the breadth of tools covered will give everyone, designers and developers alike, something to chew on.

Intro to Frontend Ops

This is a slide deck of my own creation, presented at both DrupalCon Prague and BADCamp. In contrast to Addy’s all-encompassing overview, it is intro level and aimed specifically at people who build Drupal sites. However, the slides are accompanied by working code samples that you can install instantly after cloning the slides (and after installing ruby, homebrew, node.js, and npm :p). My hope is that you can start using these tools today, rather than “getting around to it” eventually.

Multilingual CSS generated content in Drupal

CSS generated content is cool. You can make those little triangles everyone seems to love, but its real purpose is to let you add presentational words that would otherwise be a pain to generate in markup for some situations.

a:before {
  content: 'Download item';
}

It can do other neat things like output the contents of another attribute on your element. This feature was originally created to allow print stylesheets to display URLs inline for printed documents:

a:after {
  content: ' (' attr(href) ')';
}

But what happens when you need to bring multilingual into the mix? We occasionally build multilingual sites, and typically there is translatable content at every level of the stack: Drupal nodes, template files, CSS, JS, you name it. When I was originally tasked with solving this it seemed like a big problem, but it turns out to be relatively simple.

My initial thought was to use the language attribute of html tag and make individual, static content properties, but that leads to code bloat as you accommodate each new language. Furthermore, in Drupal’s case, it leaves your strings stranded in CSS and inaccessible to translators which have an interface built into Drupal’s admin UI.

Solution: Dynamically generate attributes

We had a client who wanted the links to be big CTAs accompanied by the instructions “Download item.” So instead of hardcoding the English words into my stylesheet, I added a data-attribute into the DOM via JavaScript (you could also do this in Drupal by creating or modifying the appropriate field.tpl.php, but I did some other things with JS so it was simpler to keep it all in one file).

$('.my-field').attr('data-cta-msg', Drupal.t('Download item'));

Notice Drupal.t in there? t is for translate, and it is the standard mechanism for localizing JS-powered UI components in Drupal 6, Drupal 7, and Drupal 8. There’s a bit of background magic that happens, but in a nutshell once a page containing your new Drupal.t() string has been loaded, you can access it in the Translate interface in the Drupal admin UI:

Drupal 7 interface for translating non-content/UI strings

Now you can grab a translator, add the appropriate text, and your stylesheet will always supply the correct translation in your CSS generated content! Look at the minor modification to CSS content property (compare to the very first example in this article)

a:before {
  content: attr(data-cta-msg);
}

And here’s the result in English and Arabic respectively:

English download button with CSS generated content

Arabic download button with CSS generated content

Update: Down in the comments Dan Mouyard pointed out how any CSS generated content is less accessible than real markup. Just a heads up for general use of CSS content that is intended to be read aloud on the page, not just the multilingual method described in this article.

DevTools link roundup

Today I looked through my collection of links and realized I have enough resources pooled up to put together a decent little post on browser devtools. In case you’re not familiar, development tools ship with each web browser, enabling us to analyze and debug our increasingly complex websites and apps. From finding a background color to profiling frame rate issues, browser devtools bring sanity to the world of frontend development.

Discover (Chrome) DevTools

Put together by Google and Code School, Discover DevTools takes you from zero to master using Chrome DevTools. It’s a series of 17 videos with over 75 challenges for you to complete along the way. Although the course is Chrome-specific, other browsers’ tools are similar or identical in many cases, and the real takeaway is the ability to use these tools regardless of how the buttons are laid out in a given browser.

Secrets of the Browser Developer Tools

Secrets of the Browser Developer Tools provides bite-size tips for all browsers’ development tools. There are enough that you’ll probably learn something new just by skimming. They’re broken up into various categories, and each tip is accompanied by a list of platforms where the feature can be found. This fantastic resource is brought to you by @AndiSmith and he welcomes contributions.

DevTools can do THAT?

The last link is a set of performance-oriented slides from Ilya Grigorik detailing some of the finer points within Chrome DevTools. He highlights not only particular settings but how to configure them in order to easily test for different situations (e.g. cold/warm cache). Also included is a quick walkthrough explaining network waterfalls, the life of a request as visualized in DevTools, options for exporting and processing HAR files (a JSON format for storing network waterfalls), and overviews (plus examples) of Timeline and Profiles tabs, which help you debug rendering and memory issues.

Chrome DevTools Revolutions 2013

Update 2013-11-13: Since I published this, another awesome HTML5 Rocks tutorial has been posted showing some of the latest features of Chrome DevTools, including Sass source maps, remote debugging, and some sick tools to help you debug rendering performance. Eat it up ;)

Browsers want your feedback!

Although they have a ton of features, browser makers always want to hear from YOU, the one in the trenches. Most browsers have a dedicated developer relations team to ensure that the tools stay up to date and sensible for the hard-working people of the web. Here are their twitter accounts:

Magic: Frontend Performance for all themes

Howdy perfers!

This week’s Webperf Wednesday is short and sweet, just like your page loads when you install this new module that enhances any Drupal theme. Magic is a set of frontend performance and development workflow tools for themers. Previously many themes had their own advanced settings — many of which did the same things as other themes, but they all did it a little differently — no more with Magic.

Built by Web Chef Ian Carrico and Sam Richard (of Aurora) with contributions from Sebastian Siemssen (of Omega), Magic was built by the desire to work together to make all themes better, instead of siloing improvements within specific themes.

What’s inside?

Performance features:

  • Enhancements to CSS Aggregation
  • Exclude CSS files from being included
  • Option to move JavaScript to the footer
  • Backport of Drupal 8 JavaScript handling
  • Exclude JS files from being included

Development goodies

  • Rebuild Theme Registry on Page Reload
  • Display a Viewport Width indicator
  • Display an indicator with classes applied to the HTML. Useful when used in conjunction with Modernizr
  • Export theme settings

That last one is super important, as it makes Drupal themes a little more DRY. With Magic, you can take your settings from one theme to another — or to another site completely — because they’re fully exportable. Have two different projects, and want similar asset output despite one being Omega and one being Zen? No problem, just export!

Note: the full import process has yet to land, but it’s coming very soon.

If you have an awesome trick that you always rely on during theming, open an issue and propose it to Magic. They’d love to hear from you.

Give it a shot today! Go to drupal.org/project/magic

One less JPG

I’d like to demo a simple how-to. There are many, many techniques to make pages load faster, but this post attempts to demonstrate large gains from very small code changes.

People often build beautiful sites with multiple easy-to-use JavaScript libraries. Then, when it comes to addressing frontend performance, suddenly those libraries are an enormous download that the users are forced to bear.

Just one image

Before you go worrying about how to minify every last library or shave tests out of Modernizr, try and see if you can remove just one photo from your design. It will make a bigger difference.

Coined by Adam Sontag, the “one less JPG” idea — nay, MOVEMENT — is summed up perfectly here:

Real example

Last year we re-launched Pressflow.org. We have some mobile traffic, but it’s likely people just browsing for info, since no one has a good reason to download Pressflow onto a phone or tablet. Let’s keep their attention and make the experience fast.

We have this huge, beautiful mountain on the homepage. It’s great. But it’s also 160K. I tried making it smaller, or splitting the photo off of the background pattern, but it decreased the quality of the photo too much when I lowered the file size. We made a wonderfully small SVG logo, but that’s not an option for a photograph with this kind of detail.

How much impact does it have?

A mountain is a big thing — just like the amount of traffic Pressflow can handle — and the image we chose was meant to convey that vastness. Since it doesn’t really pack the same punch on smaller screens, why include it at all? I decided to use Modernizr and conditionally load the stylesheet that references the mountain. That way it never gets loaded by tiny screens that don’t need it.

Using the Modernizr Drupal module, I added a conditional load into the .info file of my theme:

; Load CSS with Modernizr
modernizr[Modernizr.mq('screen and (min-width: 42em)')][yep][] = css/big.css

This tells Modernizr to output a Modernizr.load() statement with the test I specified. In this case, Modernizr will only load big.css if the test is true. My test checks the width of the window using a media query — .mq() — and returns true if the screen is at least 42em, causing the CSS to be fetched. Here’s the JavaScript output:

Modernizr.load({
  test: Modernizr.mq('screen and (min-width: 42em)'),
  yep : 'http://pressflow.org/sites/all/themes/pfo/css/big.css',
});

So that’s it, instant savings!

..oh what’s that? Always test your work? Thanks for keeping me honest.

Here’s some data.

I’ve got two network waterfalls here for comparison. They show a pretty stark difference following this one-line change to my code. If a screen isn’t big enough for the mountain, it’ll only take 20 HTTP requests and 193K total. If the screen is big enough, it takes 24 HTTP requests — for the CSS and then the images inside it — totalling 384KB total. That’s a savings of 191KB (almost exactly 50%) from a single change to my code. You’d have to remove 19 copies of jQuery 2.0 to achieve this kind of bandwidth savings.

(by the way, didja hear that jQuery 2.0 has small QSA-only custom builds?)

Small screens

Waterfall: Conditional load small

Big screens

Waterfall: Conditional load big

You can see in the second waterfall that the Initiator of big.css is modernizr.min.js, meaning that JavaScript loaded the file after running the test.

ThoughtContentLoaded

I hope this shows how easy it can be to reduce your page weight without worrying about shaving bytes of JavaScript that are supplying valuable functionality if you know how to use them right.

If you want to know more about the conditional loading API within Modernizr, head over to yepnope.js documentation and start reading. For more Drupal-specific examples check out the official documentation for conditional loading using the Modernizr module.

Webperf Wednesday: Video Roundup

Hey, speeders! There have been some great presentation videos put up on the web recently, so I’ve got links to a couple videos this week.

Breaking the 1000ms time-to-glass barrier

Last week we checked out slides from Ilya Grigorik, so if you enjoyed those you have to check out his 45-min presentation recorded during the last SFHTML5 meetup. For mobile web developers this is required watching. He starts with the constraint that he wants to load a mobile web page in less than 1000ms, and proceeds backwards, walking through the realities of phone chips/towers, mobile network latency, and battery usage, in addition to more familiar concepts like image compression, the browser rendering stack, and reflow/repaint gotchas. Warning: you might need a cigarette after watching this video!

Steve Souders HTML5 DevConf keynote

Steve Souders delivered a great keynote at the HTML5 Developer Conference, and he makes it very clear that users want speed. One of the original powerhouses in the frontend performance world, Steve has created more resources and tools than is possible to list here, so I’ll just encourage you to check out his site if you’re not familiar with his work. His latest blog post also contains some errata from this video so if you like it please head over there to pick up the corrections.

Webperf Wednesday: Inaugural edition

I’ve been kicking around this idea for quite some time and finally sat down to get it published. Four Kitchens has always taken performance very seriously, but traditionally most people only focus on backend server performance when thinking about these types of issues. I’m not a hardcore backend dev, but I have plenty of experience making things fast and useful within a web browser.

To that end, I’d like to spread the word about frontend performance by publishing a periodic blog post series highlighting techniques, articles, and other webperf stuff that we’re talking about day-to-day in the office. So without further ado, here are this week’s links:

Building Faster Mobile Websites (.pdf)

Ilya Grigorik presents an extremely compelling case for putting speed at the top of your priority list, especially on responsive and otherwise mobile websites. He explores the realities of network latency and suggests methods that could be used to break the 1000ms “time-to-glass” barrier. It’s a low-level, deep dive into the effects of TCP/IP and HTTP requests on your site’s loading speed, and contains tons of great information to help you build fast sites. To make the most of these slides, you’ll have to work closely with backend and/or deployment people who help manage your sites, but the payoff is well worth it.

Double-whammy from Alex Sexton

Alex has recently published a couple great resources that can actually help you achieve the lofty goals in Ilya’s slides. First is a blog post entitled Deploying JavaScript Applications that talks about building a web application which matches user action patterns, relies on intelligent caching, and employs distributed deployment (like CDNs) whenever possible. He also lists some lower hanging fruit such as reducing use of images before shaving bytes of JavaScript.

Next are his slides from HTML5 Developer Conference that highlight the awesome new Modernizr v3 workflow. Very closely related to deploying JS apps, he outlines how the Modernizr v3 will help you build applications which adapt to the browser loading it, allowing for tiered, optimized experiences that match each browser’s capabilities while minimizing the loading of unnecessary assets. Having helped out with the v3 work, I’m especially excited to see people begin to use it.

Prerender in Chrome for Faster Page Loads

A couple weeks back I wrote about a feature of Chromium that Ilya has helped publicize in his upcoming book, High-Performance Browser Networking. It’s a <link> tag which lets you suggest pages that Chrome should prerender in cases where your traffic funnels are extremely predictable. This is a great example of using data to accurately predict user actions rather than directly altering the load time of your pages. Although they still load at the speed of the network, the end result can reduce apparent load times to 0.0s in some cases! Check out my example which is live on Pressflow.org.

Auf Wiedersehen

I hope you enjoyed these links! As I mentioned earlier, these posts won’t always be limited to links, so check back for code snippets, full implementation walkthroughs, and other goodies in the future.

Feel free to leave feedback or topic requests in the comments, and happy perfing!

Minified JavaScript, on the Fly!

As web applications become richer and more complicated the amount of JavaScript running them increases. More code means longer download times which means more waiting before your application or web site is usable. Thankfully there’s an easy solution that’s already widely used in the web development community: minification. Minified JavaScript strips whitespace and renames variables to produce a smaller download size.

Removing whitespace is pretty straightforward, but renaming variables is a more abstract concept. With tools like UglifyJS this is handled for you but here’s an example of what’s going on. Let’s look at this simple function that takes a parameter and alerts a message with that variable:

var sayHi = function(name) {
  alert('Hi ' + name + '!');
};

With script minification the above code will be changed to this:

var sayHi=function(a){alert("Hi "+a+"!")};

without altering the behavior of the function. As you can see, all whitespace that can be removed has been and the variable “name” was changed to “a”. The end result is the removal of 26 characters from the code. It’s not hard to see that the savings from minification will quickly add up!

You can take this one step further by wrapping your code in immediately-invoked function expressions (IIFEs). That’s a pretty scary looking name, but chances are you’ve seen these before, this is an example:

(function($) {
  $('h1').css('text-decoration', 'blink');
}(jQuery));

The function wrapped in parentheses is immediately invoked with jQuery as its argument. Within the function jQuery is accessed with the $ variable. Abstracting variables in IIFEs is not required though, consider this case:

(function(Drupal) {
  Drupal.behaviors.sayHi = {
    attach: function(name) {
      alert('Hi ' + name + '!');
    }
  };
}(Drupal));

Minifying this code produces the following:

(function(a){a.behaviors.sayHi={attach:function(a){alert("Hi "+a+"!")}}})(Drupal);

Keeping the “Drupal” variable in your script makes sense because that’s the namespace you’re used to accessing it with and it does have meaning in the code, but by including it as an argument to the IIFE UglifyJS will replace any instances of “Drupal” with a shortened variable.

What about Drupal?

So, this is pretty cool, right? Unfortunately Drupal 7 doesn’t provide minification out of the box. Thankfully, there are contrib solutions to this problem! The Speedy module provides pre-minified scripts but unfortunately needs to be re-released every time core is updated or you need to re-minify the files yourself on core updates.

I wasn’t completely satisfied with this approach so I built uglify.me and a companion Drupal module, UglifyJS, to do script minification on the fly. uglify.me isn’t the only “minifier-as-a-service” out there, but I wanted to be able to throw something up quickly and be fairly confident that it wouldn’t upset some other poor developer out there hosting their own service.

The uglify.me service accepts POST requests of un-minified JavaScript and returns the minified version. Simple! The UglifyJS module provides an API to expose Drupal scripts that should be minified:

/**
 * Implements hook_uglifyjs_info().
 */
function mymodule_uglifyjs_info() {
  return array(
    drupal_get_path('module', 'mymodule') . '/js/mymodule.js',
  );
}

The downside to this approach is that each script will create another request to the uglify.me service when the site cache is cold. If you expose a lot of scripts to the UglifyJS API this will be time consuming and could cause timeouts.

If you’re running Pressflow 7.20.1+ or apply this patch to core and you have JavaScript concatenation enabled (which you should, if you’re in production) the UglifyJS module will automatically minify the concatenated scripts. This greatly reduces the number of requests to the web service and overhead associated with minification.

Caveats

The biggest issue that I’ve encountered with this module is the requests made to the external web service. If there’s a problem connecting to the remote server the time spent waiting for the response is wasted and can cause timeouts on cold caches. This is mitigated if you’re using Pressflow 7.20.1+ since core will not request files to be rebuilt if the hash of the concatenated scripts did not change.

The uglify.me service also currently strips some header comments from scripts which would could remove any copyright or license information if they exist. This should be fixable from the uglify.me service, so if it’s bothering you and I haven’t had time to fix it before you need it, As of uglify.me v0.1.0 any comment containing the words “license” or “copyright” (case insensitive), or the common build tags “@preserve” and “@cc_on” will not be stripped from the source code. This is controlled by a regular expression so if you find a general case that’s not met by the current regular expression open a pull request to fix it!

Conclusion

Script minification is a great way to reduce your site’s download footprint and increase usability. If bandwidth and performance are concerns you should be minifying, regardless of your ultimate solution. Informal testing on the recently released Full Plate Living site showed reduction in the front page’s download weight by an average of 110KB*. Not monumental, but not too bad either.

Happy minifying!

* Note: The UglifyJS module is not currently in use on the production Full Plate Living site, but it likely will be soon!

Pages