<!DOCTYPE html>
<style>
body {
display: flex;
flex-wrap: wrap;
}
div {
position: relative;
padding: 2px;
border: 1px solid black;
min-width: 10px;
min-height: 10px;
}
</style>
<body></body>
<script src='../resources/runner.js'></script>
<script src='../resources/generate-chrome-class-name.js'></script>
<script>
// To generate profile data for analysis with pprof, set generateProfile to
// 'true' and run chrome with "--enable-gpu-benchmarking --no-sandbox".
const generateProfile = false;
// How many targets.
const breadth = 32;
// How many levels of DOM hierarchy above each target.
const depth = 16;
// How many observers.
const redundancy = 1000;
// The total number of observations is breadth * redundancy.
function populate(level) {
let div = document.createElement('div');
if (level == 0) {
div.classList = ['leaf'];
} else {
let child = populate(level - 1);
div.appendChild(child);
}
return div;
}
for (let i = 0; i < breadth; i++) {
document.body.appendChild(populate(depth));
}
for (let i = 0; i < redundancy; i++) {
let observer = new IntersectionObserver(() => {});
document.querySelectorAll('.leaf').forEach((target) => { observer.observe(target) });
}
PerfTestRunner.measureFrameTime({
description: 'Frame time with lots of intersection observers in a deep layer tree.',
tracingCategories: 'blink',
traceEventsToMeasure: ['LocalFrameView::UpdateViewportIntersectionsForSubtree'],
setup: () => {
document.querySelectorAll('.leaf').forEach(leaf => {
leaf.innerText = generateChromeClassName();
});
// Force layout so that layout cost isn't included in measured time.
document.querySelector('.leaf').offsetTop;
if (window.internals)
internals.clearGeometryMapperCache();
if (generateProfile && self.chrome && chrome.gpuBenchmarking) {
chrome.gpuBenchmarking.startProfiling('perf.data');
}
},
run: () => {},
done: () => {
if (generateProfile && self.chrome && chrome.gpuBenchmarking) {
chrome.gpuBenchmarking.stopProfiling();
}
}
});
</script>