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];
    }
}

第一个示例的单元测试应该失败,因为它会触发每个元素的重排,但应该通过第二个示例,因为它不会触发重排。

唯一接近我想要的东西是mozPaintCount,但它只会在每次油漆时增加,而不是在每次回流时增加。我需要类似mozReflowCountor的东西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 单元测试中访问这些数据。

问:如何通过 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 回答