<!DOCTYPE html>
<style>
.container {
margin: 4px;
display: inline-block;
border: 1px solid blue;
}
.vscroller {
overflow-y: overlay;
max-height: 300px;
border: 2px solid black;
padding: 2px;
background-color: white;
}
.item-container {
display: flex;
flex-direction: column;
justify-content: start;
contain: paint;
}
.item {
font-size: 18px;
flex: 0;
margin: 1px 0;
}
</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 observed list items.
const numItems = 100000;
// How many levels of DOM hierarchy between the scrolling root and list items.
const containerDepth = 100;
// How far to scroll on each frame.
const velocity = 1000;
let scroller = document.createElement('div');
scroller.classList.add('vscroller');
document.body.appendChild(scroller);
let parent = scroller;
for (let i = 0; i < containerDepth; i++) {
let container = document.createElement('div');
container.classList.add('container');
parent.appendChild(container);
parent = container;
}
let itemContainer = document.createElement('div');
itemContainer.classList.add('item-container');
parent.appendChild(itemContainer);
parent = itemContainer;
let observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.intersectionRatio > 0) {
entry.target.classList.add('visible');
} else {
entry.target.classList.remove('visible');
}
});
}, { root: scroller });
for (let i = 0; i < numItems; i++) {
let item = document.createElement('div');
item.classList.add('item');
parent.appendChild(item);
item.innerText = generateChromeClassName();
observer.observe(item);
}
PerfTestRunner.measureFrameTime({
description: 'Frame time with one IntersectionObserver with a scrolling root element, observing many items.',
tracingCategories: 'blink',
traceEventsToMeasure: ['LocalFrameView::UpdateViewportIntersectionsForSubtree'],
setup: () => {
let max_scroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = (scroller.scrollTop + velocity) % max_scroll;
if (generateProfile && self.chrome && chrome.gpuBenchmarking) {
chrome.gpuBenchmarking.startProfiling('perf.data');
}
},
run: () => {},
done: () => {
if (generateProfile && self.chrome && chrome.gpuBenchmarking) {
chrome.gpuBenchmarking.stopProfiling();
}
}
});
</script>