Advanced Articles

High Performance SVGs

I recently worked on a project that was getting a ton of traffic but users were bouncing because the page load was too long at around 10 seconds. They called me in because the majority of the images on that site were SVGs, and they were animated. I trained the team how to decrease the file size on the SVGs while preserving the appearance and functionality, finally getting the load time to under 2 seconds. The bounce rate dropped dramatically and conversion was restored.

(more…)

Getting Started with the WordPress Customizer

The following is a guest post by Scott Fennell, a WordPress theme & plugin developer in Anchorage, AK and a regular contributor around here.

Let's say you have a client whose business is large enough to have several departments. Now let's say that this client wants each of their departments to have their own website on a dedicated domain. Each site is to have the same layout, but a different color scheme. This is a phenomenal use-case for the WordPress Customizer (aka the Theme Customization API), and I'd like to share a basic example of how to build it into a theme.

(more…)

Understanding JavaScript Constructors

The following is a guest post by Faraz Kelhini. Some of this stuff is out of my comfort zone, so I asked Kyle Simpson to tech check it for me. Kyle's answer (which we did during an Office Hours session) was very interesting. It was: 1) This article is technically sound. JavaScript doesn't really have classes in a traditional sense and this is the way most people shoehorn them in. 2) We may want to stop shoehorning them in. JavaScript has objects and we can use them in the way they are intended to do the same kinds of things. Kyle calls it OLOO (Objects Linked to Other Objects). Here's an intro. I'd think there is value in learning about both.

(more…)

Can You “Over Organize” JavaScript?

There's no question that on sites with lots of JavaScript, you need a strict organizational pattern to keep everything making sense and the code approachable. I've mentioned in the past I like grouping things into individual files each containing a functionality-specific object literal. Taking things a wee bit further, we can be strict about this pattern and make sure we group together all sectors in one place, all "init" functions in one place, all event binding in once place, and have the rest be little well-named mini functions that do very specific things.

I wonder though, is this too organized?

(more…)

Play Sound on Hover – Web Audio API Edition

I got an email from a Notary Sojac who saw my tutorial on playing a sound on hover. In that tutorial we had to resort to some fairly hackish behavior to get the sound to react nicely to our events. Notary Sojac had an update to make the existing code work better, but more importantly, was looking into the Web Audio API for doing stuff like this. I didn't even know that was a thing. Turns out it's not controlling HTML5 audio elements, it's deeper level access than that.

The following is a guest post by Notary Sojac explaining all that.

We're all impressed with the capabilities of HTML5 canvas. The idea of creating a standardized and logical way of performing 2d drawing operations opened the door to an amazing new world where one programmer could learn one language and develop amazing products that could be deployed to all relevant platforms! Think about how critical this is for a moment. Now think about who would want an amazing graphics application that has a buggy, glitchy sound system that only makes sounds moments after you clicked and sometimes forgets to make sounds all together? That's the kind of product you get (especially in mobile platforms) if you go the HTML5 <audio> element route. It's better in desktop browsers, but unfortunately will never be perfected due to reasons beyond the scope of this article. But as of now, for the desktop, there is still hope. And there is hope in the future for mobile applications as well. That hope is named...

Web Audio API

The web audio API is designed for high precision and low level access. You can literally write bits of data to the samples. I'm not 100% sure what a sample is, but I think it has to do with air pressure against a microphone (aka, the microphone's driver position) at a single moment in time. That's pretty low level if you ask me. In Google Chrome, all audio functions are handled by a separate thread to ensure non-wonkyness.

On August 21st, Mozilla began making public the fact that they're dropping their original, pioneering "Audio Data API" and are beginning to implement Google's "Web Audio API" in their browser. But that means, at the time of this writing, you'll need to use a fallback for Firefox.

You can hear a great deal of good information from this Google I/O talk by Chris Wilson:

How To Use It

Unfortunately you need to use a lot more JavaScript with the Web Audio API than you do with plain old HTML5 audio elements, but often times the precision of the Web Audio API is imperative.

First we need to load the sound, which can be done with a function like this:

// you'll put the PCM audio in here
var audioBuffer = null;  
var context = new webkitAudioContext();

function loadDogSound(url, variableToBufferSound) {
  var request = new XMLHttpRequest();
  request.open('GET', url, true);
  request.responseType = 'arraybuffer';

  // Decode asynchronously
  request.onload = function() {
    context.decodeAudioData(request.response, function(buffer) {
      variableToBufferSoundIn = buffer;
    }, onError);
  }
  request.send();
}

Then we play the buffer, with a function like this:

function playSound(buffer) {

  // creates a sound source
  var source = context.createBufferSource();

  // tell the source which sound to play
  source.buffer = buffer;          

  // connect the source to the context's destination (the speakers)           
  source.connect(context.destination);       
  
  // play the source now
  source.noteOn(0);                          
}

