Candles, Programming and Archetypes

May 22 2018

Once in a while, I daydream about being thrown back in time. I’d have no Wikipedia, no books, or any access to information except what’s already in my head.

If I were thrown into Victorian London, what could I do? What could I teach them?

Well, the first thing I would do is tell them to wash their hands. With soap. Frequently. That would probably be the most significant contribution I could make.

Beyond that, I’m a computer programmer. I like to think I know my way around a web browser pretty well, but that’s pretty useless knowledge in a world without computers.

It can be a fun exercise to start with something you know, say, TypeScript, and work your way backwards as far as you can:

  • TypeScript is a high level languge and is transpiled into Javascript

  • Javascript is a language that is interpreted by a Web Browser

  • A Web Browser is a native program, probably written in C++

  • C++ is a programming language, which is compiled into machine language

  • The machine language is run and prioritized by an operating system

  • The operating system passes streams of machine language to the CPU

  • The CPU runs the streams out of order, interfacing with other devices on the computer

  • The computer is a collection of standardized components, powered by electricity

  • Electricity is… etc (gotta stop somewhere!)

I wrote the above steps off the top of my head, and I’m fully aware there are huge gaps in my knowledge, and probably many inaccuracies in the way I’ve written it out. This is normal in our specialized modern world. There will always be far more things at play than you’ll ever have time to understand.

Having said that, there is no reason you can’t spend some time looking back and trying to fill in your own personal gaps. I’ve become a huge fan of The 8-Bit Guy on Youtube for this kind of thing. Here’s one of his best videos, about how graphics worked on “oldschool” systems:

Over the last year or so I’ve made it somewhat of a hobby of mine to find old computer manuals and briefly tour their programming guides.

You hear a lot about the challenges of programming old systems. It’s true that they had limited memory and processing power, and programs also loaded slowly from disk. But there’s also a simplicity to them that is beautiful.

A professor of mine once said something interesting about Archetypes (paraphrased):

A candle is an archetype of the light bulb. You use it to create darkness, not light.

On an old computer such as a Commodore 64, there’s nothing preventing you from accessing any piece of memory or IO device.

Booting a Commodore 64 (which you can now do in a browser!) will present you with something like this:

This is BASIC, an early high level programming language. But its simplicity doesn’t mean it can’t access the computer directly! If you type in POKE 53280, 2, that will write the value 2 into the Commodore 64’s memory at address 53280, which happens to be the video memory that determines the border color of the screen:

To a modern programmer, this should be alarming. What’s to stop a bad program from reading memory it shouldn’t, or accessing devices it shouldn’t?

Candles are literally open flame. I remember during the Northeast Blackout of 2003 the mayor coming on the radio and asking people not to use candles out of fear of starting fires all over the city.

Used responsibly, though, a candle creates a beautiful darkness. I recently toured Denis Severs' House in London. It’s a visceral arrangement of life in London through the centuries, and it’s almost entirely candlelit, which allows it to alternate between warmth and spookiness.

I probably wouldn’t object if someone told me learning to program a Commodore 64 in 2018 is a nerdy pursuit. I would object if they said it’s useless though; Programming is all about trade offs, and our predecessors made some excellent ones given the technolgical constraints of the time.

If you have the time and the interest, I’d highly recommend spending some time learning about how obsolete computers worked. I can’t promise it’ll make you a better programmer, but it will give you a better perspective, and that’s something I think all of us could use these days.

View the full article to comment on it

The value of a thousand little features

Apr 13 2017

It’s been over a year since I wrote a blog entry! And while of course the universal excuse of “I’ve been busy” applies, I think we reached a point in Discourse’s development where we just were able to focus on the product without a lot of stuff getting in our way.

