pixelshot Read One Tile of an 18,609px Wikipedia Page: the Lazy-Load Trap Under Visual RAG
I fed a Wikipedia page to pixelshot and it handed back one tile.
The page was Comparison_of_programming_languages, a wall of roughly a hundred language sections stacked vertically. My browser measured it at 18,609px tall. pixelshot decided it was 1,553px and stopped there. One screenshot, about the top 8% of the page, and a "complete": true flag telling me the job was done.
The same command tiles Simon Willison’s blog into three clean slices and OurWorldInData into seven. So pixelshot works. This specific page, under this specific tool, quietly truncates, and it does it every time. That gap between “works on most pages” and “silently wrong on a major reference site” is the part worth writing down before anyone wires this into a pipeline that feeds a model.
What pixelshot is, and why I tried it
pixelshot comes out of PixelRAG, a Berkeley SkyLab / BAIR / Berkeley NLP project from June 2026 (arxiv
.28344). The core claim is a visual take on retrieval: instead of parsing a web page into HTML chunks, you keep it as a screenshot and search over the image, so tables, charts, and layout never get flattened into text. The full system embeds screenshot tiles with a LoRA-tunedQwen3-VL-Embedding and ships a prebuilt FAISS index over 8.28M Wikipedia pages.
pixelshot is the front half of that pipeline broken out as a standalone CLI: render a page with Playwright/CDP, cut it into tiles. It’s also packaged as a Claude Code plugin (pixelbrowse) with its own SKILL.md, so the intended flow is “Claude sees the page as images instead of reading the DOM.”
That’s the part I wanted to test. I already run a headless browser locally to show pages to Claude: PinchTab, a 9.4k-star open-source browser-automation bridge (Go, MIT). It renders SPAs and holds a logged-in profile for sites where WebFetch bounces off a login wall. But its screenshot endpoint only captures one viewport, so long pages get read from the neck up. pixelshot tiles the whole thing at a size tuned for a vision model’s downscale limit. On paper it was a straight upgrade. So I measured it.
The five-page benchmark
Five pages, one from each category (short page, long article, heavy table, chart, PDF):
| id | URL | measured height |
|---|---|---|
| short-01 | arxiv abstract | under one viewport |
| long-01 | simonw’s openai-o1 report | 4,475px |
| table-01 | Wikipedia Comparison_of_programming_languages | 18,609px |
| chart-01 | OurWorldInData CO2 emissions | 8,893px |
| pdf-01 | PixelRAG paper PDF (35 pages) | — |
Shot three ways: PinchTab’s single viewport shot, PinchTab driven with scrollTo + repeated shots, and pixelshot with the settings its own SKILL.md recommends for reading with Claude:
pixelshot <url> \
--tile-height 1568 \
--viewport-width 1280 \
--wait-network-idle
--tile-height 1568 matches the point where Claude’s vision model starts downscaling the long edge (Sonnet/Haiku; Opus goes to 2576), so tiles land crisp instead of blurred. --wait-network-idle waits out SPA rendering. Results:
| id | PinchTab 1 shot | PinchTab scroll | pixelshot tiles |
|---|---|---|---|
| short-01 | whole page | (not needed) | 1 tile |
| long-01 | top 30% | 4 shots, full | 3 tiles |
| table-01 | top 10% | 16 shots, full | 1 tile, truncated |
| chart-01 | top 15% | 8 shots, full | 7 tiles |
| pdf-01 | ❌ can’t | ❌ can’t | 35 tiles |
Four of five rows behave. The one that doesn’t is table-01.
The crime scene: 1,553 of 18,609 pixels
Here is what pixelshot wrote to tiles.json for the Wikipedia page:
{
"url": "https://en.wikipedia.org/wiki/Comparison_of_programming_languages",
"page_height": 1553,
"tiles": ["tile_0000.jpg"],
"complete": true
}
page_height: 1553, against a real document.documentElement.scrollHeight of 18,609. Under 1/12th of the page, reported back as complete. Adding --wait-network-idle changed nothing. I ran it five times and got one tile five times.
The failure isn’t loud. There’s no crash, no timeout, no warning, just a confident JSON file that says the whole page is 1,553px and it’s done. If this sits inside a retrieval index, you don’t get an error; you get a Wikipedia comparison table where 92% of the rows silently don’t exist, and nothing downstream knows.
Why it happens: lazy-load and overflow fool height detection
pixelshot is not broken in general. Simon Willison’s post tiles into three, OurWorldInData into seven, both correct. Something specific to this page defeats the height measurement.
The usual suspects on a page like this:
- Lazy-loaded content. A collapsible table of contents and sections that don’t materialize until they scroll into view. Measure the height at load time and you measure the collapsed skeleton, not the expanded page.
- CSS
overflowcontainers. When the tall content lives inside an element with its own scroll context,scrollHeighton the document doesn’t see it. The page looks short from the outside.
Either way, whatever pixelshot reads for total height resolves to 1,553px, it cuts one tile, and it declares victory. The value it trusts is a lie the page told it at the wrong moment.
This is the portable part. It has nothing to do with PixelRAG being research code. Any tool that (1) measures page height once, up front, and (2) tiles or paginates from that number inherits this failure mode on lazy-load and overflow-heavy pages. Wikipedia is not an exotic target. If a major reference site trips it, your own long pages will too.
The lesson: scroll+shot survives what height detection doesn’t
The measurement that doesn’t lie is the scroll position. Instead of asking the page how tall it is and trusting the answer, you scroll down a viewport at a time, shoot each frame, and stop when you stop moving. Lazy content loads as you reach it, because you’re actually there. Overflow containers scroll because you’re scrolling them. You never depend on a single up-front height read.
That’s the shape of the fallback: drive scrollTo, screenshot, repeat with a small overlap so nothing falls in the seam, flush to the bottom at the end. On the Wikipedia table it produced 16 frames covering the whole page, versus pixelshot’s one. I walk the actual implementation on PinchTab, including the overlap math and the lazy-load settle delay, in the companion post. The point here is architectural: scroll-driven capture holds up exactly where height-detected tiling is fragile.
Where pixelshot still wins
This isn’t a takedown. For two jobs pixelshot is the better tool, and for one it’s the only one:
- PDFs. A headless browser opens a PDF but won’t page-tile it. pixelshot installs poppler + pdf2image (
pip install 'pixelrag[pdf]') and cuts one tile per page: 35 clean tiles at 200 DPI from the PixelRAG paper. For feeding papers or technical books to a model, this alone is worth it. - SPAs.
--wait-network-idlehandles JS-heavy rendering in one flag, no scroll choreography. - One command.
pixelshot <url> -o out/and you’re done. A hand-rolled scroll+shot script is more moving parts. For occasional use, simplicity wins.
And the full PixelRAG system (screenshot → embed → FAISS over 8.28M pages) is a different weight class from “screenshot one page.” If you need visual retrieval over a large corpus, that’s the thing to reach for. This post only compares the “show Claude one page” layer.
Reported upstream
The Wikipedia truncation reproduced 5 out of 5, so I filed it as StarTrail-org/PixelRAG#124. It’s a narrow, reproducible case rather than a general fault, but a silent one-tile truncation on a top-100 reference page is the kind of thing worth surfacing before it lands in someone’s index.
Wrap-up
- pixelshot read an 18,609px Wikipedia page as 1,553px and returned a single tile, five times out of five, with
"complete": true. Simon Willison’s blog and OurWorldInData tiled correctly, so the tool works. This page’s lazy-load and overflow defeat its up-front height detection. - The failure is silent. No crash, just a confident JSON that drops 92% of the page. That’s the dangerous kind for a retrieval pipeline.
- The portable lesson isn’t about PixelRAG. Any tool that measures height once and tiles from it inherits this on lazy-load / overflow pages. Scroll-driven capture doesn’t, because scroll position never lies about where you are.
- pixelshot still wins for PDFs (one tile per page) and SPAs (
--wait-network-idle), and the full PixelRAG pipeline is the right call for visual retrieval at corpus scale.
Next up, the scroll+shot implementation on PinchTab: the overlap math, the lazy-load settle delay, and why the higher native resolution reads sharper than 1,280px tiles even after downscaling.
Written by @kenimo49 / kenimoto.dev
Was this article helpful?