Tuesday, October 27, 2015

Web Performance Short Course

I went to a tutorial on web performance at HTML5DevConf. These are my notes:

Daniel Austin was the instructor.

He worked down the hallway from Vint Cerf when he was creating the world wide web, and he was the manager of the team at Yahoo that created frontend performance as a discipline. He was the manager of the guy who created YSlow. A lot of the books on web performance are from people he used to manage. He was the "chief architect of performance" at Yahoo.

He's writing a book called "Web Performance: The Definitive Guide".

He started by asking us how many hops it took to get to Google (per traceroute).

He had us install the HTTP/2 and SPDY indicator Chrome extension.

He's given this class at this conference 5 years in a row. It's changed dramatically over the years.

This is only a class on the basics.

The most important key to understanding performance problems is to understand how the web works and work within those constraints.

Understand what's going on under the covers, and identify the problems. That's half the battle.

There are lots of tools.

We're always focused on the end user's point of view (the "user narrative").

This is both an art and a science.

Most of the people doing web performance now started at Yahoo.

He didn't think the first book on web performance was very good.

All of his slides are on SlideShare.

Capacity planning and performance are opposite sides of the same coin.

Most performance problems are actually capacity problems.


  • spreadsheets
  • webpagetest.org
  • speedtest.net
  • your browser's developer tools
  • YSlow
  • netmon
  • dig
  • ping
  • curl
  • Fiddler
  • there are a bunch of mobile tools

The site is fast enough when it's faster than the user is.

Theme: Ultimately, performance is about respect. He thinks Google is just making stuff up when it says that slower responses result in X amount of lost dollars. He thinks it's really just about respect.

He seems to have an anti-Google bias ;) He even asked who in the class was a Googler.

Section I: What is Performance?

It's all about response time!

Latency is about packets on a wire. Humans experience response time, not latency.

The goal: "World-class response times compared to our competitors."

We want reliable, predictable performance.

It must be efficient and scalable.

We want to delight our users.

Performance is a balancing act.

Security vs. performance is a common tradeoff.

Section II: Performance Basics

Statistics 101:
  • sort
  • mean
  • median
  • mode
  • variance
  • standard deviation
  • coefficient of variation (variance)
  • minimum
  • maximum
  • range

He compared the mean, median, and mode. The mean is rarely used in performance work.

The median is the number in the middle. We use that more often than the mean.

The mode is the most frequent number in some set.

Performance data is full of outliers. The outliers disturb the mean which is why we can't use it.

Pay close attention that you're talking about the median, not the mean.

If the mean and the median are more than one standard deviation apart, then the data is wrong because that's not possible.

The standard deviation is the average distance between a point and the mean. It's a measure of how scattered the data is.

Performance is vastly different between Asia, the EU, and the US. It's a network infrastructure issue.

The margin of error is a measure of how close the results are likely to be.

The more data you have, the lower the margin of error.

You need 384 data points to get a 5% margin of error.

You need to gather a considerable amount of data to be confident in your analysis.

"5 Number Reports" consist of:

  • median
  • 1st quartile
  • 3rd quartile
  • minimum
  • maximum

The typical performance curve:

  • No users get response times less than a certain amount.
  • Most people get response times somewhere in the middle.
  • There's a long tail of people getting much longer response times.
  • Sometimes they even time out.

You know you have a problem if:

  • A lot of people are getting bad response times.
  • A lot of people are timing out.
  • There's a second hump in the curve for the people getting slower response times.

Curl is our favorite browser! ;)

curl -o /dev/null -s -w %{time_total}\\n http://www.twitter.com

Run it 10 times in a row, put the numbers in a spreadsheet, and calculate a 5 Number Report.

The results are really messy!

Curl is way more widely used than you might think. It's even used in production at very large companies.

I don't think I got this completely right:

0.039 min
0.045 1st quartile
0.05 median
0.107 3rd quartile
1.233 max

25% of the data points are in each of the quartiles.

In the performance world, there's usually a big difference between the mean and the median.

You can look at Wikipedia to get the exact formulas for these things.

Across the class, we did 100 measurements, and we had a huge range.

There's a significant amount of variation on the Internet in general. "The web is subject to very high variance."

dRt / dt = crazy ratio = the derivative of the response time

Anytime your slope is greater than 0.5, then it's crazy. It's possible that your connection is bad.

We have to figure out: Is the DNS slow? Is the SSL slow? Are the servers slow?

The first thing you want to do is calculate the crazy ratio.


  • Min = MIN(Data Range)
  • Q1 = QUARTILE(Data Range, 1)
  • Q2 = QUARTILE(Data Range, 2)
  • Q3 = QUARTILE(Data Range, 3)
  • Max = MAX(Data Range)


  • RT <- ...="" 0="" 1="" c="" li="" numbers="">
  • fivenum(RT)

Operational research:

  • Supply chains
  • Utilization Law
  • Forced Flow Law
  • Little's Law
  • Response Time Law

You have to understand how queues work. Think of freeways.

Resources and queues:

  • Service time (Si)
  • Queue residence time (Ri)
  • Queue length (i)

In general, systems consist of many combined queues and resources.

Workload differentiation: different lanes for different speed vehicles.

The Utilization Law: Ui = Xi * Si

The utilization (Ui) of resource i is the fraction of time that the resource is busy.

If you let your systems get to 95% load, you should be fired.

Xi: average throughput of queue i, i.e. the average number of requests that complete from queue i per unit of time.

Si: average service time of a request at queue i per visit to the resource.

The Interactive Response Time Law: R = (N/X)-Z

R = response time
N = number of users
X = number of requests/s
Z = time the user is thinking (think time)

This doesn't make sense to me because in my mind, the number of requests/second varies a lot based on the number of concurrent requests.

He suggested that you can always increase the number of requests/second by adding more capacity. However, my understanding is that it takes a lot of work to get to a horizontally scalable architecture, and that it's often the case that there is a bottleneck that throwing more servers at the problem can't
immediately solve.

Figure out if you have a capacity planning problem.

Capacity and performance are intimately related.

Often, your performance problems are really capacity problems.

Antipattern: keyhole optimization: optimizing your project at the expense of everyone else.

