No installs. No native apps. Just open a URL and push your MacBook, PC, Android, or iPhone to its limits.
We've all been there. You get a shiny new device — a MacBook Pro with an M4 chip, a Galaxy S25, or a gaming PC with the latest GPU — and the first thing you want to do is see what it can really do.
The problem? Most benchmark tools are platform-locked native apps. Geekbench costs money. 3DMark is Windows-only. AnTuTu is mobile-only. And none of them let you compare your MacBook against your phone with the same test suite.
So I built WebStress — an open-source, browser-based benchmark suite that runs on literally anything with a modern browser. No installs, no accounts, no app store. Just open a URL.
Here's what I learned building it, and how you can use (or fork) it yourself.
Why a Browser-Based Benchmark?
Browsers have become absurdly powerful. WebGL gives us GPU access. Web Workers enable multi-threaded CPU tests. TypedArrays let us do real number-crunching. The browser is no longer just a document viewer — it's a compute platform.
A browser benchmark has one killer advantage: true cross-platform parity. The exact same JavaScript code runs on your M4 MacBook, your Windows gaming rig, your Android phone, and your iPhone. Same tests, same scoring, genuinely comparable results.
What It Tests
WebStress runs 32 individual sub-tests across 6 categories. Let me break down what each one actually measures and why it matters.
🧠 CPU — The Brain
The CPU benchmark isn't just "loop a billion times and see how fast it goes." It targets specific computational patterns:
- Integer Arithmetic — Bitwise operations, XOR chains, and integer multiplication. This is your chip's bread and butter for general-purpose computing.
-
Floating Point — Trigonometric functions (
sin,cos,atan2), square roots, logarithms. Critical for scientific computing, audio processing, and physics simulations. - Hash / Crypto — FNV-1a hashing over 1KB buffers. Simulates real-world hashing workloads like integrity checks and password processing.
- Array Sort — Sorting 10,000-element Float64 arrays. Tests branch prediction, cache efficiency, and the JS engine's sort implementation.
- Prime Sieve — Classic trial division up to 500K. Pure integer ALU throughput with branching.
- Matrix Multiply — 64×64 double-precision matrix multiplication. The fundamental operation behind machine learning, graphics, and scientific computing.
- Multi-Core Scaling — Spawns Web Workers equal to your core count, all running the integer test simultaneously. Measures how well your chip scales under parallel load and how efficiently the browser manages threads.
The multi-core test is particularly interesting. Apple's M-series chips show very different scaling behavior from Intel/AMD due to their efficiency/performance core architecture. You can literally watch it in the results.
🎮 GPU — The Graphics Muscle
These tests use WebGL shaders — actual GPU programs running on your graphics hardware:
- Fill Rate — How many full-screen quads the GPU can paint per second. Raw pixel throughput.
- Fragment Shader — A complex procedural shader with trigonometric wave functions. Tests the GPU's shader unit compute performance — the same units that process every pixel in games.
- Geometry Throughput — Renders 5,000 animated triangles. Measures vertex processing and how fast the GPU can handle geometry transformations.
- Texture Sampling — Multi-level texture reads with coordinate distortion. Tests texture unit throughput and memory bandwidth — critical for game rendering.
- Particle System — 10,000 point sprites with alpha blending. Combines vertex processing, fragment shading, and blending — a realistic GPU workload.
Integrated GPUs (Intel, Apple, Qualcomm Adreno) versus discrete GPUs (NVIDIA, AMD) show dramatic differences here. Even between phones, the GPU gap can be 5-10x.
💾 Memory — The Hidden Bottleneck
CPU and GPU get all the headlines, but memory performance often determines real-world speed:
- Sequential Read/Write — 32MB linear scan. Tests main memory bandwidth when access patterns are predictable — the best case scenario.
- Random Access — 8MB random reads. This is the worst case. It exposes memory latency and how well the cache hierarchy handles unpredictable access patterns. The gap between sequential and random performance reveals your cache effectiveness.
- Bandwidth — Tests copy speed across buffer sizes from 8KB to 32MB. This maps directly to cache levels — L1, L2, L3, and main memory. You can literally see the performance cliff as data exceeds each cache level.
- Allocation Speed — How fast the runtime can allocate and initialize memory buffers. Important for applications that create lots of temporary objects.
- TypedArray Operations — Vectorized multiply-add across 8M floats. Tests how well the JS engine optimizes tight numeric loops — some engines auto-vectorize these to SIMD instructions.
🤖 AI / NPU — The New Frontier
Every chip maker is adding AI accelerators. These tests simulate common ML workloads in pure JavaScript:
- Matrix Multiply (GEMM) — 256×256 float32 matrix multiplication. This is THE operation behind neural networks. Measures raw FLOPS.
- Conv2D — 3×3 convolution with 16 output channels over a 128×128 image with ReLU activation. The core operation in image recognition models like ResNet and YOLO.
- Softmax — 10,000-element softmax across 1,000 iterations. Used in every attention layer and classifier output. Tests exp/log throughput.
- Attention Score — Full scaled dot-product attention with Q, K, V matrices (64×64). This is the mechanism inside every transformer model — GPT, BERT, Llama, etc.
- Mini-Network Inference — A 3-layer feedforward network (784→256→128→10) processing batches of 32. Simulates real model inference — like running a digit classifier.
Currently these run in pure JS on the CPU. As WebNN browser support matures, these same workloads could be dispatched to dedicated NPU hardware (Apple Neural Engine, Qualcomm Hexagon, Intel NPU). The scores will become a direct measure of on-device AI capability.
🖼️ Rendering — Browser Performance
Your device might have a fast CPU, but can the browser use it efficiently?
- DOM Manipulation — Creates 1,000 styled elements, reads layout properties, applies transforms, then removes them. This is what happens in every complex web app — React, Vue, Angular all do this constantly.
- Canvas 2D — Renders 200 circles, 100 lines, and 50 text labels per frame for 3 seconds. Tests the browser's 2D rendering pipeline — used in charts, games, and data visualization.
- CSS Animations — Animates 500 elements simultaneously with rotation and translation. Tests the browser's compositor and animation scheduler — critical for smooth UI.
- Layout / Reflow — Rebuilds a 50-item flexbox grid 500 times, forcing layout recalculation each time. This is the most expensive thing browsers do, and the main source of UI jank.
- SVG Rendering — Creates and renders 200 SVG documents with circles and Bézier curves. Tests the vector rendering pipeline.
📦 Storage — I/O Speed
How fast can the browser persist and retrieve data?
- IndexedDB Write/Read — Individual transaction read/write operations. The primary storage API for web apps.
- IndexedDB Bulk — 5,000 records in a single transaction with cursor-based reading. Tests transactional throughput.
- LocalStorage — Synchronous key-value storage. Fast but blocking — these tests reveal just how blocking.
- Cache API — Write and read from the browser's Cache Storage. Used by service workers and PWAs for offline support.
Live Monitoring
One thing I wanted that other benchmarks don't do well: watching the test happen in real time.
While benchmarks run, you see four live-updating charts:
- FPS — Browser frame rate, showing when the main thread is saturated
- Score — Rolling score updates as each sub-test completes
- Thermal — A stability metric that detects CPU throttling. It runs a quick workload repeatedly and measures timing consistency. When your chip heats up and throttles, the variance increases. It's indirect, but it actually works — you can watch a MacBook go from "Cool" to "Warm" during the GPU tests
-
Memory — JS heap usage in real-time (Chrome/Edge only, via
performance.memory)
The Scoring System
Every sub-test produces a raw metric (operations/second, FPS, GB/s, etc.). These get normalized to a 0–5000 scale against baseline values.
The baselines are calibrated so that a mid-range 2024 device scores roughly 1000. A high-end device scores 2000–3000+. The maximum is 5000, leaving room for future hardware.
The overall score is the mean across all category scores, giving equal weight to CPU, GPU, Memory, AI, Rendering, and Storage.
Results & Analytics
After tests complete, you get:
- Animated score ring with your overall score
- Category cards with bar charts and per-sub-test breakdowns
- Radar chart showing your device's strengths and weaknesses
- Timeline chart showing score progression across tests
- Full details table with every raw measurement
- Export — JSON download or one-click clipboard copy for sharing
Technical Decisions
A few choices I made and why:
Pure vanilla JS, zero dependencies. No React, no build step, no npm. The entire project is static HTML/CSS/JS files. This means it works from a file:// URL, from any static host, and loads instantly. For a benchmark tool, framework overhead would pollute the measurements.
Inline Web Workers. Workers normally need a separate JS file loaded via URL, which fails on file:// due to security restrictions. I inline the worker code as a string and create a Blob URL. This means the multi-core CPU test works everywhere — even opening index.html directly from disk.
WebGL, not WebGPU. WebGPU is the future, but WebGL2 has 95%+ browser support including mobile Safari. For a tool that needs to work everywhere, WebGL is the right choice today. WebGPU variants can be added as an optional enhanced test later.
Canvas-based charts, not Chart.js/D3. Again, zero dependencies. The mini-line charts, radar chart, and timeline are drawn directly to <canvas>. They're simple, fast, and add zero to the bundle size.
Some Interesting Findings
Testing this across devices revealed patterns you don't see in spec sheets:
- Apple Silicon is absurdly efficient. An M2 MacBook Air outperforms many desktop CPUs on single-thread while barely getting warm. The multi-core scaling efficiency is also excellent.
- Mobile GPUs are surprisingly good. A recent iPhone's GPU fragment shader performance isn't that far behind integrated laptop GPUs. The Adreno and Mali GPUs in flagship Android phones are legitimate compute devices.
- Storage performance varies wildly. IndexedDB on Safari is significantly slower than Chrome. LocalStorage blocking time can be 10x worse on some browsers. If your web app feels slow, storage might be why.
- Thermal throttling is real and visible. Run the full suite on a fanless device and watch the thermal stability metric drop. Phones throttle aggressively after 30-60 seconds of sustained load. The benchmark captures this behavior that synthetic spec sheets ignore.
Try It Yourself
The project is fully open source. You can:
- Run it now — Head to prashplus.com/web-stress-test and hit "Run Benchmark"
- Clone it — Fork the GitHub repo and run locally
- Extend it — Add your own tests, adjust baselines, build a leaderboard
git clone https://github.com/prashplus/web-stress-test.git
cd web-stress-test
python3 -m http.server 8000
# Open http://localhost:8000
No build step. No npm install. Just code and a browser.
What's Next
Some ideas for future versions:
- WebGPU compute shaders for true GPU compute benchmarks
- WebNN integration to actually test NPU hardware when browser support lands
- WASM benchmarks comparing JS vs WebAssembly performance
- Network speed tests measuring latency and throughput
- Battery impact estimation for mobile devices
- Leaderboard with anonymous result submission for comparison
- Historical tracking to see how browser updates affect performance
The Bottom Line
Your browser is a more powerful computing platform than most people realize. WebStress proves it by pushing every subsystem — CPU, GPU, memory, AI, rendering, and storage — through real workloads, on any device, with zero friction.
The web platform is the only truly universal runtime. Building a benchmark on it means anyone, anywhere, on any device can test and compare their hardware with a single click.
Give it a try, share your scores, and let me know what tests you'd want to see added.
WebStress is open source under the MIT license. Try it live or star it on GitHub if you find it useful.
Tags: JavaScript, WebGL, Benchmarking, Performance, Web Development, Open Source, Browser, Cross-Platform
Top comments (0)