2

JavaScript 関数の単体テストを作成し、関数がブラウザーでリフローをトリガーする頻度を測定したいと考えています。次の例を考えます。

// Bad example
function foo(elements) {
    for (var i = 0; i < elements.length; i++) {
        elements[i].className = 'w' + elements[i].offsetWidth;
    }
}
// Good example
function foo(elements) {
    var widths = [];
    for (var i = 0; i < elements.length; i++) {
        widths[i] = elements[i].offsetWidth;
    }
    for (i = 0; i < elements.length; i++) {
        elements[i].className = 'w' + widths[i];
    }
}

単体テストは、すべての要素のリフローをトリガーするため、最初の例では失敗しますが、リフローをトリガーしないため、2 番目の例ではパスする必要があります。

私が望むものに近づく唯一のものは ですがmozPaintCount、リフローごとではなく、ペイントごとにのみ増加します。mozReflowCountまたはのようなものが必要ですmozRecalculateStyleCountが、どのブラウザーでも可能性のあるものは見つかりませんでした。そのようなプロパティが存在する場合、単体テストは次のようになります。

// mozReflowCount doesn’t exist, such a property is what I’m looking for
var reflowCountBefore = window.mozReflowCount;
foo(document.querySelectorAll('*'));
if (reflowCountBefore === window.mozReflowCount) {
    // passed
}
else {
    // failed
}

ブラウザーの開発者ツールを調べて、リフローまたは「強制同期レイアウト」がトリガーされた回数を手動で確認できることは知っていますが、JavaScript 単体テスト内からそのデータにアクセスする方法がわかりません。

Q: JavaScript を使用してブラウザーでリフローをカウントするにはどうすればよいですか?

4

1 に答える 1

0

最良の方法は、おそらく MutationObserver を使用することです: Mutation Observer API

そのページの例は、これをどのように実装できるかについてかなり良い概要を示しています:

// select the target node
var target = document.querySelector('#some-id');

// create an observer instance
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    console.log(mutation.type);
  });    
});

// configuration of the observer:
var config = { attributes: true, childList: true, characterData: true };

// pass in the target node, as well as the observer options
observer.observe(target, config);

// later, you can stop observing
observer.disconnect();
于 2015-09-10T12:31:03.290 に答える