That's a heck of a lot more code than we need as designers, just trying to play simple mouseover sound effects. Luckily, I snapped together a little JavaScript framework for using the Web Audio API.

With this new API, all one needs to do is:

  1. Create an AudioContext
  2. Load a sound into that AudioContext
  3. Play the sound

All of these steps are one liners! Fallbacks to good old HTML5 are included!

<script src="javascripts/webAudioApiForDesigners.js"></script>

<script>
// 1
var context = initializeNewWebAudioContext();

// 2
context.loadSound('audio/beep.ogg', 'beep');

$("#nav-one a")
  .mouseenter(function() {
    // 3
   context.playSound('beep');
  });
</script>

View Demo

List of reasons why HTML5 audio elements may be a bad choice

  • Wonky latency problems where sounds are heard at wrong times
  • Unexplainable popping sounds when playing multiple sound files at once
  • Limit to number of HTML5 audio elements that can play simultaneously

Reasons why HTML5 might be more suitable to your project

  • Very simple and straightforward to use
  • Can play background music just fine
  • Eventually (wild guess: no sooner than within the next 3 years) the bugs will be ironed out of these sorts of html DOM elements

More Information

HTML5 Rocks has a solid introduction.

Custom Events are Pretty Cool

Let's say you are working on a web application in jQuery and you are tasked with writing an accordion suited to the needs of your web app. You decide to make it into a plugin. That way anywhere in this app that needs an accordion, they can load this plugin and call it upon semantic markup that is ready to become an accordion. Then ta-da, they have a lovely working accordion.

Now another developer is using your accordion and they want to be able to Ajax load some content into one of the sections of the accordion, but only when that section is opened. Together you decide that you should keep your code separate. The generic functionality of how an accordion works should be separate from code specific to one accordion on one page of an app.

Callbacks, the traditional way

One way to approach that would be to write "callbacks" into your plugin. The other developer would specify the name of a function that she wants run when certain actions happen on that accordion. So the calling of it might be like:

$(".accordion").accordion({
  panelOpen: myPanelOpenCallback,
  panelClose: myPanelCloseCallback;
});

And they would have created those callback functions themselves:

function myPanelOpenCallback() {
  // Do Ajax stuff 
}

Then the plugin itself would honor those callbacks in its related internal functions:

$.fn.accordion = function(options) {
    
	return this.each(function(i, el) {

	  var base = el;
	  
	  base.init = function() {
	  	// Do initialization stuff
	  };
	  
	  base.openPanel = function(panel) {
	  	// Open panel
		
		// Do callback
		options.panelOpen.call();
	  };
	  
	  base.closePanel = function(panel) {
	  	// Open panel
		
		// Do callback
		options.panelClose.call();
	  };
	  
	  base.init();
	       
	});
  
};

View Demo of Callback Model

Custom Events, a better way

Now let's say a third developer gets involved, and they also want to write a bit of JavaScript that reacts to a panel opening as well. For the sake of a use case, say what's inside the accordion panels are settings, and this developer wants to save those settings whenever keys are opened or closed automatically.

Now we're in an interesting position. We've already defined our callback for accordion panels opening and closing. So in the callback model, these developers are going to have to get together on that callback and run both of their code in that one callback. Not that big of a deal, but now we're forced to mix code when that might not be ideal. Remember we started this whole thing off by separating specific functionalities.

Here's where custom events are super rad. Instead of firing off a specified callback, the accordion functionality plugin fires off a custom event. Custom events are just like any other event (e.g. click) only they are only declared and called programmatically.

First, callbacks are gone, we just call the accordion plugin without them:

$(".accordion").accordion();

Now in place of where we called the callbacks, we'll trigger our Custom Event. Basically, just make up a name that makes sense (like you are naming a function).

// OUT
// options.panelOpen.call();

// IN
panel.trigger("panelOpen");

Now our other developers can bind their stuff to this custom event and do their own thing.

$(".panel").on("panelOpen", function() {
   // Developer 1: do Ajax stuff
});

// Meanwhile, in another part of town...
$(".panel").on("panelOpen", function() {
   // Developer 2: do saving stuff
});

Yay for freedom! Yay for separation of functionality!

In my opinion custom events are just better all around. I do think they require a bit more communication though. You'll probably have to write up some comments somewhere that explain what custom events are fired and when and make that easy to discover.

View Demo of Custom Events model

More Information

The scenario outlined above is very simple. The following two articles go way more into depth about Custom Events including more complex examples and more information on how they work.

Animated Knockout Letters

I was watching some commercial the other day and they had these letters fly in over a black screen and reveal an image beneath them. It was a pretty cool looking effect and it reminded me how WebKit has that cool -webkit-background-clip property which allows you to show background through text. So I set off on trying to see if I could do something like that. You can, but there are some interested stumbling points...

(more…)

We have a pretty good* newsletter.