Here is my follow up comment, suggesting that although Webkit, and Chrome in particular claim to have string concatenation licked, it's still a problem and can only be solved (for this real world problem) by using array joins.

Update - I'm no longer convinced the concat is the issue, though switching to the array solves the problem:

Damn, after almost being able to sleep on this, I more and more think the problem isn't the concat, but the index lookup - which is what's been already discussed. Obviously the array provides the solution because it has the native index support - whereas swapping data[i] out for data.substr(i, 1) yields almost exactly the same results ref.

Given the disparity between browsers (some way better at concat, some better at join), is one method supposed to be better in theory? i.e., did some of the vendors screw up, or did others just choose to optimize one particular routine?