Something went wrong. Try again.
Demo comparing html-over-the-wire w/ WS and SSE.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118// Test 3 — bytes on the wire, counted below TLS at the TCP proxy.//// This is where the "HTTP headers on every interaction" claim lives, and where// HTML-over-the-wire behaves very differently from JSON: the same markup// repeats, so a persistent compression context matters more than framing.//// Runs the full cross product of {narrow, fat} payload x {none, gzip, br}.
import { startServer, startProxy, sleep, table, fmtBytes } from './lib.js'import { createClient } from '../src/client.js'
const CLIENTS = Number(process.env.BYTES_CLIENTS ?? 1)const ROUNDS = Number(process.env.BYTES_ROUNDS ?? 100)
const VARIANTS = [ { name: 'ws', arch: 'ws', tls: true }, { name: 'sse+POST h2', arch: 'sse', tls: true }, { name: 'sse+POST h1', arch: 'sse', tls: true, h1: true },]const MODES = ['narrow', 'fat']const COMPRESSIONS = ['none', 'gzip', 'br']
const results = []
for (const mode of MODES) { for (const compress of COMPRESSIONS) { for (const v of VARIANTS) { const server = await startServer({ ...v, compress, mode }) const proxy = await startProxy({ targetPort: server.port, owdMs: 0 }) await sleep(200)
const clients = [] for (let i = 0; i < CLIENTS; i++) { const c = createClient({ arch: v.arch, h1: v.h1, host: '127.0.0.1', port: proxy.port, tls: v.tls, room: String(i), compress, }) await c.connect() clients.push(c) } await sleep(200)
// Reset AFTER connect+initial render: we want steady-state marginal cost, // not the one-time handshake and first paint. proxy.reset() const handshakeConns = proxy.stats.connections
await Promise.all( clients.map(async (c, idx) => { const pending = new Map() c.onPatch((nonces) => { for (const n of nonces) { const p = pending.get(n) if (p) { pending.delete(n) p() } } }) for (let r = 0; r < ROUNDS; r++) { const nonce = idx * 100000 + r + 1 const arrival = new Promise((res) => pending.set(nonce, res)) await c.dispatch({ id: idx % 200, nonce }) await Promise.race([arrival, new Promise((res) => setTimeout(res, 5000))]) } }), ) await sleep(300)
const ops = CLIENTS * ROUNDS results.push({ mode, compress, variant: v.name, up: proxy.stats.bytesUp, down: proxy.stats.bytesDown, upPerOp: proxy.stats.bytesUp / ops, downPerOp: proxy.stats.bytesDown / ops, totalPerOp: (proxy.stats.bytesUp + proxy.stats.bytesDown) / ops, newConns: proxy.stats.connections - handshakeConns, })
for (const c of clients) c.close() await sleep(150) await proxy.close() await server.stop() await sleep(300) console.error(` done ${mode}/${compress}/${v.name}`) } }}
console.log(`\n=== Test 3: bytes on the wire, per command round trip (${ROUNDS} ops) ===\n`)for (const mode of MODES) { console.log(`-- payload: ${mode} ${mode === 'fat' ? '(whole 200-row board)' : '(single row)'}`) console.log( table( results.filter((r) => r.mode === mode), [ { label: 'compress', get: (r) => r.compress }, { label: 'variant', get: (r) => r.variant }, { label: 'up/op', get: (r) => `${r.upPerOp.toFixed(0)} B` }, { label: 'down/op', get: (r) => `${r.downPerOp.toFixed(0)} B` }, { label: 'total/op', get: (r) => `${r.totalPerOp.toFixed(0)} B` }, { label: 'new conns', get: (r) => r.newConns }, ], ), ) console.log('')}
console.log(JSON.stringify({ test: 'bytes', rounds: ROUNDS, results }))