Adtile Technologies

About Adtile Technologies

Adtile is a pioneer and developer of motion-sensing technology for smartphones and tablets. We are working with leading technology companies and Fortune 500 brands.

Follow us on Twitter

Responsive & Fixed One Page Nav

Adtile Technologies
Adtile Technologies wrote this on

Responsi Fixed One Page Navigation

Today, we are open sourcing the JavaScript code and the assets we used to build the above functionality for our new website. The code and examples are hosted on GitHub and can be found from here. There’s a live example too, under our site, give it a spin. Below is a list of some of the features provided:

Fixed Nav Features

  • Fixed positioned, always visible navigation bar
  • Uses vanilla JavaScript, no jQuery required
  • Smooth animated scrolling
  • Removes 300ms tap delay
  • Adds a mask over the content when navigation is open
  • Auto highlights current location when scrolling the site
  • Uses a tiny custom font for icons (only two characters included)
  • Closes the navigation when user tap’s outside of it
  • Tapping a link changes the URL, so users can still copy/paste it from the address bar and link to different sections
  • Built progressive enhancement in mind
  • Tested to be working in IE6 and up

Fixed Nav on GitHub →

A Dive Into Plain JavaScript

Adtile Technologies
Adtile Technologies wrote this on

While I’ve worked over a decade building various websites, it has only been the past 3 years that I’ve started learning more on how to work with plain JavaScript, instead of using jQuery always as the starting point. The fact that I’m learning a dozen new things every day now, has made working on Adtile’s JavaScript SDK feel more like building an open source project than “actual work,” and I have to say I like that a lot.

Today, I’m going to share some of the basic things I’ve learned during the past years, which will hopefully also help you to dive into the world of plain JavaScript, making it easier to decide whether or not you will need jQuery in your next project.

Progressive Enhancement

While libraries like jQuery help to forget most of the browser inconsistencies, you really become familiar with them once you start using plain JavaScript for everything. To avoid writing JavaScript that’s full of browser hacks and code which only solves browser compatibility issues, I recommend building a progressively enhanced experience using feature detection to only target the more modern browsers. This doesn’t mean that browsers like IE7 don’t see anything at all, it just means that they get a more basic experience without JavaScript enhancements.

Here’s How We’re Doing It

We have a separate JavaScript partial which has all the feature tests. The actual list of tests is often much longer, but let’s get back to this a bit later. To rule out some of the older browsers we use these two tests:

var test = {
  addEventListener : !!window.addEventListener,
  querySelectorAll : !!document.querySelectorAll,
};

Then, in the main application partial, we detect if these features are supported by using this simple "if" statement below. If they aren’t supported, the browser won’t execute any of this code:

if (test.addEventListener && test.querySelectorAll) {
  this.init();
}

These two tests make sure that we have a native way of using CSS selectors in our JavaScript (querySelectorAll), a way to easily add and remove events (addEventListener) and also that the browser’s standards support is better than what IE8 has. Read more about this technique called “Cutting the mustard” from BBC’s blog.

Browser Support

Here’s a rough list of the browsers which support the features we are testing, and will hence keep executing the JavaScript:

  • IE9+
  • Firefox 3.5+
  • Opera 9+
  • Safari 4+
  • Chrome 1+
  • iPhone and iPad iOS1+
  • Android phone and tablets 2.1+
  • Blackberry OS6+
  • Windows 7.5+
  • Mobile Firefox
  • Opera Mobile

The Basics, Plain JavaSript Way

Let’s start looking how the most basic and often needed functionalities work in plain JavaScript, compared to jQuery. For each example, I’m going to provide both the jQuery and plain JavaScript approach.

Document Ready

With jQuery, many of you are probably used to using document.ready like so:

$(document).ready(function() {
  // Code
});

But did you know that you can just put all of your JavaScript at the bottom of your page and that does basically the same thing? JavaScript has also an event listener for the DOM content loaded event which you can use instead of jQuery’s document.ready:

document.addEventListener("DOMContentLoaded", function() {
  // Code
}, false);