Section III: The MPPC Model

Dimensions of performance:

Network location
Transport type
Browser/device type:
RT varies by as much as 50%
Page composition:
Client-side rendering and execution effects
Network transport effects:
Number of connections; CDN use

You have to test on multiple types of devices.

Take some crap off of your page to make it faster.

CSS used to be benign in terms of performance. That's now no longer true. CSS can cause performance issues.

He's big on CDNs.

He talked about how hardware and routing work. It was a pretty complex slide.

The backbone is about as good as it can get. It's the last mile that is the problem.

He talked about the OSI Stack model.

Microsoft invented ethernet type 2.

MTU = 1500 bytes = maximum transmission unit

MSS = 1460 bytes = maxiumum segment size = the size of data in the packet

20 bytes for IP, 20 bytes for TCP.

SSL is a good example of the session layer.

He said HTTP is layer 7, application.

We care about:

  • IP (layer 4)
  • SSL (layer 5)
  • HTTP (layer 7)

OSI = Open Stack Interchange

HTTP connection flow:
  • Make a TCP connection
  • Send a request
  • Get the response

HTTP is a request/response protocol.

MPPC = Multiple Parallel Persistent Connections

He wrote the original paper on this model.

To calculate the end-to-end time, you can use the given equation: E2E = T1 + T2 + T3 + T4

  • T1 = network connection:
    • T1 = T(DNS) + T(TCP) + T(SSL)
  • T2 = server duration = time it takes the server to respond
  • T3 = network transport
  • T4 = client processing = process the response, display the result, plus the user's think time

For Facebook, it's usually T3 (network transport) that takes the longest, whereas most developers are almost entirely focused on T2 (server duration).

Don't go chasing after T2 too quickly. Figure out all of the Ts.

He thinks Microsoft's browser, Edge, is perfectly fine.

There are two types of hyperlinks on the web:

  1. Transitive hyperlinks: The ones you click on.
  2. Intransitive hyperlinks: The ones that browsers clicks on for you (images, JS, CSS, etc.).

He said that the number of intransitive hyperlinks is way more than the number of transitive hyperlinks. [I did some tests on a bunch of sites, and that turns out to often not be true.]

95% of the bytes are from intransitive hyperlinks (images, JS, CSS, etc.).

DNS is typically a larger part of the E2E than expected.

TCP is highly variable.

SSL is slow!

T1 might be bigger than you think. For PayPal, T1 accounts for 40% of their E2E.

Nothing happens and the user doesn't see anything before DNS.

Google runs their own DNS servers to improve response times. It makes it more reliable and predictable.

He had us install Dyn Dig on our phones.

Using Dyn Dig on my iPhone, it took 40 msec to resolve udemy.com.

Using dig, it took 175 msec to resolve udemy.com.

He worked on x.com. It's the only single letter domain that you can sign up for your own email address.

Among all the people in the class, there was very high variance in the DNS response times. There was a factor of 10 difference. A factor of 3 is more common.

A DNS lookup anywhere on earth should take less than 500 ms.

It shouldn't take you longer than 10ms to get to your ISP.

Mobile DNS lookup times are all over the map.

For popular sites, DNS lookups are fairly constant because it only involves talking to your ISP.

It takes 14 steps to make an SSL connection.

He said that wherever he said SSL, he really meant TLS.

SSL takes up the lion's share of T1.

If you're using SSL, it is likely the biggest thing in T1-T4.

EV certificates = extended value certificates

EV certificates take twice as long. It's a 2048 bit key.

Banks use EV certificates.

When they're used, there's a nice green bar in your browser.

"The current internet is overly reliant on encryption and confuses encryption with security...Don't confuse being encrypted with being secure."

T2 - The Server Duration

He treats the server as a black box. He doesn't care what's inside it. He only cares about how long the server takes to respond to a request.

If there's a lot of variance in T2, it's a capacity problem.

We want servers to scale linearly with the number of users.

At some point, a server can't respond to more load in a linear way. Don't load your machines past the point where they go non-linear.

Typically, machines in production run at 70% utilization or less. 40% is actually pretty common.

You have to have enough capacity to account for machines going down.

T3 - TCP Transport Time

This is the part he likes the most since he's a network guy.

TCP is pretty predictable.

Remember that HTTP has evolved over time.

He said that HTTP/1.1 came out in 1998.

We got HTTP Keepalive in HTTP/1.1.

HTTP/2 became a standard on May 14, 2015.

Firefox will open up to 6 connections for each unique host on a page. IE will only open 2.

"There was no equation until your truly solved it...published in IEEE."

With HTTP/2, you make one connection, but then there's a bunch of streams within that one connection.

TCP is not very efficient for transferring small files.

The size distribution of objects on the internet peaks around 7k.

The Yahoo logo is always fairly small in file size. It only uses a single color.

T4 - What the Browser Does

He showed the waterfall of request times for yahoo.com.

T4 is especially important for mobile devices. They have smaller processors, so they take longer to render pages.

The big guys have mobile versions of their sites that have less stuff on them.

Mobile devices often run JavaScript much more slowly than desktop devices. Part of this is because of how they do floating point arithmetic.

Bandwidth and latency have to do with the network.

More bandwidth is like having a wider hose.

Latency is like the length of the hose.

Adding bandwidth only helps up to about 5 Mbps.

Reducing latency helps linearly with reducing response times.

In the US, more than 90% of people have a 5 Mbps connection or better.

If the pipe is fixed, then put stuff in the pipe more efficiently.

He talked about packet loss.

He talked about the congestion window.

Every time TCP looses a packet, it cuts the bandwidth in half.

He really likes using equations with Greek characters to model things. He calls it "solving the equation".

On mobile, packet loss is typically 5-7%.

For any given user, their latency and bandwidth is fairly fixed.

Packet loss is a limiting factor for bandwidth.

Packet loss almost always happens because of overflowed buffers or failure to reassemble fragmented packets.

Antipattern: saying "that's outside my control."

It's never the case that there is nothing you can do about a performance problem.

Compensate in some other part of the E2E. Think outside the box.

Section IV: Tools and Testing

I didn't get his entire list of tools. Sorry.

  • YSlow
  • HTTPWatch (very good)
  • Your browser's development tools

