// Performance probe for what wayBetter injects into X tabs. Loads tab-bridge.js, observer.js and // x-runtime.js as init scripts (like the native tab webview) into headless Chromium and measures: // script evaluation time, fetch/XHR wrapper layers and their synchronous overhead, Response clones // and large JSON.parse calls made by our code, MutationObserver callbacks / rAF / timer work // attributed to our scripts, and main-thread long tasks. The probe is the framework's // (waybetter/dev-tools/perf-probe.mjs); X's scripts, fixtures and scenarios are here. // // node scripts/perf-probe.mjs [--dir | --none] [--seconds 8] [--runs 3] [--live] // // Fixture scenarios intercept every request locally (an X-like timeline at /home and a chat page at // /i/chat/…, both with synthetic traffic). `--live` additionally opens a logged-out x.com profile // page over the network (read-only, no interaction besides scrolling). Numbers are headless Chromium, // not WebView2; compare runs on the same machine only. import { readFile } from 'node:fs/promises'; import path from 'node:path'; import { chromium } from 'playwright'; import { runPerfProbe } from '../../../waybetter/dev-tools/perf-probe.mjs'; const args = process.argv.slice(2); const flag = name => args.includes(name); const option = (name, fallback) => { const i = args.indexOf(name); return i >= 0 ? args[i + 1] : fallback; }; const dir = option('--dir', path.resolve(import.meta.dirname, '../src-tauri')); const none = flag('--none'); const seconds = Number(option('--seconds', '8')); const live = flag('--live'); const liveUrl = option('--url', 'https://x.com/NASA'); const runs = Number(option('--runs', '3')); const scripts = none ? [] : await Promise.all(['tab-bridge', 'observer', 'x-runtime'].map(async name => ({ // The tab bridge is the framework's (waybetter-host); the other two are this app's build outputs. name, code: await readFile(name === 'tab-bridge' ? path.resolve(import.meta.dirname, '../../../waybetter/crates/waybetter-host/tab-bridge.js') : path.join(dir, `${name}.js`), 'utf8'), }))); // ---------------------------------------------------------------------------------------- fixtures const NAV = `

`; const SIM_COMMON = ` const sleep = ms => new Promise(r => setTimeout(r, ms)); const traffic = () => { fetch('https://abs.twimg.com/responsive-web/client-web/vendor.wasm').then(r => r.arrayBuffer()).catch(() => {}); fetch('https://pbs.twimg.com/media/Fabc.jpg?name=small').then(r => r.blob()).catch(() => {}); fetch('/i/api/1.1/jot/client_event.json', { method: 'POST', body: 'log=%5B%5D' }).catch(() => {}); const x = new XMLHttpRequest(); x.open('GET', '/i/api/2/badge_count/badge_count.json'); x.send(); };`; const TIMELINE_SIM = `${SIM_COMMON} let n = 1800000000000000000n; const col = document.getElementById('tl'); function article() { const id = String(n++); const a = document.createElement('article'); a.setAttribute('data-testid', 'tweet'); a.innerHTML = '
Jack
' + '
Post number ' + id + ' with some text that goes on for a while
' + '
' + '
' + '99K
'; return a; } for (let i = 0; i < 20; i++) col.appendChild(article()); setInterval(() => { col.appendChild(article()); if (col.children.length > 25) col.firstElementChild.remove(); const spans = col.querySelectorAll('[data-testid="like"] span'); const s = spans[(Math.random() * spans.length) | 0]; if (s) s.firstChild.nodeValue = String((Math.random() * 99) | 0) + 'K'; window.scrollBy(0, 30); }, 60); setInterval(() => fetch('/i/api/graphql/abc123/HomeTimeline?variables=%7B%22count%22%3A20%7D&features=%7B%7D').then(r => r.json()).catch(() => {}), 400); setInterval(traffic, 120);`; const CHAT_SIM = `${SIM_COMMON} const list = document.getElementById('msgs'); let m = 0; setInterval(() => { const d = document.createElement('div'); d.setAttribute('data-testid', 'messageEntry'); d.innerHTML = '
message ' + (m++) + ' from a friend
'; list.appendChild(d); if (list.children.length > 60) list.firstElementChild.remove(); }, 50); setInterval(() => fetch('/i/api/graphql/zz9/GetConversationPage?variables=%7B%7D').then(r => r.json()).catch(() => {}), 250); setInterval(() => fetch('https://abs.twimg.com/responsive-web/client-web/chat-crypto.wasm').then(r => r.arrayBuffer()).catch(() => {}), 200); setInterval(traffic, 120);`; const timelineHtml = `Home / X
${NAV}
For you
Following
`; const chatHtml = `Chat / X
${NAV}
`; function timelineJson() { const entries = []; for (let i = 0; i < 40; i++) { const id = String(1900000000000000000n + BigInt(i)); entries.push({ entryId: `tweet-${id}`, content: { itemContent: { tweet_results: { result: { __typename: 'Tweet', rest_id: id, core: { user_results: { result: { rest_id: '12', legacy: { screen_name: 'jack', name: 'Jack', description: 'x'.repeat(200), url: null } } } }, legacy: { full_text: 'lorem ipsum '.repeat(40), extended_entities: { media: [{ type: 'photo', media_url_https: `https://pbs.twimg.com/media/A${i}.jpg` }] } }, } } } } }); } const body = JSON.stringify({ data: { home: { home_timeline_urt: { instructions: [{ type: 'TimelineAddEntries', entries }] } } }, pad: 'p'.repeat(250_000) }); return body; } const TIMELINE_JSON = timelineJson(); const WASM = Buffer.alloc(2 * 1024 * 1024, 7); async function routeAll(context) { await context.route('**/*', route => { const url = new URL(route.request().url()); if (url.hostname === 'abs.twimg.com' && url.pathname.endsWith('.wasm')) return route.fulfill({ status: 200, contentType: 'application/wasm', body: WASM }); if (url.hostname === 'abs.twimg.com') return route.fulfill({ status: 200, contentType: 'image/x-icon', body: Buffer.alloc(64) }); if (url.hostname === 'pbs.twimg.com') return route.fulfill({ status: 200, contentType: 'image/jpeg', body: Buffer.alloc(40_000, 1) }); if (url.origin !== 'https://x.com') return route.abort(); if (/\/HomeTimeline$/.test(url.pathname)) return route.fulfill({ status: 200, contentType: 'application/json', body: TIMELINE_JSON }); if (url.pathname.startsWith('/i/api/')) return route.fulfill({ status: 200, contentType: 'application/json', body: '{"ok":true,"data":{}}' }); return route.fulfill({ status: 200, contentType: 'text/html', body: url.pathname.startsWith('/i/chat') ? chatHtml : timelineHtml }); }); } // x.com answers headless Chromium with 403 (bot protection); the live scenario only works where it is served. const results = await runPerfProbe({ chromium, scripts, seconds, runs, scenarios: [ { name: 'fixture /home', url: 'https://x.com/home', route: routeAll }, { name: 'fixture /i/chat', url: 'https://x.com/i/chat/123-456', route: routeAll }, ...(live ? [{ name: `live ${liveUrl}`, url: liveUrl, scroll: true }] : []), ], }); console.log(JSON.stringify({ build: none ? 'none' : dir, seconds, results }, null, 2));