I’ve now been working on Discourse full time for 5 years. In the beginning we had a lot more uncertainty about technical decisions. Some of the things we debated interally include:

  • Whether to use Rails or Node.js (We chose Rails)
  • Whether to use an ORM or direct SQL (We use ActiveRecord)
  • Whether we could get away with a NOSQL database instead of Postgres
  • Whether to do server side rendering or embrace a front end MVC framework (We use Ember.js)
  • Whether to use CoffeeScript/Javascript (Javascript won, now ES2015)


Beyond those major discussions, we also went back and forth a lot about the details of our codebase:

  • How much test coverage is enough?
  • How and when do we introduce internationalization?
  • How should the code base look (how much space, when to add new lines, etc)
  • How do we handle code reviews from within our team?


If you’re reading this as a developer, I’ll bet some of the above bullet points triggered some immediate opinions :)

The truth is that over time our team found its mojo. Issues we had with our major decisions eventually found workarounds or solutions. Members of our team whose priorities were different (performance focused vs code quality for example) eventually found a happy ground and we just became productive.

We also saw some excellent performance gains in Ember.js and V8, and both of those teams deserve some serious credit. Android performance still isn’t where I’d like it to be, but it’s improved significantly since the project began.

To be clear: we aren’t done changing our codebase. For example there’s interest in moving to TypeScript, and we are pretty tired with Sprockets so we’ll be ditching that, plus we want to upgrade Ruby and Rails versions. Web technology continues to advance and we’re along for the ride!

A thousand little features

Once in a while, someone will ask me (in a polite way) something like “hey, after 5 years, what is left to do for forum software?”

From a 10,000ft view, it seems that Discourse already does what you’d expect forum software to do. We let users log in, read content and post replies. So what the heck is our team still working on?!?

There is a tendency in software engineering to oversimplify products you’re not familiar with. I remember reading a Hacker News article about Disourse a few years ago where someone posted something to the effect of:

Why is the Discourse codebase so big? Aren’t they just taking text and showing it on a web page?

Well, yes. But isn’t every web application ultimately just taking text and showing it on a web page? If it were that simple I think we would have packed it up a long time ago.

If you zoomed in closer on Discourse, say to the 5000ft view, you’d see that we have many big features we had to implement but might not seem obvious at first including: Sub-categories, User Groups, Theming, Moderator Tools, a Setup Wizard, etc). I think a lot of experienced developers would recognize that you’d need all that stuff as your product gets used by more people.

The thing that has been a great learning experience for me though, is the thousands of little features that most people don’t see.

When a user posts on Discourse, they’re presented with what is essentially a HTML <textarea>. They fill it in, hit post and their content shows up in the topic.

What is not obvious, unless you’ve actively used the software is how many little features are layered on top of that to encourage what we think is good discussion.

For example (and this is nowhere near an exhaustive list):

  • If your reply is too short, we’ll encourage you to say more. Short replies offer little value.
  • If your post links to something recently mentioned, we’ll say “Hey that was already posted x replies above you.”
  • If your new topic is similar to one that already exists, we link to it and tell you to check it out first before perhaps creating a duplicate.
  • If you start dominating the topic by replying too much, we ask you to slow down and give other people a chance to participate.
  • If you are only replying to the same person over and over, we suggest that you might be derailing the topic and perhaps should take it elsewhere like a private message.


Those thousands of little features really add up over a while. We’ve added them because we use Discourse every day and have seen patterns of usage in our own forums and the forums of our customers that we think we can improve.

Of course, a truly toxic user will find a way to be toxic regardless of how many times to discourage their bad behavior, but the vast majority of users are not toxic and will happily follow hints that lead them towards a better discussion. Many of our users will never see this work, but the ones who do will hopefully be pointed in the right direction.

I love that we can add these little things quicky to our codebase, and because we’re a web application we can deploy them to users right away to see their effects and tweak them over time. It has really changed a lot of my thinking of software development, where there traditionally seems to be a huge focus on BIG features to create value.

Maybe instead of spending months creating a big feature, spend a day or two knocking out a small one? Those little ones really add up, and can add up to make a big difference before you know it!

