Christian Heilmann

You are currently browsing the Christian Heilmann blog archives for October, 2013.

Archive for October, 2013

Perpetuating terrible JavaScript practices

Thursday, October 31st, 2013

I just went to the Samsung Developer Conference in San Francisco and one thing in the goodie-bag was a book (paper, no less) on building apps for the amazing new Smart TVs they are bringing out. Exciting stuff, especially as the platform is HTML5 and JavaScript driven. When opening the book randomly though I found the following code:

Click for bigger

<div id="left">
  <a href="javascript:void(0);" id="left_anchor" 
     onkeydown="left.keyDown();">left</a>
</div>
<div id="right">
  <a href="javascript:void(0);" id="right_anchor" 
     onkeydown="right.keyDown();">right</a>
</div>

// left anchor event handling function
left.keyDown = function () 
{ 
  var keyCode = event.keyCode;
  switch (keyCode) 
  {
    case tvKey.KEY_RIGHT:
      jQuery('#right_anchor').focus();
      jQuery('#right').addClass('focus');
      jQuery('#left').removeClass('focus');
      break;
    default:
      break;
  }
};

I do understand that a SmartTV is a defined environment and there might be things that work better when you do things in a certain way, but I am really hard pressed to see any reason why anyone in 2013 would write JavaScript and HTML like that unless what happened is that we keep copying old code without thinking of the impact it has.

There is a huge movement of teaching people to code. Great startups like Codecademy, Codecombat, Codewars and many, many more use the web to teach people how to build things for the web, how to grasp the concepts and logic of code and how to write it. On the other side of the coin we have implementation guides that ride roughshod over everything we learned in all the recent years we used web technologies for the sake of writing a very “easy to understand” hello world example or “keep the code short”. This is not helping, all it does is perpetuate the prejudice that the web is not a professional environment to work in and instead it is OK just to copy and paste something and change some function names as long as the browser understands it.

We got into a world of copying and pasting solutions that work without caring at all about the effects they might have. This is unfortunate, seeing how JavaScript has become a first class language, or as Shinetech put it in their excellent “Respect the JavaScript” post:

It is the only runtime language I can think of that will run on any modern processing device. It’s ubiquitous and the ecosystem has evolved beyond what anyone could have imagined, with many implementations (Rhino, V8, now Nashorn) and it’s very own matching server-side equal, node.js

So, what is so terrible about this code? Chris, why are you such an arrogant bastard in your web standards ivory tower punishing people who just want to write code and release products quickly?

Call me old fashioned, but I don’t like waste. I also don’t like when people use things without understanding the consequences. Our goal should not be “it renders, therefore it must be right”, instead it should be “this is clean, extensible and it uses various technologies benefiting of their different strengths”.

Use the wrong element, then make it work?

So what’s wrong here? The first glaring, utterly useless and bloated mistake that does not seem to want to die is links with a href attribute of javascript:void(0) (I lamented about this in 2005 in Six JavaScript features we do not need any longer).

A link is there to point to a resource. That’s what we defined them for. If you don’t point to a resource – don’t use a link. Much like you don’t use an H1 when you want to define an INPUT, although modern JavaScript and CSS are perfectly capable of making one act like the other. It does not make sense though, which is why you don’t do it. So why use links with href attributes that are long and – by definition – don’t do anything?

If you want something that is focusable, can start a script when the user interacts with it and is both keyboard and mouse accessible, use a BUTTON element. This is what they are for.

Add an ID, then you can access it easily?

The next problem is the use of IDs on the parent element and on each button. It is simple to define a button with an ID and make it styleable and accessible either with getElementById() or querySelector() but it also means that this is a unique thing in the whole document. What if you want more than one button that enables navigation to the right? You need to add a different ID and check for that one in the code. This is wasteful and limits the extensibility of your interface.

Using IDs is simple, but it means that you create a unique element with unique functionality – are you sure you won’t need to repeat the same element at a later stage?

Everybody in line

The next massive issue is the inline event handler on every single element. This seems to be special to the SmartTV platform – the API emits a key event that tells you what key was pressed on the remote control. In essence, all you would need to do is to assign one key event handler to the whole document instead of lots of inline handlers to every single control. This is not only wasteful and mixes HTML and JavaScript (remember, we do work in a pure JavaScript environment here), it also means that you are very likely to repeat the same code over and over again for each control rather than writing a single handleKeys() function that can be activated by various controls depending on what view of your application you are.

If you use an inline event handler on an HTML element you make debugging harder, you make it much harder to refactor code (as function names need to change in your JS and in each HTML documents) and you are very likely to write code that repeats the same functionality in different listeners.

This actually happens in this example as on the next page the right.keyDown method is a copy of left.keyDown with the only difference being the shifting of focus and class names.

Goldfish code

The next bit that is worrying here are all the jQuery calls to get references to elements to set the focus and to remove and add classes to. First of all, hey, we have a jQuery dependency here, why didn’t the rest of the code use jQuery for the event handling? Secondly, why all the repetition? Every time you access the DOM you slow down your app. We know these elements, we gave them IDs to ensure that we know them. That’s why asking jQuery to find them again for us every single time an event is dispatched means your code has the memory capacity of a goldfish (and uses a lot more memory). If you can, always cache elements in variables to avoid yet another DOM lookup. Simple caching like this goes a long way:

/* Navigation buttons */
 
var navright = document.querySelector('#right');
var navleft = document.querySelector('#left');
var navup = document.querySelector('#up');
var navdown = document.querySelector('#down');
 
// from now on use navright, navleft, navup, navdown
// this also means you can rename the IDs later without
// having to hunt all your code for them!

Unnecessary shifting of classes

The last obvious issue here is the shifting of classes from the left to the right. The problem with this is that if you were to add more buttons you’d have to add them to the method as you right now do not know which one was activated. This means you need to either add a “remove class from x” line for each button or write a loop over all buttons removing the class before setting it to the current one. This is a very common and simple to rectify mistake.

First of all, there is no need to set a class to an element if you want to highlight it when it is focused. Setting an active and focus style in CSS is enough (as shown here).

button {
    display: block;
}
button:active {
    background: green;
}
button:focus {
    background: green;
}

But even if you need to set a class to the currently focused element, there is no need to loop through all the others at all. Again, the trick is storing the current element in a variable and remove the class from that cached element:

var current = null;
document.body.addEventListener('click', function(ev) {
    if (ev.target.tagName === 'BUTTON') {
        if (current) {
            current.classList.remove('focus');
        }
        current = ev.target;
        current.classList.add('focus');
    }
}, false);

The code as it stands here does a different thing, agreed, but the solution is still clunky. Instead of repeating the same functionality in each handler, the better way to write this would be a setfocus() function that takes the new element to focus on as a parameter and removes the class and the focus from the current one.

To conclude

All in all, I am really disappointed to see code like this in a brand new book about bleeding edge technology using JavaScript. This is not by design, this is plain and simple laziness and bad editing. JavaScript has become incredibly powerful and is used in a lot of cases for business critical functionality. In a closed environment like a SmartTV there is nothing at all wrong about that. What is wrong though is educating new developers to write code that was maybe needed to support IE4 or Netscape2 and even back then was the lazy and hard to maintain way of doing it. If you write some instructions or tutorials, please, for the sake of the quality of the next generation of developers:

  • Don’t use any inline handlers or javascript: pseudo protocol URLs. You know they are a terrible hack – if you don’t then generate your HTML in JavaScript and keep it cleaner that way.
  • Limit DOM interaction to the barest minimum – it slows down your App
  • Don’t loop when you can store – if you need to shift a focus around this means you need to know the last “active” element and the next one to focus. There is no need to loop over all elements in a group.
  • Extensibility is key – if your script is limited to a defined number of elements and repeats them in event handlers, you cause terrible maintenance code.

Of flying cars and the greater good – my Firefox OS talk at 360i

Friday, October 25th, 2013

Yesterday I visited the lovely people at 360i for the first edition of their inspired speaker series talking about Firefox OS, the greater good of the internet and how HTML5 got pushed by the need to build an operating system with it.

As always, I’ve recorded a screencast of the presentation and you can watch it on YouTube

The slide deck is available online, but doesn’t offer much that the video doesn’t. Here are the resources I covered:

I had good fun explaining our ideas and seeing what a bleeding edge design agency’s issues with new technology are. A very insightful evening.

The shiny silver elephant in the room

Thursday, October 17th, 2013

I am typing this on my Macbook Air. A very pragmatic and great machine for me to use. 13 inch, really small and light to use on the plane, 8 GB of RAM, 250 GB solid state drive which makes video editing a snap; the works. I’ve been using a Mac for about 5 years now and I moved away from Windows because I was sick of having to use a larger part of my processor for virus scanning. Once switched to Mac using Windows also seems unwieldy and I would really miss my Terminal with Unix emulation.

'Simply Silver', Green Park

I am not alone in this – at most conferences all you see is MacBooks in various forms and ages. When I started as a web developer this was different. Thinkpads with Windows were the big thing and Macs were too expensive and just not right to use.

Now, as someone working for an open source company it seems to be hypocrisy to use a system that is not open source, and believe me, I had my share of people telling me that it is just that. I run Linux on my servers, I had a Linux laptop, but I just did not get warm with it. Many things like watching movies and playing songs were too much of a hassle because of codecs not being open, I missed Photoshop, and I just didn’t find an editor I liked (that was some time ago).

The fact is that I am happy with the system, it makes me most effective in what I do and everything works and is beautiful. Apple is great at that. It makes sure things work when you stay in the world you have chosen to use. We give up things we thought mandatory (like replacing a battery) for convenience. We don’t screw new hardware in or change the configuration, in many cases this is not even possible.

And all of that is a problem.

Web developers in the Western world are not people using the web. We are much more of a technological elite than we want to admit. Whilst we discuss the merits of high retina displays and how to support them the average world-wide web surfer sits out there with a Windows box or a Linux machine or uses a hotel computer or something slightly resembling a computer in an internet cafe.

Other people only surf at work, on the windows box ghosted by their IT department with no discussion as to what goes on it as every piece of non-IT-certified software might be a virus.

