Browserboard Update: Everything Is Faster.

I went into this weekend telling myself I would take it easy. And I think it's fair to say I did—I spent the best parts of Saturday biking around the city. But then I came home and wrote some code for Browserboard. I wanted a break from adding features to the whiteboard itself, so instead I worked mostly on performance and the landing page.

Summary: pages load faster, panning is faster, your boards are paginated, and when you click the “new board” button, the name field is auto-focused so you don't need to click it.


tl;dr computer go brrrrr

Every line you draw and shape you place in Browserboard ends up as a unique HTML element. If you draw 5,000 lines, there are 5,000 Canvas elements on the page. Modern web browsers handle this surprisingly well; there's at least one board that has over 5,000 events. Those people managed to draw 5,000 lines (and text boxes, and shapes, etc).

Faster page loads

That huge board took 5+ minutes to load. That's because Browserboard has been replaying the entire event log on every page load. So if you drew a line, erased part of the line, undid the erase, and erased again, Browserboard would retrace all those steps, instead of just drawing the line in its final state. If you do a lot of undoing and erasing, Browserboard could be doing ten times more work than is necessary.

That's fixed now. The board that took 5+ minutes to load now takes less than 30 seconds, and most of that is waiting for network requests. Browserboard only draws the final state of each shape.


Panning around that 5,000-object board was pretty choppy.

When you pan and zoom in Browserboard, it simply updates the CSS transform of the parent element of all the shapes. This approach keeps things simple in the code, but it makes the browser do more work; my understanding is the browser keeps re-rendering all these elements to a parent texture on each update, which is very expensive.

To improve the situation, I added a very basic optimization that video game developers have been using since the invention of video games: I started marking offscreen objects as hidden, simply setting style.display = "none". Visibility is recomputed only after the mouse lifts or the zoom level changes, so when you're panning, the browser doesn't need to redraw anything. You'll see some pop-in, but it's much better than panning at 1.5 frames per second.

There's a lot more I can do here. I should probably try removing offscreen objects from the DOM tree completely, and also transform each element individually instead of transforming a parent element. This approach made a huge difference back when I worked on Buildy. But panning performance is “fine” now, so I don't think I'll look into that for a while.

Thumbnail size limit

When I started making boards save thumbnail images for easier browsing on your dashboard, I had them simply render the entire board contents to an image and then scale that down to a small size. This took multiple seconds on the 5,000-shape board, which is a real problem because JavaScript in a web browser can't run outside the UI thread and still have access to the DOM. Long thumbnail render times will affect user experience. So I simply clipped the thumbnail size to something reasonable, which should keep thumbnail render times under 50 milliseconds.

These are good problems

New products often hit this awkward stage where people like using them just enough to feed them more data than they can really handle. I was waiting for this moment before investing deeply in performance; after all, if nobody uses the app, great performance benefits no one. From now on, I'll keep an eye on it.

A few minor features for logged-in users

  1. When you're logged in, your list of whiteboards shows 16 per page, instead of all your boards at once. Please email if you need more features on this screen.
  2. The “+ new” button will focus the whiteboard name field immediately, so you don't need to click it to set a name. You can just start typing and press Enter.
  3. You'll see a list of recent site updates below your boards. I thought it was impolite of me to only show the changelog to logged-out users. You can also sign up for the newsletter and get updates like the one you're reading right now! But I suppose you know that if you're reading this update.

New landing page

The old landing page was meant to be endearingly rough, to reflect the minimalistic and personal nature of the app. I'll share some old images here for posterity:

some very ugly screenshots

I've added and improved Browserboard a lot since I made that page. I also bought a cheap Wacom tablet, and while it doesn't improve my drawing skills, it does make it more fun to draw on a computer. So I spent today reinvisioning, writing the HTML, and drawing some new boards to show in screenshots.

screenshot of the top of the new landing page

more nice images

The new landing page does a much better job of explaining what Browserboard can do and how it benefits different kinds of people. It's still pretty rough, but at least there's much more meaningful content that I hope will improve Browserboard's search engine ranking and help people decide whether it's worth a try.

What's next, other notes

There's one tiny new feature that nobody but me cares about: I wrote tools that let me export boards as JSON files and import them into my local development environment. I only do this with permission, to help diagnose problems with specific boards. It means I can mess around with a buggy whiteboard without trampling someone's live data.

Next, I'm thinking about how to make sharing more granular. A few people have requested the power to limit guests' ability to clear the whole board, which is very important when drawing with kids. Rather than bolt it on thoughtlessly like I've done with so many things, I want to reimagine how Browserboard thinks about user permissions, and see if I can give the owner more settings in the actual whiteboard view, rather than hiding settings on a completely separate page. It's probably more than one weekend of work, unfortunately, so I'll try to find something else to do next weekend as well.