Stipple Code is Unobtrusive to Sites It Runs On
Installing Stipple on your website is not only easy, it’s very safe. As a federated platform, it is crucial for the Stipple code to play nicely with all manner of website architectures, disparate page structures and various third-party plugins and libraries. This post describes one of the strategies Stipple uses to stay unobtrusive and avoid any unintended effects on your site’s user experience.
Asynchronous Loading
When a user visits a Stippled website, the first thing that must occur before any dots are displayed is the Stipple code itself must be loaded and initialized. As an embeddable javascript library, Stipple can be loaded the same way any other javascript asset would be, by adding a script tag to the page:
|
1 |
<script type="text/javascript" src="http://stippleit.com/stipple.js"></script> |
However, this approach has a significant disadvantage. Because web browsers commonly load assets (such as javascript files) one by one in the order they are encountered within the HTML, the browser will wait until the stipple code has finished downloading before it will continue loading the rest of the page. If you’ve ever been sitting on a blank page, waiting for it to load and seeing messages in the status bar such as “waiting for someothersite.com…” one after another, this is what’s happening. This synchronous loading of external items can end up taking a long time, delaying the display of page content and significantly degrading a site’s user experience.
This problem can be mitigated to some extent by simply embedding the <script> tag at the bottom of the page (usually just before the closing </body> tag). However, this approach defers the download so it does not even begin until very late in the page load process. What we really want is to kick off our javascript download asynchronously while the rest of the page continues loading right along.
In order to download assets asynchrounously, HTML5 provides an “async” attribute for the script tag:
|
1 |
<script type="text/javascript" src="http://stippleit.com/stipple.js"></script> |
Unfortunately, this async attribute is not supported by Internet Explorer so Stipple employs a well established pattern for asynchronous script loading that works just about everywhere. Let’s look at it applied to the Stipple framework.
When you register your website with Stipple, the “install” tab on your site dashboard provides the code you need to enable Stipple on your site and begin tagging images. Ignoring the wrapper tags, here’s what that install code looks like:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
var _stippleq = _stippleq || [];
(function() {
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = location.protocol === 'https:' ? 'https://stippleit.com/stipple.js' : 'http://stipple.cachefly.net/production/stipple.js';
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
})();
_stippleq.push(['load', 'your-site-id', {}]); |
Putting aside the first and last lines for now, we have:
|
1 2 3 4 5 6 7 8 |
(function() {
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = location.protocol === 'https:' ? 'https://stippleit.com/stipple.js' : 'http://stipple.cachefly.net/production/stipple.js';
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
})(); |
This is the code that actually downloads the Stipple javascript and embeds it in your page. Notice that this code is wrapped in an anonymous function which we are invoking inline (that last pair of parentheses before the semi-colon). Great writeups about this pattern abound on the web, so suffice it to say that the upshot of executing this script is that it dynamically injects a script tag like this into the HTML of your page:
|
1 |
<script type="text/javascript" src="http://stippleit.com/stipple.js"></script> |
Look familiar? The trick here is that we dynamically injected this tag using our anonymous javascript function to directly manipulate the page’s HTML structure. The browser, sensing that the page has changed, processes this new tag asynchronously from the rest of the page load — which is exactly what we want.
What about initializing Stipple and dotting those images? Once the Stipple code has finished downloading, we could just invoke the “load” command on it:
|
1 |
STIPPLE.load('your-site-id', {}); |
The problem is: when do we know when the code has finished downloading? We triggered the download asynchronously in another thread of execution, so it could finish anytime unbeknownst to the rest of the page where our install script still lives. Look again at the first and last lines of code:
|
1 2 |
var _stippleq = _stippleq || [];
_stippleq.push(['load', 'your-site-id', {}]); |
Rather than calling methods directly on the Stipple library, commands are issued by adding them to a queue (the “_stippleq” variable). Once the Stipple code becomes available it will immediately start grabbing commands from the queue and executing them.
Using this strategy, Stipple is applied to the page at the earliest possible opportunity without interrupting the normal page loading process. Our goal is to be as unobtrusive as possible so that the website’s existing user experience is preserved and enhanced with the addition of Stipple. In order to be a good citizen within a website’s ecosystem of extensions and plugins, it’s very important to us that Stipple behaves safely and politely right alongside every other component in a site’s existing infrastructure.
- this post was written by Scott Brown, Stipple’s VP of Engineering
(thumbnail photo courtesy of flickr user Patrick Hoesly)