mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 16:02:26 +00:00
Replaces the scroll event listener and `getBoundingClientRect` polling with `IntersectionObserver` to eliminate layout thrashing and improve scrolling performance. - Removes `window.onscroll` handler in `docsView.js`. - Implements `IntersectionObserver` with `rootMargin` to track active headings. - Retains initial one-time scan for correct state on load. - Adds benchmark `benchmarks/docs_scroll_spy.html` and `benchmarks/docs_scroll_spy_bench.js`. Benchmark results: - Legacy: ~0.065ms/call (200 calls) -> Total ~13ms CPU (sync layout thrashing) - Optimized: ~0.028ms/call (32 calls) -> Total ~0.9ms CPU - 14x improvement in CPU time for scroll handler logic. Co-authored-by: PR0M3TH3AN <[email protected]>
83 lines
2.2 KiB
JavaScript
83 lines
2.2 KiB
JavaScript
import { chromium } from 'playwright';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
(async () => {
|
|
const browser = await chromium.launch();
|
|
const page = await browser.newPage();
|
|
const filePath = `file://${path.join(__dirname, 'docs_scroll_spy.html')}`;
|
|
|
|
console.log(`Loading ${filePath}`);
|
|
await page.goto(filePath);
|
|
|
|
// --- LEGACY ---
|
|
console.log('Running Legacy Benchmark...');
|
|
await page.evaluate(() => window.startLegacy());
|
|
|
|
await page.evaluate(async () => {
|
|
return new Promise(resolve => {
|
|
let scrollY = 0;
|
|
let steps = 0;
|
|
const maxSteps = 200;
|
|
const stepSize = 200;
|
|
function step() {
|
|
scrollY += stepSize;
|
|
window.scrollTo(0, scrollY);
|
|
steps++;
|
|
if (steps < maxSteps) {
|
|
requestAnimationFrame(step);
|
|
} else {
|
|
resolve();
|
|
}
|
|
}
|
|
step();
|
|
});
|
|
});
|
|
|
|
// Wait for RAFs to flush
|
|
await page.waitForTimeout(500);
|
|
|
|
const legacyMetrics = await page.evaluate(() => window.getMetrics());
|
|
console.log('Legacy Metrics:', legacyMetrics);
|
|
|
|
await page.evaluate(() => window.stopLegacy());
|
|
await page.evaluate(() => window.scrollTo(0, 0));
|
|
|
|
await page.waitForTimeout(1000);
|
|
|
|
// --- OPTIMIZED ---
|
|
console.log('Running Optimized Benchmark...');
|
|
await page.evaluate(() => window.startOptimized());
|
|
|
|
await page.evaluate(async () => {
|
|
return new Promise(resolve => {
|
|
let scrollY = 0;
|
|
let steps = 0;
|
|
const maxSteps = 200;
|
|
const stepSize = 200;
|
|
function step() {
|
|
scrollY += stepSize;
|
|
window.scrollTo(0, scrollY);
|
|
steps++;
|
|
if (steps < maxSteps) {
|
|
requestAnimationFrame(step);
|
|
} else {
|
|
resolve();
|
|
}
|
|
}
|
|
step();
|
|
});
|
|
});
|
|
|
|
// Wait for IO to flush
|
|
await page.waitForTimeout(500);
|
|
|
|
const optimizedMetrics = await page.evaluate(() => window.getMetrics());
|
|
console.log('Optimized Metrics:', optimizedMetrics);
|
|
|
|
await browser.close();
|
|
})();
|