You must gather data from lots of users. Performance work is statistical in nature.

Remember, we have a special position here in the valley. Think about people who don't have internet connections as good as ours.

Those tools aren't going to help you make the network faster in India. But, they can help you fix problems with page composition.

For instance, what things are being loaded? What things are blocking progress on your page?

There might be an ad making your page slow.

There are commercial performance services:

  • Gomez (Compuware)
  • Keynote
  • AlertSite
  • ThousandEyes

Gomez and Keynote are super expensive corporate tools.

New Relic is a less expensive tool to try to solve some of those problems.

Performance numbers are going to vary between the backbone and the last mile (of course).

gamma = last mile response time / back bone response time

His goal is to identify problems. How to solve them is another thing.

He's worked at a lot of the big dot coms.

RUM = real user measurements

Yahoo alone was responsible for 16% of JavaScript errors on the Internet. It was mostly because of ads.

Users were seeing response times that were 10X the response times on the backbone.

When he tests things, a test is a set of pages. A monitor is a set of tests.

He talked about YSlow. The rules were published by his team at Yahoo. People pay attention to the first 14 rules, but there were actually 105.

PageSpeed is from Google.

HTTPWatch is the commercial software.

UNIX tools: ping, dig, traceroute, curl


MSS / RTT = maximum segment size / round trip time = a good way to guess how long it'll take for your page to arrive.

Use ping to figure out the RTT.

WebPageTest.org will give you a lot of the same information that the commercial tools provide.

All the performance work in the web world came out of Yahoo.

The 14 YSlow rules are all about T3.

Here are the original 14 YSlow rules:

  1. Make fewer HTTP requests.
  2. Use a CDN.
  3. Add an expires header. (There are now better headers.)
  4. Gzip components.
  5. Put CSS at the top.
  6. Put scripts at the bottom. (We now say to put them in the head.)
  7. Avoid CSS expressions.
  8. Make JS and CSS external.
  9. Reduce DNS lookups.
  10. Minify JS.
  11. Avoid redirects.
  12. Remove duplicate scripts.
  13. Configure ETags. (He says don't bother.)
  14. Make AJAX cacheable.


Mobile devices are weak on floating point operations. Hence, they may not be as good at decompressing things.

Do not put the scripts at the bottom. The advice has changed. Chrome compiles your scripts to binary, but only if you put them at the top.

It halts the rendering process if you have JavaScript in the body. If it's in the head, it doesn't.

He's mixed on whether minification is good or not. It makes debugging harder. Maybe gzip is enough.

The rules are now different.

Unix performance testing tools:

  • ping
  • nslookup, dig (These are somewhat interchangeable.)
  • traceroute
  • netstat (This lists the network connections on the machine.)
  • curl

When you traceroute a site, the number of hops varies between runs.

If you get stars during a traceroute, that means there's a firewall that is preventing you from getting that information.

traceroute google.com

When tracerouting google, we got a range of 13-17 hops.

UNIX can't really measure things less than a millisecond.

netstat -a
netstat -A
netstat -A | grep -i HTTP

curl only returns the base page. It doesn't retrieve the images, etc.

WebPageTest.org is really good.

When you look at a waterfall diagram, find the long pole.

cache ratio = cached response time / uncached response time

Cache more.

WebPageTest.org is running real browsers.

It's okay if your base page isn't cached. Make sure the images, etc. are cached.

Task-based performance thinking: Users have use cases. They don't care about just a single page.

Look at the paths users use. Then, make those paths easier.

Users don't do what you thought they would do when you designed the website.

Focus on optimizing the 2-3 things the users do the most.

Test your competitor's performance.

Tumblr was a top 20 website, and it ran out of the founder's basement before Yahoo bought it.

Stormcat is for global performance testing.

Antipattern: design-time failure.

You can't bolt performance onto your website after you launch it.

Section V: ???

He talked about "W3C navigation timing". He almost never uses this. He doesn't think it's very good even though he worked on it.

Antipattern: we'll be done with this soon.

Performance is an ongoing activity, not a fire and forget activity.

Antipattern: not treating performance as a property of the system, or only testing at release time.

Pattern: establishing a long-term performance management plan as part of your cycle.

Native apps run 5X faster than HTML5.

Mobile is 10X slower than desktop.

HTML5 on mobile devices can be 50X slower:
  • 10X from the ARM chip
  • 5X from JavaScript

However, chips have gotten a lot better lately.

3G adds 2000ms of latency.

3G is not very common here, but it's very common overseas.

4G is much better.

Since 2009, mobile browsers went from 30X to 5X slower than desktop browsers.

In the US, we're generally on LTE, not 4G.

HTTPWatch is a good app for mobile.

Amazon's home page makes 322 requests. It's insane.

74% of users will leave if a mobile website takes more than 5 seconds to load.

Use the right tool for the right job:

  • Server
  • HTML
  • CSS
  • JavaScript

Nick Zakas architected the Yahoo homepage.

Doug Crockford said, "Don't touch the DOM!" [Not sure about that.]

TTFB = time to first byte

TTFB is not a good measure of server duration.

Use web workers for preloading.

Test performance on different transport types.

Test battery consumption.

The NYT website eats up your battery life.

Mobile networking is a big challenge, so design for delay tolerance.


There's iCurl for the iPhone.

Antipattern: Failing to recognize that the distribution of the mobile E2E is very different from a desktop performance profile.

The server duration is about 35% of the total E2E.

Section VI: Psychology of Performance

100ms to identify distinct objects
150ms to respond
250ms for user "think time"

TVs delay the sound by 30ms.

Th = Tp + Tc + Tm
T(human) = T(perceptual processing) + T(cognitive) + T(motor)

When faced with N choices, users will take O(log N) cycles to proceed.

The size of UI objects on small screens limits your accuracy.

Wearables and small devices are near the point of minimum usability for visual interactions.


My initial response time was 244ms ;)

  1. Make performance a priority.
  2. Test, measure, test again.
  3. Learn about tools.
  4. Balance performance with features.
  5. Track results over time.
  6. Set targets.
  7. Ask questions; check for yourself!