Selectors API

JavaScript’s native selectors API is very good. It works with CSS selectors and is very similar to what jQuery provides. If you are used to writing this in jQuery:

var element = $("div");

You can now replace that with:

var element = document.querySelector("div");

Or, to select all div’s inside some container:

var elements = document.querySelectorAll(".container div");

You can also query against a specific element to find it’s children:

var navigation = document.querySelector("nav");
var links = navigation.querySelectorAll("a");

Quite straightforward, easy to understand, and doesn’t really require much more writing now does it? To go a little further, we could even build a tiny JavaScript library for ourselves for simple DOM querying. Here’s something that Andrew Lunny has came up with:

// This gives us simple dollar function and event binding
var $ = document.querySelectorAll.bind(document);
Element.prototype.on = Element.prototype.addEventListener;

// This is how you use it
$(".element")[0].on("touchstart", handleTouch, false);

Traversing the DOM

Traversing the DOM with plain JavaScript is a bit harder than it is with jQuery. But not too hard. Here are some simple examples:

// Getting the parent node
var parent = document.querySelector("div").parentNode;

// Getting the next node
var next = document.querySelector("div").nextSibling;

// Getting the previous node
var next = document.querySelector("div").previousSibling;

// Getting the first child element
var child = document.querySelector("div").children[0];

// Getting the last child
var last = document.querySelector("div").lastElementChild;

Adding and Removing Classes

With jQuery, adding, removing and checking if an element has certain classes is really simple. It’s a bit more complex with plain JavaScript, but not too much so. Giving element a class called "foo" and replacing all the current classes:

// Select an element
var element = document.querySelector(".some-class");

// Give class "foo" to the element
element.className = "foo";

Adding a class without replacing the current classes:

element.className += " foo";

Removing "no-js" class from html-element and replacing it with "js":

<html class="no-js">
<head>
  <script>
    document.documentElement.className = "js";
  </script>
……

That was quite straightforward, right? Next step, removing only certain classes, is a bit more complex. I’ve been using this small helper function in a separate partial called util.js. It takes 2 parameters: element and the class you want to remove:

// removeClass, takes two params: element and classname
function removeClass(el, cls) {
  var reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
  el.className = el.className.replace(reg, " ").replace(/(^\s*)|(\s*$)/g,"");
}

Then, in the main application partial, I’ve been using it like so:

removeClass(element, "foo");

If you also want to check an element against some class, kind of like jQuery’s hasClass works, you could add this in your utils:

// hasClass, takes two params: element and classname
function hasClass(el, cls) {
  return el.className && new RegExp("(\\s|^)" + cls + "(\\s|$)").test(el.className);
}

…and use it like so:

// Check if an element has class "foo"
if (hasClass(element, "foo")) {

  // Show an alert message if it does
  alert("Element has the class!");
}

Introducing HTML5 classList API

If you only need to support more modern browsers like IE10+, Chrome, Firefox, Opera and Safari, you could also start using HTML5’s classList functionality which makes adding and removing classes even easier.

This is something, that I ended up doing with our latest Developer Docs, as the functionality I was developing, was more like an enhancement to the UI and not really something that would break the experience if it wasn’t present.

You can feature detect if the browser supports it by using this simple "if" statement:

if ("classList" in document.documentElement) {
  // classList is supported, now do something with it
}

Adding, removing and toggling classes with classList:

// Adding a class
element.classList.add("bar");

// Removing a class
element.classList.remove("foo");

// Checking if has a class
element.classList.contains("foo");

// Toggle a class
element.classList.toggle("active");

One other benefit of using classList is that it will perform much better than using the raw className property. If you had an element like this:

<div id="test" class="one two three"></div>

Which you’d want to manipulate:

var element = document.querySelector("#test");
addClass(element, "two");
removeClass(element, "four");

For each of these methods the className property would be read from and then written to, triggering a browser repaint. However, this is not the case if we use the relevant classList methods instead:

var element = document.querySelector("#test");
element.classList.add("two");
element.classList.remove("four");

With classList the underlying className is only altered when necessary. Given that we are adding a class that is already present and removing a class that isn’t, the className is never touched, meaning we’ve just avoided two repaints!

Event Listeners

Adding and removing event listeners from elements is almost as simple in plain JavaScript as it’s in jQuery. Things get a bit more complex when you have to add multiple event listeners, but I’ll explain that in a bit. The simplest example, which will just pop out an alert message when an element is clicked, is as follows:

element.addEventListener("click", function() {
  alert("You clicked");
}, false);

To achieve this same functionality on all of the elements on a given page, we have to loop through each element, and give them all eventListeners:

// Select all links
var links = document.querySelectorAll("a");

// For each link element
[].forEach.call(links, function(el) {

  // Add event listener
  el.addEventListener("click", function(event) {
    event.preventDefault();
    alert("You clicked");
  }, false);

});

One of JavaScript’s greatest features related to event listeners is the fact that "addEventListener" can take an object as a second argument that will automatically look for a method called "handleEvent" and call it. Ryan Seddon has covered this technique thoroughly in his article, so I’m just gonna give a fast example and you can read more about it from his blog:

var object = {
  init: function() {
    button.addEventListener("click", this, false);
    button.addEventListener("touchstart", this, false);
  },
  handleEvent: function(e) {
    switch(e.type) {
      case "click":
        this.action();
        break;
      case "touchstart":
        this.action();
        break;
    }
  },
  action: function() {
    alert("Clicked or touched!");
  }
};

// Init
object.init();

Manipulating the DOM

Manipulating the DOM with plain JavaScript might sound like a horrible idea at first, but it really isn’t much more complex that using jQuery. Below, we have an example that selects an element from the DOM, clones it, manipulates the clone’s styles with JavaScript and then replaces the original element with the manipulated one.

// Select an element
var element = document.querySelector(".class");

// Clone it
var clone = element.cloneNode(true);

// Do some manipulation off the DOM
clone.style.background = "#000";

// Replaces the original element with the new cloned one
element.parentNode.replaceChild(clone, element);

If you don’t want to replace anything in the DOM, but instead append the newly created div inside the <body>, you could do it like this:

document.body.appendChild(clone);

If you feel like you’d want to read even more about different DOM methods, I’d suggest you to head over to Peter-Paul Koch’s DOM Core tables.

Diving Deeper

I’m going to share two bit more advanced techniques here, which I’ve recently discovered. These are both functionalities we have needed while building Adtile, so you might find these useful too.

Determining Max-Width of Responsive Images in JS

This is one of my own favorites, and it’s very useful if you ever need to manipulate fluid images with JavaScript. As browsers return the current resized dimensions of an image by default, we have to come up with some other solution. Luckily, modern browsers now have a way of doing this:

var maxWidth = img.naturalWidth;

This will give us image’s max-width: 100% value in pixels and it’s supported in IE9, Chrome, Firefox, Safari and Opera. We can also take this further and add support for older browsers by loading the image into an in-memory object:

// Get image's max-width:100%; in pixels
function getMaxWidth(img) {
  var maxWidth;

  // Check if naturalWidth is supported
  if (img.naturalWidth !== undefined) {
    maxWidth = img.naturalWidth;

  // Not supported, use in-memory solution as fallback
  } else {
    var image = new Image();
    image.src = img.src;
    maxWidth = image.width;
  }

  // Return the max-width
  return maxWidth;
}

You should note that the images must be fully loaded before checking for the width. This is what we’ve been using to make sure they have dimensions:

function hasDimensions(img) {
  return !!((img.complete && typeof img.naturalWidth !== "undefined") || img.width);
}

Determining if an Element is in the Viewport

You can get the position of any element on the page using getBoundingClientRect method. Below is a simple function showing how simple and powerful it can be. This function takes one parameter, which is the element you want to check. It will return true when the element is visible:

// Determine if an element is in the visible viewport
function isInViewport(element) {
  var rect = element.getBoundingClientRect();
  var html = document.documentElement;
  return (
    rect.top >= 0 &&
    rect.left >= 0 &&
    rect.bottom <= (window.innerHeight || html.clientHeight) &&
    rect.right <= (window.innerWidth || html.clientWidth)
  );
}

The above function could be used by adding a “scroll” event listener to the window and then calling isInViewport().

Conclusion

Whether or not you should use jQuery in your next project depends a lot on what you are building. If it’s something that requires large amounts of front-end code, you should probably use it. However, if you’re building a JavaScript plugin or a library, you might want to consider sticking with just plain JavaScript. Using plain JavaScript means fewer requests and less data to load. It also means that you aren’t forcing developers to add jQuery to their project just because of that dependency.

Can Mobile Ads Be Done Right?

Adtile Technologies
Adtile Technologies wrote this on

There’s an article about us on Arctic Startup, written by Dmitri Sarle:

The best part of this experience was that I was told nothing about how Adtile ads work. Yet, I found and clicked the ad all on my own. It felt natural and I was interested. My complete and utter banner blindness did not filter it out.

This is when I remembered Forsbloms words from the interview: “It is a seamless extension of the application. The ad does not feel like an ad anymore” and I found myself surprised to experience exactly that.

Read the full article →

Adtile Device Lab

Adtile Technologies
Adtile Technologies wrote this on

The web doesn’t live on a desk anymore and we now need to test our work on multiple devices, instead of just few desktop browsers. This is especially true for us at Adtile, since we’re developing a mobile first advertising solution and need to make sure that our JavaScript SDK works flawlessly on as many devices as possible.

That’s why we’ve decided to start hosting the Helsinki Device Lab in addition to our own device lab here in Helsinki. There are currently 63 various devices in our collection, and the number is growing rapidly as our work continues.

Here’s an overview of what the lab looks like at the moment:

Adtile Device Lab

Adtile Device Lab

There’s still work to do regarding the lab, but this is a good start. It also seems that we need to build yet another wooden stand for even more devices(!)

BTW, did you already spot the Gameboy? ;)

Building High Throughput APIs with Ruby—Part 1

Adtile Technologies
Adtile Technologies wrote this on

Welcome to a series of blog posts on building high throughput APIs in Ruby. These are all based on lessons learned while building Adtile and, more specifically, the ad serving component of it.

Ad servers need to be fast. Really fast. So fast that users don’t notice something external is loading. Response times need to be low, even when handling thousands of ad requests and event tracking operations every second. It’s a beautiful mix of fast responses and well designed SDKs to provide a seamless loading experience. For now, we’ll focus on what we do to get our responses out as fast as possible.

Why Ruby?

We know there are many languages out there with better raw performance. We use Ruby because that’s what we like and are good at. As simple as that. It lets us experiment and adapt quickly.

Don’t just build things in a language because it runs fast. Do it in a language where you can build things fast instead. Create small components that work together to create a larger system. That way you’ll be able to replace the slow parts later, if really needed. Raw performance only takes you so far, while a good architecture will take you much further.

Our stack

Our ad server is a Rails::API application that reads and writes to PostgreSQL, Redis, DynamoDB and Memcached. We use Sidekiq Pro for background processing.

This specific part of Adtile runs on JRuby instead MRI. JRuby has allowed us to squeeze a lot of performance out of single instances since we can run code truly concurrently and have the JVM optimize our code as it runs.

Finding bottlenecks

During the initial phases of development, we tried not to focus too much on performance while we played around with different ideas. On the other hand, we also tried to make good decisions that wouldn’t lead to a slow application. When we were finally done with our features we finally took a good look at performance.

Our code wasn’t particularly slow, but it also wasn’t as fast as I had hoped. To get a feeling of how things would work in production, we launched enough instances and did some load testing. We’ve been using Loader.io and have been happy with it. Benchmarking your application locally can only tell you so much. In production you’re going to be dealing with load balancers, databases running on separate machines and the latency that comes with it. If you’re not doing any load testing against your staging or production environment, you definitely should. You may be surprised.