View the full article to comment on it

We finally did something about Android Performance

Feb 25 2016

Back in September, Codinghorror wrote a popular post on the state of android Javascript performance on Discourse’s Meta forum. It drew a lot of attention, and led to some fascinating discussions on our forum and behind the scenes with browser engineers.

The poor performance of Discourse on Android was already old news to us at that point: we started paying attention several years ago, and have spent some time contributing to the Ember.js community tools to help profile application performance, in particular the “Render Performance” tab on the Ember Inspector, and the ember performance suite.

Over time, we’ve seen some modest performance improvements in newer Ember.js releases. In particular, the HTMLBars upgrade resulted in a roughly 25% boost. However, rendering topics was still approximately 6 times slower on the top of the line Android device versus the equivalent iPhone.

After years of waiting for a breakthrough in Android or Ember performance, we decided it was time to to take the nuclear option: we replaced the Ember rendering engine for our most common view with a custom virtual DOM based renderer.

The results have been fantastic:

Large Topic Rendering Speed (Initial Visit)

  • Desktop

    • 633ms avg (before)
    • 120ms avg (after)
  • Nexus 6p (high-end Android)

    • 1248ms avg (before)
    • 248ms avg (after)
  • Nexus 7 (2013 mid-range Android)

    • 4078ms avg (before)
    • 636ms avg (after)

Large Topic Rendering Speed (Subsequent Visits)

  • Desktop

    • 429ms avg (before)
    • 69ms avg (after)
  • Nexus 6p (high-end Android)

    • 710ms avg (before)
    • 152ms avg (after)
  • Nexus 7 (2013 mid-range Android)

    • 2757ms avg (before)
    • 350ms avg (after)


  • Across all platforms, viewing a topic in Discourse averages 5x faster.

  • On older Android devices, viewing a topic is between 6-8x faster.

  • Our worst improvement was on the Nexus 6p on subsequent renders which was 4.6x faster.

On a Desktop PC, the speedup is a nice touch, mainly if you are an avid Discourse user.

On Android, it’s a huge quality of life improvement. Going from over 4 seconds to around half a second completely changes the experience you have on a forum.

Diagnosing Performance Problems

Ember’s rendering system is made up of a hierarchy of components. Every template that you render is backed by an instance of a Component class, and it manages the lifecycle of the template as well as delegating events to actions. Components can contain other components, and can use helpers to control flow. Here’s what a typical template looks like:

post.hbs (for rendering a single post)

{{avatar-link user=post.creator}}
{{poster-name user=post.creator}}

<span class='date'>{{}}</span>

<div class='post-body'>
  {{post-controls post=post}}

<div class='gutter'>
  {{post-links links=post.links}}

In the above example, avatar-link, poster-name, post-controls and post-links are all custom components that are displayed on every post. Each one would have its own handlebars template similar to post.hbs, and probably also a Javascript file to handle clicks and other interactions with it.

Ember also handles data binding for you. In the above example, if the or post.body changed, the template would automatically update. During development, this means you spend a lot less time thinking about how to update your user interface. If you want to change the body of a post, just call post.set('body', 'new body') and you’re done!

Behind the scenes, Ember does a lot of work to wire all this up. It keeps tabs on all the properties that can change, which components they belong to and so forth. If you’re only rendering a few posts, the overhead involved in this is small, but as you render more things with more details, it can add up.

It can’t be understated that all performance issues are about tradeoffs. I think Ember does the right thing here and focuses on apps that are organized and scale up as you add more features. For the vast majority of views in your application, the framework overhead will not concern you. However, if you are rendering many nested components with many bindings, the situation can become pathological.

While Discourse might look simple on the surface, each post is rendered with quite a few components. We have many dynamic buttons, links and effects applied every time a post is rendered with over 150 attributes involved.

Hindsight is 20/20