He pointed at me and said, "This guy has been asking me questions all day, and he's not entirely sure I'm right about everything, which is good...I'm not right about everything...I can be wrong."

Tim Berners-Lee invited the WWW, HTTP, and the URL addressing scheme.

Doug Engelbart invented the mouse and hypertext. He died 2 years ago.

Dr. Charles Nelson (?) invented SGML. [Hmm, Wikipedia says something else.]

HTML is based on CALS which is an SGML dialect.

Tim Berners-Lee wrote the original code for all of this, although he's not very good at writing code. His genius was assembling all the parts into a working system.

Wednesday, October 21, 2015


I went to HTML5DevConf. Here are my notes:

ES6 for Everyone

JavaScript started in 1995.

ECMAScript version 3 came out in 1999. It was in IE6. It's what most people are used to.

for (var state in states) {
if (states.hasOwnProperty(state)) {

There were 10 years of sadness after that during which not much happened.

ECMAScript 5 came out in 2009. It was a minor improvement.


Then, HTML5 started happening.

Object.keys(states).forEach(function(state) {

Babel is a tool that compiles ES6 code to ES5 code.

Only 10 people in the room were using it in production.

Here is some ES6 code:

let states = {...};
.forEach(state => console.log(state));

ES6 is mostly syntactic sugar.

To use it, you must have Chrome, Edge, or Babel.

Default parameters:

... = function(height = 50) {

Previously, you had to do:

... = function(height) {
height = height || 50;

Template literals (back ticks):

var name = `${first} ${last}`;

var x = `
I have a wonderful
block of text here


Grab the house and mouse properties from the thing on the right:

var { house, mouse } = $('body').data();

If those properties aren't defined, you just get undefined.

He's not covering let and const.

Grab the middleware property from the my-module module:

var { middleware } = require('my-module');

It works with arrays too:

var [column1, column2] = $('.column');

Skip a column using multiple commas:

var [line1, line2, line3,, line5] = contents;

How do you get started with ES6?

  • Babel converts ES6 to ES5.
  • Webpack takes your JS modules and combines them into a single file.

Arrow functions.

Old way:

var greetings = people.filter(function(person) {
return person.age > 18;
}).map(function(person) {
return "Hello " + person.name;

New way:

var greetings = people
.filter(person => person.age > 18)
.map(person => "Hello " + person.name);

If you have more than one line, you can add brackets, but that gets rid of the implicit return statement.

Arrow functions deal with "this" better.

You don't have to do things like:

var self = this;

Arrow functions implicitly bind "this".

$.get("/awesome/api", data => {

Be careful of jQuery because jQuery will hijack "this".

Use parenthesis if you have more than one argument.

() => console.log("hi");

(person) => person.name;

person => person.name;

(one, two) => {
return three * four;


(x => console.log(x))("hey");

All of the above are the simplest, most useful features of ES6.

He's not going to cover classes today. He thinks that they don't add enough value.


$.get(`/people/`${id}`).then((person) => {
}).catch(function() {

This standardizes promises because everyone had their own version.

Only two things are important:

  1. .then
  2. .catch

Errors in the "then" also end up in the catch which is really helpful.

Use Promise.resolve to convert jQuery promises to ES6 promises.

The history of modules in JavaScript:

First, we used closures.

var module = (function($) {
return ...;

Then, AMD:

define(['jquery'], function($) {

Then CommonJS (which is a good place to start):

var $ = require('jquery');

var x, y, z;
module.exports = $.doSomething();

ES6 modules:

import $ from 'jquery';

var x, y, z;
export default $.doSomething();

// More examples:
export var age= 32;

export function printName() {

// In another file:
import { age, printName } from 'my-module';

He still didn't cover a ton of stuff. Babel has a nice tutorial on all the new features.

Reusable Dataviz with React and D3.js



He showed how to implement a Space Invaders game using React and D3. Very clever!

The problem: Spreadsheets don't scale. Simple libs aren't customizable. D3 is hard.

React principles:

  • Components
  • Immutability
  • Just re-render

Solution: change the data and redraw. This is how a video game works.

Flux is an architecture, not a library.

Only 1 person in the audience admitted to using Emacs. Crazy.

You can use React to build SVG, not just HTML.

Just update the model and let React deal with it.

React gives you hot reloading.

Use D3 more for the math and less for the SVG.

He thinks that React may be better than Angular because of the diffing algorithm (and virtual DOM). Angular also makes it harder to move things around because of the nesting and scopes.

He strongly recommends using Flux with React.

React--Not Just Hype!



He is the primary author of react-router.

He also works on Redux.

He gave many compelling arguments and examples of how React has an advantage over Angular and Ember.

React has historically had better performance than Ember and Angular.

"It's amazing what you can do with the right abstraction."

He wrote the JS implementation of MustacheJS.

In Angular, you can put things in scope in the controller, rootScope, directive, somewhere else in the view, etc. If you see a variable in the template, it's hard to know where it's coming from.

He showed a nice side-by-side example of Angular and React.

It's easier to drive things from the JS (in React) than from the template (in Angular).

<div ng-repeat="model in collection">


collection.map(model => (
React.createElement('div', null, model.name)


collection.map(model => (

Angular has to keep inventing new DSL syntax for the templating language to implement new features. In React, you just have JavaScript.

He's done a lot of work in both models. He just thinks the React model is better.

Scoping in Angular is complex. Scoping in React is just JavaScript scoping.

In general, it's better to be in JavaScript than to keep on adding stuff to Angular's templating DSL.

MDN's docs are pretty good for JavaScript documentation.

React lets you "describe UI". It doesn't have to render to just HTML. It can render to other things as well, for instance SVG, Canvas, three.js (WebGL), Blessed (terminal), etc.

Netflix uses React to render to TVs.

Decouple from the DOM. Describe the UI and render wherever it makes sense.

This is the same thinking that underlies React Native.

He poked at Ember a bit.

With Ember, it's complex to understand the side effects of setting a property on an object.

If you're setting two properties, it might end up executing the same block of code twice. You can't batch the changes.

He doesn't like Object.observe. He says it makes it hard to know what's going to happen when you make changes to state.

Two important questions:

  1. What state is there?
  2. When does it change?

He likes setState more than the KVO paradigm (i.e. Object.observe).


  • One object contains state.
  • Imperative, intent is obvious.
  • Easy to grep.

React inserts a virtual DOM between the view logic and the DOM.

This lets you delegate a lot of responsibilities to the framework. The framework can handle a lot of optimizations. You can also introduce new render targets.

Most tech companies have web, iOS, and Android teams that are all mostly separate.

He recommends structuring teams around feature verticals instead of technologies.

He gave a plus for React Native.

Architecting Modern JavaScript Applications

He's one of the Meteor developers.

Meteor is a full stack framework. In encompasses both the frontend and the backend. It's really quite impressive what it can do and how far ahead of other stacks it really is.

He wants to talk about the "connected client" architecture.

He used UBER as an example. You can look at a map and watch all the cars move around in realtime.

Move from websites to apps.

The main driver for this is mobile.


  • Stateful: There's a stateful server with a connection to the client (WebSockets or XHRs)
  • Publish / subscribe
  • Data: What goes over the wire is data, not presentation

He has mentioned multiple times that the server needs to be able to push data to the client.

The architecture for these modern apps is really different.

We've seen major shifts in how software is built before:

Mainframe => PC => Web => Connected client

Connected client:

  • Stateful clients and servers with a persistent network connections (WebSockets) and data cached on the client.
  • Reactive architecture where data is pushed to clients in real time.
  • There's code running on the client and in the cloud. The app spans the network.

You need to cache things on the client in order to get any kind of performance. Hence, the server needs to know what's on the clients.

You have to be able to push code changes.

We have to move away from stateless, share nothing, horizontally scalable architectures.

Each part should "reactively" react to changes in state.

You have to have the same team working on a feature on the client and on the server.

However, you can still have separate teams for separate microservices.

"JavaScript is the only reasonable language for cross-platform app development."

That's because it runs everywhere you need it to run.

He says JavaScript is better than cross-compiling from languages like Java.

He gave a plug for ES 2015.

You can transition to ES 2015 gradually.

He likes ES 2015 classes.

He showed how ES 2015 code made the code much nicer and shorter.

Sass seems to be more popular than Less.

He talked about Reactivity.

He wants more than what Angular or React can provide. He wants reactivity across the whole stack.

With Meteor, you can be notified of changes in your datastore so that you can update your UI. (That's impressive. I've seen the Android guys do that, and the Firebase guys do that, but I haven't seen many other people do it.)

He's very pro-WebSockets. Use an XHR if they're not available.

He doesn't use REST. You publish/subscribe with live data.

He talked about Facebook's Relay Store, GraphQL, etc.

DevOps is different when you have connected clients.

He talked about something called Galaxy.

You need stable sessions. I.e. when a client reconnects, they must reconnect to the same server.

He talked about reactive architectures for container orchestration.

He plugged Kubernetes and Marathon (Mesos).

You have to update the version of the software on the client and the server at the same time.

He showed how he dealt with deploying new versions of the software. It's complicated.

Meteor is an open-source connected client platform. It simplifies a ton of stuff.

Building Web Sites that Work Everywhere

Doris Chen @doristchen from Microsoft.

She is going to talk about polyfills and Modernizer.

Edge is the default browser in Windows 10.

Edge removes as much IE-specific code as possible and implements as much support for cross-browser stuff as possible.

Testing tools:

  • Site Scan: Free
  • Browser screenshots: Free
  • Windows virtual machines: dev.modern.ie/tools/vms/windows
  • BrowserStack: Paid

http://dev.modern.ie/tools is Edge's developer site. It's pretty neat. It gives you a bunch of warnings for when you're doing things that don't have cross-browser support.

She keeps skipping Chrome in a lot of her slides ;)

I think she said stuff for CSS3 needs prefixing.

Autoprefixer is a postprocessor that automatically adds CSS prefixes as necessary.

You can integrate this using Grunt.

Browser detection (using the version string to decide what your code should do) just doesn't work.

All the browsers have User Agent strings that mimic each other. They embed substrings of the other browsers.

Instead use feature detection.

IE browser detection is going to be broken in Edge since it doesn't support the older IE ways of doing things.

Modernizr is the best tool to use for feature detection.

It also has polyfills to keep older browsers supported.

Edge's dev tools are called F12 Tools.

She talked about polyfills.

MP3 is supported in all the browsers.

H.264 (MPEG-4) is supported in all the browsers.

Browsers won't render elements they don't understand (such as video tags), but they will fallback to rendering the stuff inside the tag.

She called Silverlight "legacy", and said people should move away from using any plugins.

She disables Flash as well as all other plugins.

She talked about using Fiddler to modify requests and responses.

She used it to manually change some Flash video to HTML5 video by looking at the MP4 the Flash code was playing (it was an argument to the Flash player).

Edge has an emulation mode to emulate older versions of IE.

Evolution of JavaScript

The story of how the "glue of the internet" became the world's most popular programming language.

His view of the history of JavaScript was, unfortunately, somewhat flawed...Actually, it was very, very flawed.

I left early along with some other people.

WebGL: The Next Generation

Tony Parisi.


WebGL is everywhere. It runs generally the same everywhere.

It started in 2006 at Mozilla.

It's OpenGL but built to work the way the web works.

It has very low-level drawing primitives.

No file format, no markup language, no DOM.

Libraries and frameworks are key to ramping up quickly and being productive.

If you use the base API, it takes a 300 line program to make a cube that spins in space with an image on each face.

three.js is the most popular WebGL library. It's very well done.

WebGL 2 is a major upgrade based on OpenGL ES 3.0. It was introduced earlier this year.

Unity can cross-compile from C++ to JavaScript using Emscripten.

WebGL 2 has lots of features that allow you to get low-level efficiency gains.

It has deferred rendering. It enables you to have tons of light sources.

WebVR is virtual reality in the browser.

The world of VR is moving very quickly.

Firefox and Chrome have VR working in the browser.

Head tracking is part of VR.

So is stereo view mode.

Firefox and Chrome can attach to VR devices.

You have to update the head tracking position at 70-90 Hz to avoid motion sickness.

HMD = head mounted display

He talked about Google Cardboard. It's not as good as the professional stuff, but it's still pretty neat.

Browsers have an accelerometer API.

glTF is a web-friendly 3D file format for use with WebGL. It's a "JPEG for 3D".

He wrote the glTF loader for three.js.

FBX is a fairly standard proprietary format. There's an FBX to glTF converter.

He wrote "Learning Virtual Reality" along with two other O'Reilly books related to WebGL, etc.

He has an Oculus Rift DK2 headset. You can buy it on their website.

Firebase: Makes IoT Prototyping Fun

This was one of my favorite talks because it was so simple and yet so inspiring.

Jenny Tong @MimmingCodes

She gave a brief intro to some simple EE topics.

0V = ground

PWM = pulse width modulation

10k ohm resistors are the only resistors you need to worry about right now.

The longer foot of an LED goes to high voltage, and the other foot goes to ground.

She's working with voltages in the range of 0 to 5.

Arduino Unos are simple, durable, and inexpensive. Keep in mind there is no OS. Your code runs directly on the metal.

A Raspberry Pi is a tiny computer. It usually runs Linux.

Instead of doing things mostly in hardware or in C, she tries to make it so you can do things in JavaScript.

Her standard recipe is:

  • Arduino Uno
  • Johnny-Five: a NodeJS library for interacting with hardware stuff
  • Raspberry Pi (or laptop): for talking to the internet
  • Firebase (she's a developer advocate for Google Cloud)

Johnny-Five is very versatile and has great documentation. It has images that walk you through various projects.

Firebase has a realtime database. You can think of it as a giant ball of JSON in the sky. You can create a listener in your JavaScript code to listen for changes to the database.

http://wherebus.firebaseapp.com is a cool example.

The "hello world" of IoT is creating a button that changes something on the Internet. During her talk, she created a button that controlled a real light. The light responded to changes in the data in her Firebase database.

Arduino has a bridge called Firmata that can be used to connect Johnny-Five to your Arduino.

She started wiring things together using a breadboard:

Red = high
Brown = low

She started with some JavaScript to make an LED blink.

A pull down resister (10k ohm) connected to ground gives the electrons a place to go when the circuit would otherwise be open (i.e. not connected).

She integrated Firebase really quickly.

You can use APPNAME.firebaseio-demo.com/TABLE as a Firebase DB without even signing up. However, keep in mind that so can everyone else.

You can go to the Firebase URL to get a web view of the data. Change the data there, and it gets pushed into the JavaScript code, which controls the board.

It's really easy to prototype cool things with real hardware, JavaScript, and Internet connectivity.

When you are learning how to build this stuff, these things will catch on fire sometimes. That's okay. Keep a fire extinguisher on hand ;)


You can buy a bunch of cool hardware from Adafruit.

Upgrade your JavaScript to ES2015

David Greenspan (Meteor Development Group).

The speaker takes a very conservative approach to new browser features. In the talk, he gave an overview of whether using ECMAScript5 features via transpiling with Babel is a prudent thing to do.

He started in 2007 with IE 6 (Firefox 1.5, Safari 2, no Chrome).

Meteor dropped IE 6 in 2013.

IE 7 still couldn't garbage-collect cycles between JavaScript and the DOM. [I remember that. I sure am glad they fixed that!]

You can enjoy ECMAScript 2015 because of Babel which is a transpiler.

ECMAScript3 -- 1999 -- IE 8-9
ECMAScript4 -- cancelled in 2008
ECMAScript5 -- 2009 -- IE 9, "modern" browsers -- just a minor update
ECMAScript6 -- 2015 -- being implemented now (aka ECMAScript 2015)

They're going to start rolling new versions annually.

Features will appear quickly in new browsers.

In 0-2 years, we'll stop caring about IE 8.

When people say "ES", they're just using it as an abbreviation for "EcmaScript".

Start using ES 2015 and transpile to ES 5 using Babel.

Babel targets ES 5. You can even get it to transpile to ES 3 if you build the right plugins.

Babel can get you a lot of the newer syntax features.

However, it can't provide all of the "engine-level" features such as efficient typed arrays, Proxy, Reflect, WeakMap, WeakSet, and proper tail call optimization.

Babel can do generators, but it's a tricky transform.

All sophisticated JS apps have a build step of some sort these days, so requiring a build step is nothing new.

Readability / debuggability of generated code isn't bad, especially with source maps.

Even just a year ago, the transpilers weren't that great. Babel has kind of won the war.

Babel is ready for production. However, you do have to follow some guidelines:

  • Use "loose" mode. It's the fastest, and it makes the best trade-offs.
  • Avoid "high-compliancy" mode.
  • Don't go nuts with experimental (ES7+) transforms.
  • Whitelist your transforms.
  • Use external helpers.
  • If you need IE 8 support, you'll need custom helpers.
Here's an ES6 class:

class TextView extends View {
constructor(text) {
this.text = text;

render() {
return super.renderText('foo');

It's just nice syntactic sugar for what you'd do anyway.

Classes are very controversial in JavaScript. However, he said that there is no significant reason not to use classes.

Arrow functions:

[1, 2, 3].map(x => x*x)

['a', 'b', 'c'].forEach((letter, i) => {
this.put(i, letter);

setTimeout(() => {
}, 1000);

"this" refers to the same thing inside and outside the function. It's not broken for nested functions.

Use arrow functions.

Block-scoped variable declarations: let and const

The difference between let and var is that var is function scoped, but let is block scoped.

const is like final. It just says that the variable can't be reassigned. That doesn't mean that the thing the const points to isn't mutable.

Switch from var to let and const. Default to using const.


import {foo, bar} from "mymodule";

export function logFoo() {

It transpiles to CommonJS.

By using transpilers, we'll always be able to try out new features before they're completely set in stone. We get the features early, and the standards bodies get some feedback on their designs. It's a win win.

Use Babel and ECMAScript 2015 today.

However, don't use engine-level features like generators, Proxy, Reflect, etc. yet.

The latest Chrome supports a lot (but not all of) ES 2015.

Proper tail call optimization is not implemented in any of the browsers yet.

ES7 and Beyond!

Jeremy Fairbank @elpapapollo

TC39 is the group responsible for the standard.

He uses React a lot.

ES6 was only standardized this year, and there's already more stuff coming down the pipeline.

Some proposed features might be coming after ES7. They call this "ES.later".

You can use those features now using Babel.

He went over what features were at what level of standardization. I didn't get a chance to write down the exact meaning of each of the stages, but the smaller the stage number, the closer it is to being in the standard.

Remember, nothing in this talk has been fully standardized yet.

At stage 1:


class Person {
get fullName() {

function enumerable(target, name, descriptor) {
descriptor.enumerable = true;
return descriptor;

Decorators can take arguments.

Decorators can work on classes as well. You can use this to create a mixin @decorator.

At stage 2:

Object rest and spread.

// Rest
const obj = { a: 42, b: 'foo', c: 5, d: 'bar' };

// Save the "a" and "b" attributes into the variables named
// "a" and "b", and save the rest of the attributes into an
// object named "rest".
const { a, b, ...rest } = obj;

// Spread
const obj = { x: 42, y: 100 };

// Add all of the attributes from obj inline into the current
// object. In "obj" has a "z" attribute, it'll override the
// earlier "z".
const newObj = { z: 5, ...obj };

// If "obj" has an "x" attribute, it'll be overriden by the
// "x" that comes after it.
const otherObj = { ...obj, x: 13 };

These are both just transpiled to Object.assign.

Here's a nice example of their use:

function createDog(options) {
const defaults = { a: "Some default", b: "Some default" };

return { ...defaults, ...options };

Be careful, this is not a deep clone.

At stage 3:

Async functions. These provide synchronous-like syntax for asynchronous code.

Prepend the function with "async". Use the "await" operator on a promise to obtain a fulfilled promise value.

async function fetchCustomerNameForOrder(orderId) {
let order, customer;

try {
order = await fetchOrder(orderId);

} catch(err) {
throw err;

try {
customer = await fetchCustomer(order.customerId);
return customer.name;
} catch(err) {
throw err;

Await awaits a promise and obtains the fulfilled value. It's non-blocking under the covers.

It takes a lot of work to transpile async / await code into ES5 code.

Babel has a REPL that you can use to see how it transpiles things.

Here's how to make requests in parallel:

const orders = await Promise.all(
orderIds.map(id => fetchOrder(id))

You should prefer making a bunch of requests in parallel rather than making them sequentially.

Sometimes you have to do things sequentially because of the business logic. You have to get one thing before you know what the next thing you need is.

Async functions let you use the language's native flow control constructs like for...of, try/catch. The problem with promises is that you can't easily use things like try/catch.

There are many other upcoming features in various stages:

SIMD: single instruction, multiple data.



See: https://github.com/tc39/ecma262

To get every possible crazy feature, use babel --stage 0 myAwesomeES7code.js. However, keep in mind that if the standard goes in a different direction, your code is going to break.


Thursday, September 24, 2015

Android vs. iOS from a User's Perspective

I've been an Android user for several years. I have also written Android apps. About 9 months ago, I decided to switch to iOS in order to learn how to do iPhone development.

You might be wondering what I think of iOS after switching. Ok, you probably weren't wondering, but I'm going to tell you anyway. I think it doesn't really matter very much. There are huge differences when it comes to developing for Android or iOS, but when it comes to usage, not so much.

Sure, there are differences between the OSs. Each has a few features that the other doesn't have. But how do they impact my life? Pretty much all of the apps I personally care about are on both platforms. There's a huge difference between having a modern smartphone and not having one. However, I think the choice of which one to have isn't really that significant.

The vicious cycle of co-dependent attention slavery

Don't you ever get tired of everyone in the world demanding your attention?

It's like we're caught up in some vicious cycle of co-dependent attention slavery. There are a million apps and companies notifying you all the time that you have to pay attention to them. If it isn't a notification, it's an email. You spend countless wasted minutes every day clearing these notifications and dealing with these emails.

On the other hand, companies are desperate to get your attention. They track things like monthly active users, views, likes, etc. The financial success of various companies is directly connected to how many users they can get to log into their products, and how often they can get them to log in. Furthermore, a linear growth in usage is not acceptable. Everyone wants a hockey stick of exponential growth.

Yes, I'll admit the hypocracy in my complaining about this considering I worked in developer relations for two years, and I worked at a social media company for another two years. Permit me to have a Jerry Maguire moment. Stop! What can we do to break this cycle of co-dependency? If these apps are so smart, why do I have to babysit them all the time? Why does my leisure not feel leisurely anymore? How do we make the pain stop?

Saturday, September 05, 2015

I think I need some career advice

I left Twitter several weeks ago. It looks like I need to not only decide where I want to work next, I might also need to decide what I want to specialize in as a programmer. Apparently, there's less and less demand for full-stack web developers or generalists. Most open positions are for specialists.

I've always been a polyglot. I really like learning new languages. Even though I'm mostly a Python expert, I love to learn as many new languages as possible. For instance, I accomplished the following just while I was at Twitter:

  • I built a custom supply chain management system in Python.
  • I technical edited two Scala books.
  • I learned Go fairly well.
  • I learned Android at a beginner to intermediate level.
  • I learned Objective-C and iOS at a beginner to intermediate level.

Another thing that sets me apart from most programmers is that I'm a friendly extrovert, and I like giving talks. Given the above, developer relations is a natural fit for me. I did that for two years at Google.

However, it seems like that's not enough these days. It seems like most companies and most recruiters are really only looking for specialists. It seems like these are the specialties I could conceivably go after:

  • Ruby backend programmer
  • Go backend programmer
  • Scala backend programmer
  • Developer relations (mentioned above)
  • Frontend developer (JavaScript, Angular, React, etc.)
  • Distributed systems engineer (cloud computing, AWS specialist, etc.)
  • SRE
  • DevOps engineer
  • Data scientist (machine learning, big data, etc.)
  • Hadoop specialist
  • Android engineer
  • iOS engineer
  • Software engineer in biotech
  • Contractor or consultant

As I mentioned above, I know lots of languages, including Python, Ruby, Go, and Scala. I know JavaScript and some frontend development (at least using the old-school approaches). I know Java and some Android programming. I know Objective-C and some iOS programming. However, aside from Python, I am not an expert in any of these things.

Developer relations is fun, but I'm not sure it's a good idea to bank my entire future on it.

Distributed systems, cloud computing, AWS, SRE work, DevOps, etc. are all interesting to me. However, I'm not sure I can convince anyone to give me a job doing these things. Furthermore, I'm also not sure these things are the right thing to bet my career on. On the other hand, I'm a lot more interested in cloud computing than, say, frontend work.

I have an interview at a biotech company. That could be promising. That could be really good for my career, or a dead end for my career. I'm not sure.

I'm reluctant to become a contractor or consultant. It seems to me that once you become a consultant as an older programmer, it becomes very hard to get hired as a normal engineer at many companies. One of my buddies is a brilliant older programmer (UNIX®, MIT AI lab, various wireless hardware and software systems, etc.) but companies like Google won't hire him anymore. I think being a contractor or consultant has a lot of pros and a lot of cons. I can't even wrap my head around whether or not it's a good idea to start doing.

I suspect one benefit of being a specialist is that it makes interviewing easier. If you only have to know a particular field really well, it's not that hard. In contrast, I read Python Weekly, Ruby Weekly, Go Weekly, Scala Weekly, JavaScript Weekly, HTML5 Weekly, etc. Trying to keep up with so many areas means that I can't delve too deeply into any of them aside from Python.

Furthermore, I've noticed that the fewer people have a skill, the easier it is to get the job. For instance, it used to be really easy to get jobs because I knew Python and whatever Python web framework happened to be popular at the time. These days, everyone knows Python, so it's really no help at all.

What's certainly true is that interviews are getting much tougher! Every time I have to interview, I'm fighting against the best and brightest students from all over the world. They're mentally quicker than me, willing to work more overtime, and they cost a lot less. Furthermore, now that Python has become so ubiquitous at Universities, this battle is more fierce than ever. Furthermore, the amount of code companies expect you to be able to write in an interview is getting harder and harder.

On top of all of that, I think the cards are institutionally stacked against more senior engineers. I saw three principal engineers interview at my previous company. Two of them were buddies of mine, so I knew they were really good. That company turned down all three of them.

Some companies have also resorted to using timed programming tests like HackerRank. I like the fact that HackerRank is an objective measurement of a candidate's skills. However, it favors the young since it requires lightning quick thinking and ignores all of the other skills a more seasoned engineer has learned such as testing, design, scalability, requirements gathering, teamwork, agile, code review etiquette, etc.

Furthermore, anytime someone gives me a timed programming test, I completely fall apart. Usually, to be successful, you have to be creative enough to come up with an elegant (i.e. efficient) solution. However, having a gun put to your head is the enemy of creativity. I've been getting better by practicing at LeetCode, but I'll probably never be as good as a bright Russian kid who's been training for programming competitions for years.

The next problem is that the more companies you've worked for, the more hiring managers question whether you're a problematic employee. 2 years at Google right after college? You must be awesome! 2 years at Google, 2 years at Twitter, and 13 other startups? There must be something wrong with you! Forget about the fact that most of those companies don't even exist anymore ;)

The last challenge I'm facing is that the location of my house in Concord means I can really only work at companies in San Francisco or the East Bay. Unfortunately, the only thing harder than commuting to Mountain View (or other parts of Silicon Valley) is trying to buy a house there! Since we're in the middle of adding onto my house, I don't think we'll be moving anytime soon.

In summary, I'm pretty sure I can find my next job. What about after that? Will it keep getting harder and harder as I keep getting older, and there are more companies on my resume and more specialties? What should I do for the rest of my career? I just hit 40, and I'm wondering, am I going to keep on being able to put food on the table when I'm 50 or 60?

Finally, let me express my thanks to all of my friends who have been so supportive lately as I struggle with these questions. My buddies Ryan Larrabure, Alex Martelli, and Jarek Wilkiewicz and all my IronPort co-workers have been surprisingly encouraging. Love you guys!

Wednesday, August 05, 2015

Distributed Systems: Another Great Jeff Dean Quote

During the first year of a typical Google datacenter, there will be five rack-wide outages, three router failures large enough to require diverting processing away from connected machines, and eight network scheduled maintenance windows, half of which cause 30-minute random connectivity losses. At the same time 1 to 5 percent of all disks will die and each machine will crash at least twice (2 to 4 percent failure rate).

Dean, J. (2009), Designs, lessons and advice from building large distributed systems.

Friday, July 31, 2015

The Waterfall Model was a straw man argument from the very beginning

Over the years, I've read a lot of books on software engineering. Agile books in particular like to refute the "Waterfall Model". Every time I read about the Waterfall Model, I think to myself: I'm sure there must be companies out there that have tried this approach, but I have a hard time believing some software book would seriously propose it as the best way to write software. It must be the boogie man of software engineering methodologies.

I was reading The Practice of Cloud System Administration: Designing and Operating Large Distributed Systems, and I came across this quote:

Royce’s 1970 paper, which is credited with “inventing” the model, actually identifies it so Royce can criticize it and suggest improvements. He wrote it is “risky and invites failure” because “design iterations are never confined to the successive step.” What Royce suggests as an alternative is similar to what we now call Agile. Sadly, multiple generations of software developers have had to suffer through waterfall projects thanks to people who, we can only assume, didn’t read the entire paper (Pfeiffer 2012) [p. 175].

I think this quote lends credence to my theory that the "Waterfall Model" has been a straw man argument from the very beginning. I know that there were companies that used it, and that there are companies that still do. However, I think this proves that no one ever wrote a book that proposed that the "Waterfall Model" was the best way to write software.

Monday, July 06, 2015

Tetris Over SSH

I wanted to try out Google Compute Engine, but I wanted to build something other than a simple web app. Hence, I setup a virtual server that runs tetris when you log into it, and I gave everyone the credentials :)

$ ssh -o UserKnownHostsFile=/dev/null -o CheckHostIP=no -o StrictHostKeyChecking=no tetris@ # Password: tetris

Here's the code. I set it up so that gotetris is the login shell, and the user doesn't have permissions to modify any files. Hence, it should be relatively safe to share with the world ;)