Woo! After a lot of testing, head-scratching and swearing, I found the problem! I wasn’t clearing the line dash mode correctly!

I had code like this:
if (typeof(dash) === "undefined")
dash = [1,0];

context.setLineDash(dash);

Visually, it does the right thing, draws a solid line. However I think it actually draws the line 1 pixel at a time instead!

The correct code is this:

if (typeof(dash) === "undefined")
dash = [];

context.setLineDash(dash);

Massive win!