愛と勇気と缶ビール

ふしぎとぼくらはなにをしたらよいか

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で読んだ気がするんだけど、忘れた…