JavaScriptが100ms以上実行されてると怒られるようにする
http://www.slideshare.net/nzakas/high-performance-javascript-2011
わかりやすいスライドだなー、と思いつつ。
1つのJavaScript job(わかりにくい表現だけど、event handlerとかtimerからキックされるJS code)の実行は目安として100ms以下に抑えましょう、って他のどこかでも見たことがある。要は、ユーザが何もできない && ユーザアクションが何も反映されない時間を100ms以下に抑えましょう、ということだろう。
でも50msとか100msとか数字で言われてもよくわかんないよねー、ということで。
大体の場合JS codeのキックはelementにくっつけたevent handlerか、timerのどっちかだよねー、ってことで、いささか無理くりながら50ms or 100ms以上JSが実行されてると怒られるようにできないこともないな、と思って試しに書いてみた。
function trace(callback, e) { var start = Date.now(), end; callback(e); end = Date.now(); if ( end - start > 100 ) { console.log("event handler execution: 100ms over! execution: time = " + (end - start) + ", handler = \n" + callback.toString()); } else if ( end - start > 50 ) { console.log("event handler execution: 50ms over! execution: time = " + (end - start) + ", handler = \n" + callback.toString()); } } var orig = HTMLElement.prototype.addEventListener; HTMLElement.prototype.addEventListener = function (type, callback, useCapture) { orig.call(this, type, function(e) { trace(callback, e); }, useCapture); }; ["setTimeout", "setInterval"].forEach(function(functionName) { var orig = window[functionName]; window[functionName] = function(callback, time) { orig.call(window, function() { trace(callback); }, time); }; });
ヒャッハー!既に他の誰かがやってそうなニオイがプンプンするぜぇー!
もちろんHTMLElement以外にもeventはbindできるし、他にも色々あるだろうけど、それは今回はおいとく。
ちなみにFirefoxだとHTMLElement.prototype.addEventListenerは書き換えられない。なんかその理由をどこかのblogで読んだ気がするんだけど、忘れた…