Every time you see a blog entry that says “by switching our codebase from language X to language Y, we improved our performance by a factor of Z!” you should realize that there’s an important detail omitted: When you re-write code, you have the full domain knowledge of the problem it solved the first time around. This knowledge goes a long way towards making it faster, because you know exactly what you need to do to get it to work.

For example: every time an Ember template encounters a {{property}}, it sets up a binding to make sure the template updates when the underlying property changes. This is a good default to have, but what if you know that the property will only change following an AJAX request? You can use this knowledge to render significantly faster.

This is the general approach we took to rewriting our topic rendering. We thought about the bare minimum amount of work the browser needed to do to implement the interface we’d already built. How maintainable would that code be? Was there some middle ground, where we could gain significant performance but also keep the code reasonably clean and integrated with the rest of our Ember app?

Wrapping code in Ember

Ember’s Components are also great tools to wrap third party Javascript, as they give you lifecycle hooks for when an element is inserted into the DOM and when it is removed. You can use these hooks to render pretty much whatever you want as long as you’re using Javascript.

Our approach was to create a single component, instead of a series of nested components, and when it was inserted in the DOM, to perform the rendering ourselves. We’d only re-render the DOM if the user performed an action on it or if our message bus told us to do so.

We looked around at various options for rendering quickly on the client side, and found virtual-dom to be very promising. It is only 8k when minified and gzipped, which seemed like a reasonable amount of code in exchange for a performance boost.

We didn’t want to sacrifice too much code quality, so we implemented a lightweight version of Ember Components called Widgets. (note: yes, I know Widget is very similar to Component, but a distinction was required and hey… naming is hard!)

Widget are classes that, given a series of attributes and optionally some state, would emit a series of virtual DOM nodes to be rendered. If you wanted to render a button that increased a counter on click, the widget would look like this:

import { createWidget } from 'discourse/widgets/widget';
import { h } from 'virtual-dom';