Simply throwing a lot of traffic at our application gave us a pretty good idea of what needed improvement right away. When our application couldn’t handle it anymore and started throwing exceptions instead of successful responses, it became clear from looking at the logs what our problems were.

Even with a big enough connection pool size for our databases, we were still seeing timeouts waiting for connections. It’s not because any of our databases are slow, but mostly due to other factors such as connection limits, and perhaps even more important, latency.

For example, in our AWS region, the latency between availability zones is around 2ms. It doesn’t seem like much, but if you’re doing multiple operations that are dependent on each other, you’ll be multiplying that latency a few times and it does add up pretty quickly.

Going easy on the database

One of the biggest improvements we saw was when we managed to cut writing to the database on every request. We still need all that data from each request, but we realized we were doing very simple operations, such as incrementing values, so we came up with a way to do those less often. Even simple ideas like this will go a big way in massively improving overall system performance. And not only that, but you’ll also be saving money. We’ve all heard that hitting the database is expensive, and with for example with DynamoDB that can be said literally, as you pay based on provisioned database throughput.

We built a small Ruby library to do just this, which you can find on GitHub. It lets you define aggregator tasks that run on a separate thread as often as you want them to run.

An example aggregator that would keep track of pageviews could look something like:

class PageviewAggregator < Aggregator
  def process(collection, item)
    collection ||= {}
    collection[item] = collection.fetch(item, 0) + 1
    collection
  end

  def finish(collection)
    # Update the database based on your aggregated data:
    # { "/" => 471, "/about" => 127, ... }
  end
end

Then, instead of doing database calls for every single page you serve, you could simply push an item to the aggregator:

PageviewAggregator.push(request.path)

You can find full instructions on how to use it on the project README.

Since we use JRuby, it means that aggregations can run at the same time we serve requests. However, even if we were running on MRI, we’d still benefit from it.

If you’re gathering analytics data, good chances are you can combine multiple writes into either a single one or less. And all that while still saving data often enough so that you can present users with up-to-date information.

Coming up next…

This post is just an introduction to our stack and a solution to a bottleneck we found. In future posts we’ll go through things such as gotchas in Rails, tuning for performance, improving Rails caching performance with Memcached, abusing Redis scripting for fun and profit and many other things. Stay tuned!

Proper Link Handling With PushState

Adtile Technologies
Adtile Technologies wrote this on

Have you ever come across some web application that uses pushState and doesn’t let you use Cmd + Click to open links in new tabs? I know I have. More worrying is that sometimes these so called links are just div elements, not <a> elements at all. Let’s fix this problem.

We can start with a very simple link:

<a href="/profile">Profile</a>

The value of the href attribute on all internal links is going to start with a slash, so we can react to those. The important thing is that we stay out of the way if any modifier key is being pressed. We can achieve our desired behavior with the following code (using jQuery):

$(document).on("click", "a[href^='/']", function(e) {
  if (!e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey) {

    e.preventDefault();
    // Trigger the route change

  }
});

Now users can expect your application to work just like any other website. Pressing a modifier key while clicking the link will let the browser handle the link without any JavaScript interference. As an added bonus you can even deal with other things here in addition to the route change, such as notifying your web analytics service of a new page view.

Here is the above example with actual route changing (using Backbone.js):

$(document).on("click", "a[href^='/']", function(e) {
  if (!e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey) {

    e.preventDefault();
    var url = $(e.currentTarget).attr("href").replace(/^\//, "");
    app.navigate(url, { trigger: true });

  }
});

Pretty straightforward: We grab the URL from the <a> element, remove the leading slash, and call navigate on our instance of Backbone.Router (here named “app”). The “trigger” option will make it call the route function for the URL we are navigating to.

Update: No longer using rel="internal" on the links, which was my original suggestion. Thanks Alan Hogan for pointing out why it was a bad idea, and Ben Cherry for suggesting a better solution.