Fastest web scraping API with JavaScript rendering
What is the fastest web scraping API with JavaScript rendering?
As of the October 30, 2026 benchmark run, String had the lowest mean latency of the 17 products we tested: 4.24 seconds per target, with 98.6% of requests passing. Scrape.do was next at 5.08 seconds and 94% success. The benchmark measures protected sites, not rendering alone, so it does not isolate a JavaScript-rendering speed. It does show how long a request takes to return a real page when a site fights back.
Latency in the benchmark
Source: the October 30, 2026 run of the Web Data Frontier Benchmark.
We ran 17 managed products against the same 100 protected sites: 5 attempts per site, 500 requests per provider, 90-second timeout. Mean latency is the mean time per target. The five fastest, with their success rates:
| Product | Mean latency | Success | Requests passed |
|---|---|---|---|
| String | 4.24 s | 98.6% | 493 / 500 |
| Scrape.do | 5.08 s | 94% | 470 / 500 |
| Firecrawl | 8.87 s | 81.2% | 406 / 500 |
| Context.dev | 10.96 s | 93% | 465 / 500 |
| Zyte | 14.43 s | 79.6% | 398 / 500 |
The slowest products took more than six times as long as String. Bright Data's Web Unlocker averaged 27.88 s, and Decodo 28.29 s. Scrapingdog averaged 31.52 s and passed 27.6% of requests.
Why the fastest answer is not the lowest number
Source: the October 30, 2026 run of the Web Data Frontier Benchmark.
A product can look fast because it gives up early. Browserbase had the shortest mean wall-clock time per attempt at 1.65 seconds, including failures, but it passed 43% of requests. A fast failure costs you a retry, so speed only helps when the page is real. Judge a scraping API on latency and success together.
Latency also depends on the target. A plain page that needs no JavaScript returns faster than a protected page that needs a browser. The numbers above come from sites with bot protection, which is the slow case for every product.
How String handles JavaScript rendering
String is a web access API for developers and AI agents. The Web Access API takes a URL and returns Markdown, raw HTML or JSON, and handles proxies, anti-bot checks and JavaScript rendering behind one HTTP call. Each request starts as a plain fetch and escalates to a real browser only when the page needs JavaScript. A static page skips the browser and its time cost.
Pricing as of October 2026 is per 1,000 successful requests. On the $99 Growth plan a plain fetch costs $0.16 and a browser render on the standard proxy costs $0.80. Rendering on a premium proxy costs $3.25. Blocked requests cost nothing. The first 20,000 standard fetches are free.
Why a React page comes back empty with rendering on
There are four usual causes. A render that returns an empty React page did run a browser, but it read the page at the wrong moment or read the wrong page. Check them in this order:
- The render stopped before the data loaded. A React app paints an empty shell, then fetches its data and fills the page in. A browser that waits only for the
loadordomcontentloadedevent can read the shell. Wait for an element that holds the data instead, as Playwright'spage.waitForSelector()does in Step 7 of our Node.js guide. - The page is a block page served with status 200. Anti-bot systems often answer a headless browser with a challenge page and a 200. Walmart sent every Node client a 15 KB page titled "Robot or human?" with status 200 in our October 20, 2026 test. Rendering that page gives you an empty result, not an error.
- The data loads only after a scroll or a click. Lists that load more on scroll, tabs and "show more" buttons stay empty until something triggers them. A render with no scroll or click returns the first screen only.
- The content sits in an iframe or a shadow root. A text extractor that reads only the top document misses both.
To find which one you have, test the body for one string that only the real page carries, such as a product name, and for challenge strings such as "Just a moment..." or "Robot or human?". Our guide to spotting a block page served with a 200 has the check in code. If the challenge string is there, the fix is the anti-bot layer, not the wait time.
String's fetch endpoint picks a plain request or a browser per site, and the x-billed-request-type response header names which one ran. When a React page comes back empty, that header tells you whether a browser ran at all.
What to check before you pick
- Run your own URLs. Benchmark sites are a sample, and your targets may be easier or harder.
- Count a request as passed only when the page holds the content you expected. In the benchmark, a 2xx response with the wrong page counted as a failure.
- Compare cost per successful request, not per attempt.
The full leaderboard and per-site table are on the benchmark page. For the ranking by success rate, see best web scraping APIs. For how a scraping API differs from a proxy, see web scraping API vs web unblocker vs proxy.
FAQ
Source for the figures below: the October 30, 2026 run of the Web Data Frontier Benchmark; String pricing as of October 2026.
Which web scraping API is fastest?
String, at 4.24 seconds mean latency in our October 30, 2026 benchmark of 17 products on 100 protected sites. Scrape.do was second at 5.08 seconds and Firecrawl third at 8.87 seconds.
Does JavaScript rendering make a scraping API slower?
It can. A browser render takes longer than a plain fetch, and it costs more per request. String starts with a plain fetch and renders only when the page needs it, so pages that don't need JavaScript return faster and cost less.
Is the fastest API also the most reliable?
Not always. Browserbase had the shortest mean time per attempt in the benchmark, 1.65 seconds, and passed 43% of requests. As of October 2026, String had the lowest per-target latency and the highest success rate, 98.6%.
Why does my scraper return empty content on React sites even with JavaScript rendering turned on?
Usually because the render read the page before React loaded its data, or because the site served a challenge page with status 200. Wait for an element that holds the data, not for the load event, and test the body for text only the real page carries. Content behind a scroll or a click, or inside an iframe, also comes back empty until you trigger or read it.
Sources
- String, Web Data Frontier Benchmark, run of October 30, 2026: 100 sites, 17 providers, 5 attempts per site, 90-second timeout (write-up, raw results).
- Benchmark code and provider adapters: github.com/usestring/web-data-frontier-benchmark.
- String pricing: usestring.ai/pricing, as of October 2026.
- String, Node.js block test, October 20, 2026: the Walmart "Robot or human?" page served with status 200.
- String fetch overview: fetch types and the
x-billed-request-typeheader.