export default createWidget('counter', {
  tagName: 'button.counter-button',

  defaultState() {
    return { count: 0 };

  html(attrs, state) {
    return `Clicked ${state.count} times`;

  click() {

Widgets can render other widgets if they want too:

export default createWidget('controls', {
  tagName: 'div.controls',

  html(attrs, state) {
    return h('div.controls', this.attach('counter', attrs, state));

And you can mount a widget in any template template in our Ember application:

{{mount-widget widget="controls"}}

The existing actions in your Ember application can be triggered by templates:

{{mount-widget widget="button" doSomething="doSomething"}}

You can send it up from a click event easily:

// in your widgets/button.js code
click() {
  return this.sendComponentAction('doSomething');

If your action returns a promise, once it is resolved the widget will re-render itself. Most of the time the rendering is handled automatically like this for you, but you can also trigger a re-render yourself by calling this.queueRerender(). Renders are queued up and coalesced nicely by leveraging Ember’s event loop.


After converting our old Handlebars templates over to be virtual DOM widgets, I have to admit I find creating HTML this way significantly uglier than just creating a template. It’s not so bad if the widget only has a little markup, but if there is a lot it gets a little unwieldy.

On the other hand, there are some major advantages to emitting HTML by hand. The fine-tuned control over the exact DOM I was creating came in very handy when rendering the gaps between posts in a topic which was clumsier in the ember implementation.

It also took me quite a while to convert the entire topic renderer over, because we have so much functionality hidden in there! The project took me about a month of full time work to knock out an alpha, and then another 3 weeks of fixing bugs and to develop an upgrade path for our plugin authors.

It did feel good to refactor some of the oldest code we had, though. I also added a couple of hundred new acceptance tests. Traditionally the topic stream was not tested as well as the other parts of the site because its code was the oldest and weirdest. I straightened all that out while I was in there.

The Road Ahead

Before setting out on a similar project, I’d ask yourself: are you okay spending a lot of time without adding new features, and in the process likely breaking a bunch of working stuff before you fix it again? Would you sacrifice some code quality for a speed improvement?

Those are the major trade offs we made, and I believe it’s worth it because Discourse is quite a popular project used by many people. The 5-7x speed improvement will add up across all the forums in the world, especially with all of the Android users who browse it.

Going forward, we are likely to improve the widget system even more. I’d love to hook into the HTMLBars complier AST so we could write some templates using Handlebars, so we are not supporting two very different ways of creating templates. I spent about a day looking into this now but couldn’t find sufficient documentation or public APIs, but I’m told that in the future it’s likely we will be able to do this.

Until then, full speed ahead!

Update: If you want to learn more about how the Widget framework works, I’ve written more here.

View the full article to comment on it

TIS-100: My emulator for a CPU that doesn't exist

Jun 29 2015

Recently I became infatuated with TIS-100, a game which aptly describes itself as “the assembly language programming game you never asked for!”

The point of the game is to program the (imaginary) TIS-100 CPU to solve problems. For example, you might need to take input from two ports and swap them, then write the outputs to two other ports.

The game flies in the face of all modern game design: The first thing you need to do is sit and read a 14 page PDF that outlines the TIS-100 instruction set. And when I say “read”, I mean “learn”, because a quick skim is not going to cut it! There are no tutorial levels or handholding. You must read the manual.

After solving the first few problems and feeling good about myself, I approached some of my programmer friends and tried to get them to buy the game so I could compare my solutions to theirs. I swear I tried bringing this up with 3 people and had the exact same conversation:

Them: “So, it’s a game about programming…”

Me: “Yes, it’s so much fun!”

Them: “But I program all day.”

Me: “Me too!”

Them: “The last thing I want to do when I come home is program again”

awkward silence

Them: “You’re nuts.”

The rabbit hole goes deeper

Despite not having any close friends to play with, I plowed through the puzzles in the game. One in particular was quite devious; The TIS-100 is, as I mentioned, an imaginary CPU. And it is clearly designed to be puzzling rather than practical. It has only two registers, and one is a backup that cannot be addressed directly. This afformentioned puzzle involved taking the input of two numbers and dividing one by the other. You then output the resulting quotient to one port and the remainder to another.

It was quite fun to work through, but to my dismay my solution was quite inefficient. If I clicked the regular “Play” button to execute it it would take several minutes to finish. Even if I ran it in “Fast” mode it would take about 5 seconds to complete successfully.

This was obviously unacceptable.

A typical person might call it a day and say, “well, the real victory is solving the puzzle!”. Another, more eccentric person might spend the time figuring out how to optimize their solution so it executes in less time. And then there’s me.

Introducing my TIS-100 emulator

I decided the most logical thing to do was to implement the TIS-100 CPU myself in pure C. This seemed like a good idea to me despite having not used C in about 15 years.

Amazingly, most of the concepts came back fairly quickly. Maybe C is like riding a bike? Maybe using so much Javascript (and its C syntax) kept me on the ball? I’m not sure.

I first wrote a parser to input the TIS-100 assembly language as defined in game. It writes it to memory in byte code, which is then interpreted. The resulting performance is really impressive!

The Unity version of TIS-100 that runs on my Mac executes my division program in about 5 seconds, which is an eternity as far as programs go! My C emulator runs the code in a sleek 0.005s, or roughly 1000x faster!

The full source code is on GitHub, so feel free to download it and check it out. I’ll even accept pull requests as I’m sure there’s a lot of room for improvement.

Why did I spend my time on this pointless project?

I try to not use the word “crazy” often because I don’t want to trivialize mental illness, but let’s be honest: I have to be a least a little off base to attempt a project like this. Programming is a legitimate hobby of mine. I make a living at it but I also do it in my spare time. TIS-100 was a perfect storm of programming and fun, and I didn’t want it to end.

Obivously I’m not the only one who enjoyed the game, so there is a market for this kind of thing. Maybe this is the long tail of games?

All I know is I had a lot of fun doing it, and I hope someone has fun with my emulator. Let me know if you do!

View the full article to comment on it

ember-tv: Creating a 10 foot interface in Ember.js

Nov 17 2014

Over the weekend I spoke at the Embergarten Saturday Symposium, which was an awesome mini conference on Ember in Toronto. My topic was “Ember at 10ft”, and it was about how to build a TV friendly interface in Ember.js.

The talk was recorded but not yet posted, however I’ve already posted the source code on github. The github repo contains my slides from the talk as well as speaking notes.

I’ve also put up an online demo. Check it out!

View the full article to comment on it

Learn Ember.js with me in Toronto!

Aug 15 2014


If you’re interested in learning Ember.js, I’m happy to announce that I’m partnering with my friends at Unspace to teach an introductory class on Saturday September 13th here in Toronto.

We did one of these last year and it was super fun. This time around we’re just focusing on the beginner stuff, so if you or anyone you know are new to Ember.js, you should check it out.

All the information you need is on the Embergarten website!

View the full article to comment on it

Creating an Integration test in Ember.js (Screencast)

Jun 27 2014

Once upon a time it used to be difficult to create integration tests in Ember.js. Fortunately, the framework has come a long way and it’s now really easy to get integration testing working in your application. This screencast shows how to set it up with ember-cli:

There is some boilerplate code required that you’ll need at the top of your integration test files if you want to do it yourself. Here it is:

import startApp from 'vault/tests/helpers/start-app';
var App;

module('Integration - Secret', {
  setup: function() {
    App = startApp();
  teardown: function() {, 'destroy');
View the full article to comment on it

Building Emberredit (screencast)

May 29 2014

One of my more popular blog entries is on using Ember.js without Ember Data. Recently I’ve been going through my old entries and making sure they don’t have any glaring mistakes, and I realized this would be a good opportunity to convert my emberreddit project to ember-cli.

This screencast shows how you can build an Ember.js application without using Ember Data. It starts off simple and then shows how to build advanced stuff like an identity map yourself.

It assumes some knowledge of Ember. The guides and docs for Ember.js are available at:

To install NodeJS go to:

The excellent ember-cli is available at:

And finally the code created in this screencast can be found here:

Thanks to Stefan Penner, Jo Liss and the Ember Core team for making this amazing framework and tools. Also thanks to Erik Bryn for showing me a few tips about the model hook!

I had a lot of fun making the screencast so I will likely do more in the future. Drop me a line and let me know what future screencasts you’d like to see.

View the full article to comment on it

Getting Started with ES6 Modules

May 3 2014

Javascript is a fantastic example of how something, despite having visible warts and very poor design, can dominate the tech landscape. Nobody uses Javascript because it’s a beautiful language; they use it because it’s ubiquitous. Its warts are now well understood and most have workarounds.

An amazing omission in Javascript’s design is the lack of a built-in module system. As more projects used Javascript and shared more code, the need for a robust module system became necessary. Two contenders sprung up, Asynchronous Module Definition (AMD) and CommonJS (CJS). The former is much more popular with browser applications and the latter is much more popular with server applications written in node.js.

Having two major standards for defining modules led to a technological holy war in the Javascript community akin to the vim/emacs arguments of the editor world. It wasn’t pretty.

Fortunately, there is light at the end of the tunnel. TC39 has been hard at work on the next version of Javascript, called ES6 (short for EcmaScript 6). One of the major features of ES6 is a standard syntax for handling modules in Javascript.

A simple example of ES6 modules

By default anything you declare in a file in a ES6 project is not available outside that file. You have to use the export keyword to explicitly make it available. Here’s an example of how to export a user class:

// user.js

var localVariable = 123;  // not visible outside this file

export default function User(age) {
  this.age = age;
}; // can be imported by other files

And now if we wanted to use the User class in another file:

// user-details.js

import User from 'user';

var evilTrout = new User(35);

Pretty simple, isn’t it? There are many more examples of the syntax here if you are curious about other ways it can be used.

When will it be available in browsers?

In the past, it was very risky to use new Javascript features before they were standardized and widely available in browsers. You’d never know if someone was using an old or incompatible browser and it would cause your code to crash and burn.

These days, thanks to the Extensible Web movement, people are working hard at making it so that developers can try out advanced features before they’re compatible in all browsers.

The great news is you can use ES6 modules today! You just have to run your code through a transpiler. The transpiler will convert your ES6 modules into Javascript that browsers can understand today. In the future, when the browsers understand ES6 modules natively, you’ll be able to stop transpiling and it will just work.

The transpiler I’ve been using lately is es6-module-transpiler from Square. If you check out their build tools section you’ll see they’ve got integration stories for all the major Javascript build tools.

If you are using Rails on the server side, Dockyard has created an easy to use Gem version of it that you should be able to drop into your project.

ES6 Modules and Ember.js

The Ember community has bet big on ES6 modules. For example, if you are using Ember App Kit to structure your project, it includes ES6 module support via transpiling out of the box.

Recently, Robert Jackson converted the Ember source code to ES6 modules. This means that, if you have things set up properly in your development environment, you can import just the parts of Ember.js that you want to use and end up with a potentially smaller runtime.

ES6 modules integrate quite beautifully in an Ember project. If you’re not using ES6 modules, the standard way of making parts of your application available for discovery was by hanging them off your application’s global namespace. For example:

// app/controllers/user.js
App.UserController = Ember.ObjectController.extend({
  // ... controller code

Then if you transitioned to the user route, Ember would search for a UserController on your App object. This actually works quite well, but making everything available globally makes it too easy for developers to reach into components they have no business reaching into. If you make it easy for a developer to do the wrong thing, they will do it.

To contrast, if you are using Ember with an ES6 application you can define your user controller this way:

// app/controllers/user.js

export default Ember.ObjectController.extend({
  // ... controller code

Ember’s new resolver will then look for the module exported from the app/controllers/user path and will wire it up for you automatically.

Going Forward

I’ve found that since I started using ES6 modules in my projects that their code bases are a lot cleaner and more organized. It also just feels awesome to be using a standard before it’s widely available.

I’ve got a branch of Discourse that I am converting to ES6 modules one at a time. The bad news is that Discourse has hundreds of files to convert, so it will be some time before we are 100% on ES6. The good news is, with a little duct tape in our custom resolver, the application can run with some modules in the global Discourse namespace and some in ES6 format. I’m hoping to merge it into master shortly so our contributors can help with the converting efforts.

My advice is to not wait for browsers to implement these modules; start hacking today and put your project ahead of the curve. There are other ES6 features that can be transpiled too, and I’m excited to try some of those out too!

View the full article to comment on it

The Refresh Test

Apr 10 2014

How many times has the following happened to you?

You go to a web site and it asks you to create an account. You fill out a form with all the obvious fields and hit submit. The page refreshes and shows you the form again.

Phone Number is required

Well, that’s annoying. There was no indication that the site needed your phone number. You prefer not to give out your phone number to every web site, but this one is run by a company you trust, so you scroll down and fill it out. You submit the form again.

Password is required

What the heck!? You already entered a password! You scroll down to the form and see that the fields are now empty. It turns out that even though you filled out the password fields the first time, after you missed the phone number they were cleared. You fill them out and submit the form again.

Username is not available

At this point you’re ready to throw your computer out the window. There are fewer things more frustrating than trying to get your data into the exact shape a web site wants, especially if it clears fields every time you fail.

Another annoyance: just about every time I order something online, right after I input my credit card information, I am presented with a spinner animation and the text “Do not hit the back button or refresh your browser!” It’s terrifying that a company that is taking my money over the Internet can’t handle me refreshing the page without charging my card twice.

The sad thing is that both of these problems are totally solvable. In fact, they’ve been easy to solve for over a decade. Yet you still see them all the time.

Lessons from Live Reloading

Recently I spent some time playing with Ember App Kit. Ember App Kit is a suggested project structure for your applications built by Stefan Penner (and a bunch of other awesome developers). It’s really great and if you’ve never tried it out you should![1]

One feature Ember App Kit includes out of the box is support for connect-livereload, which automatically reloads your changes in your browser whenever you save a file.

It sounds like a minor thing, but after using it for a few hours having to manually hit Cmd-R feels like a chore. It’s a great little productivity booster.

Live Reload also has a side effect: it encourages you to make your application refresh resistant.

In my application I had a multi-step wizard where you had to enter many form fields at once, and I found it so frustrating to have all my form data pulled out from underneath me every time I hit save.

The frustration led me to persist the form data temporarily in localStorage. Once I did that, every time my application refreshed it looked exactly the same as it did before. It was probably a grand total of 10 minutes of work, and my application was much more resilient for it.

The Refresh Test

A great experiment to perform on a Javascript heavy application is to simply refresh the page and see where you end up. Does it look the same as before? Did you lose any work?

Users will put up with losing a small amount of state on refresh, for example if they’d expanded a menu and it’s suddenly collapsed, but you should never throw away what they were working on.

One thing I love about Ember.js is that its router makes you think in terms of URLs, which gives you a great head start for handling refreshes and the dreaded back button.

Many people think of URLs as files, because in the past requesting a path like profile.php?id=eviltrout meant you really wanted a file on the server called profile.php with the parameter eviltrout.

I find it’s better to think of a URL as the serialized state of your application. A path of /profiles/eviltrout should mean “I’m viewing eviltrout’s profile.”

If you’re building a Javascript application and the URL is not changing as your users navigate around, that is practically begging to give them a bad experience at some point. Not only can they be easily frustrated if they hit the back or refresh buttons, but they won’t be able to bookmark or share links with others.

I’m not suggesting that the URL contain every possible interaction a user can make; if you do that you will end up with a huge headache and a meaningless URL. Instead, you should focus on the most important things a user will want to see when the page is refreshed. For example, on Discourse we maintain a user’s scroll position in a topic by changing the URL as they scroll.

Going forward, I’m going to make sure that all my applications handle refreshing elegantly and I recommend you do too! If you’re interested in more on this topic, Tom Dale has a great talk on this called Stop Breaking the Web.

1. If you’re a fan of using bleeding edge stuff, check out Stefan Penner’s ember-cli and Jo Liss' broccoli. Ember App Kit works well today but those projects are a glimpse of the future of where Ember development is headed.

View the full article to comment on it

Older Posts

Embedding Discourse in Static Sites

Jan 22 2014

Hiding Offscreen Content in Ember.js

Jan 4 2014

Internationalization Support in Ember.js

Nov 24 2013

Enemy of the State

Oct 5 2013

Let's Talk about Browser Applications (and Forums and Discourse)

Jul 31 2013

Computed Property Macros

Jul 7 2013

Adding Support for Search Engines to your Javascript Applications

Jun 19 2013

AngularJS vs Ember

Jun 15 2013

Organizing Data in Long Lived Applications

May 26 2013

Ember without Ember Data

Mar 23 2013

Generating IIFEs in Rails

Feb 25 2013

Infinite Scrolling that Works

Feb 16 2013

Why Discourse uses Ember.js

Feb 10 2013

Crawling the Downvote Brigades of Reddit

Jan 16 2013

How our users exploited concurrency and how we fixed it

Jan 10 2013

Turbolinks and the Prague Café Effect

Jan 6 2013

Just because you're privileged doesn't mean you suck

Jan 3 2013

I've been programming since I was 7

Dec 30 2012

Is Penny Arcade being ghost drawn?

Sep 30 2012