We never suffer their pain, we just don’t know any longer. Using Windows to me now feels weird and I don’t enjoy it. I like my command line, I don’t want to click through layers and layers of menus and find checkboxes to activate.

But this is not who we work for. On the desktop a huge amount of people use Windows and will use Windows for quite some time to come. Does this mean we have to optimise things for Windows, and even older Windows with terrible versions of IE? No, cause this brought us the dark ages of the browser wars with “site only works in IE” solutions that drive us nuts right now. On the other hand it means though that we should not make the mistake to assume that everything works in IE and Windows just because it works in Chrome or Firefox on a Mac.

The biggest irony is that as web developers we’ve been complaining about Microsoft and its lack of standards support for our whole life, and now that Microsoft does support standards we optimise for prefixed and beta functionality in other, Mac browsers instead. It is the same mistake developers did supporting all the cool things IE6 promised to standardise or we told ourselves are “de facto standards” as “everybody has a Windows PC with IE6” back then.

I think we have to face the fact that IE will not go away, and that having a VM running on your Mac and testing in IE is a damn good test to see how your work will perform outside, where the users are. Yes, this is frustrating, yes, it is annoying and means having a VM on your computer and give up quite some space of your HD for virtual images that need to be re-created every 90 days but it is worth it. And Microsoft is dedicated to make it easy for people, as shown in their Modern.ie site with all the info and downloads you need. Of course, having IE on Mac and Linux would be the best solution, but IE being part of Windows’ core, this will never happen.

If we care about standards and about cross-platform support we should make sure our stuff works in IE - it does not have to be the same as in all other browsers, but it needs to work. I see far too many solutions actively blocking IE to ensure there is no testing needed. That is exactly what those sites that state “only works in a modern browser like IE6” did. I think we’ve moved on from this.

Our job is to create enticing and beautiful products for the people of the web. Just because we have access to power tools doesn’t mean we should concentrate on what they provide. Let’s lower our expectations on what is out there and concentrate on making things work. A lot of what we consider amazing right now might never be of any interest for our end users and should happen under the hood instead of being a “you need this to see what I did”.

Start spreading the news… I’m coming to New York, New York

Wednesday, October 16th, 2013

Tomorrow I am flying to NYC for a week to squat in Queens and as I felt bad about not having a speaking date during that time I asked on Twitter and, lo and behold, was asked to give two quick tech talks next week.

Ziegfeld

On Tuesday I will be speaking in detail about FirefoxOS at the Flatiron Tech Talk Lunch Series by Reflexionsdata. I will concentrate not necessarily on building apps for the marketplace but on how to re-use existing web content and make it installable and findable with the app search of FirefoxOS.

The 2nd talk will be on Thursday, the 24th of October at 360i at 32 Avenue of the Americas, 6th Fl NY, NY 10013 in TriBeCa. You can sign up for this one at 360i’s Meetup page or the 360i’s Eventbrite page.

I will be speaking about “HTML5 Beyond the Hype: Current Issues & Near-Future Solutions”:

HTML5 has been sold to us as the new Flash and somehow fell behind in delivering that promise. The main issue is that the platforms that hyped HTML5 failed to cater to its needs. In this short presentation, Christian Heilmann of Mozilla shows what HTML5 can do in a more dedicated environment and how Mozilla pushes the standards with FirefoxOS. Learn how to worry less and deliver more for the next generation of users and browsers which are just around the corner

After this, I am off to San Francisco for the Samsung Developer Conference. See you there.

The passion accessibility presentations need

Monday, October 14th, 2013

I am lucky that in my job I manage to come across amazing people all the time. In some cases it takes a while for them to come out of their shell and show what they can do. One of those is my friend Luz Rello (luzrello.com) from Barcelona. Here she is next to me with my friends Javier Usobiaga and Marta Armada when we met in Barcelona (and she asked me a few things about presenting on stage, which I happily shared):

Luz, Javier, Marta and Chris

Why is Luz amazing? Well, many things. For starters, she is an accessibility researcher with dyslexia. And she just delivered an amazing talk about “New solutions for dyslexia” at TEDxMadrid:

Now, I don’t speak Spanish, but seeing how Luz delivers a talk full of passion, movement and speed makes me not doubt at all that this will be soon translated in subtitles by TED and accessibility enthusiasts. And this makes me happy and this makes me hopeful for accessibility to get out of its niche in technology, education and digital literacy and become what it should be: a litmus test for content. If what you publish is easy to understand, structured and clear you will reach many, many people. In far too many cases what the final product looks like dictates how it is built, and that needs to change.

This is the kind of passion I want to see from accessibility advocates, these are the voices we need. Not another library to add ARIA to badly thought-out HTML, not another course that teaches web accessibility as pleasing screenreaders or text-to-voice tools. We need people who stand up and be passionate and bring information that matters and is up-to-date. Not guidelines from long ago that forgot that technology moves on. People like Luz, and people like you, if you are up for the challenge.

I have no doubt at all that Luz will move a lot in this space, and guess what? She does like to move it (from her Madagascar trip).