

Hacking Twitter's Javascript - jazzychad
http://blog.jazzychad.net/2011/03/27/hacking-twitters-javascript.html

======
simonw
"Basically, there is a timer that fires every 2 seconds to update timestamps,
but each time it fires, it only updates timestamps that end in a certain
number, starting at 0 and going up to 9 then repeating. So every 20 seconds
all the timestamps update themselves. This is the weirdest thing I have ever
seen"

Sounds like a performance optimisation to me. Having all of the timestamps
update in one go could block the JavaScript thread for a non-trivial amount of
time, making Twitter feel less responsive. This is a neat way of spreading
that CPU intensive operation over 20 seconds, leaving gaps for other tasks to
run. I imagine they use similar tricks in other places as well.

~~~
jazzychad
That was my second thought as well. But if you look at the selector

    
    
        $find("._timestamp[data-time$=" + E + "000]")
    

surely running this regex-find on DOM elements is not such a savings on
performance?

It also has the weird side-effect that some tweets can look older than the
tweets below them, making the ordering look incorrect. Meh, not really a big
deal, but I was glad to have finally figured out what was really going on
there.

~~~
mgkimsal
The DOM performance hit is probably smaller than the network hit (both on the
client and at the server side) for doing all at once (if I'm understanding it
correctly).

~~~
jazzychad
It's all done client-side, so in this case there is no network hit for doing
the timestamp updates anyway.

------
loganlinn
Interesting method to getting current timestamp:

    
    
      var I = +new Date;
    

I've always used:

    
    
      var I = (new Date).getTime();

~~~
russ
They're the same, +new Date doing an implicit cast to number. I prefer getTime
as well for its clarity.

~~~
shazow
I benchmarked all the variations on Chrome, var foo = +new Date() was the
fastest—not by a huge amount than the rest, but I remember there was one
approach that was especially slow.

I did this while optimizing performance of a fast-paced game in Javascript
(LineRage). Profiling showed that getting timestamps was responsible for
significant portion of the processing time. I also ended up switching to a
global clock approach.

Unfortunately I no longer have the original benchmark code/results. Would be
happy to have someone replicate it.

------
kwamenum86
regarding the timestamp performance optimization, seems like the more robust
solution is using setTimeout to avoid blocking the main thread with timestamp
updating. basically you perform updates on a set amount of nodes and then
defer the updates for the rest using setTimeout. This scales to any number of
DOM nodes but the solution outlined in this post works for the vast majority
of use cases.

~~~
altano
setTimeout does not run in a background thread that can be parallelized. There
is no "main thread" vs. "background threads." If you write an endless loop in
a setTimeout callback, none of your other JS will ever run. You can easily
test this:

setInterval(function(){ console.log("hi"); }, 500); setTimeout(function(){
while(true) { console.log("no more hi"); } }, 100);

~~~
spullara
Why wouldn't you use a setTimeout per timestamp set to go off a bit after the
next time it should be updated? Seems like that would have a spread
distribution and would also minimize the amount of work done.

~~~
kwamenum86
Not per timestamp. Per x timestamps. For example, update 80 timestamps in 4
batches of 20. This should perform well in all cases because we are doing a
predictable amount of work.

------
akent
Great work but why not just contact Twitter directly and ask them to directly
integrate your bugfixes?

~~~
jazzychad
If only 'twere so easy.

