{"slug": "what-a-5-mb-super-resolution-model-can-and-can-t-do-inside-a-browser-tab", "title": "What a 5 MB super-resolution model can (and can't) do inside a browser tab", "summary": "A developer demonstrated running a roughly 5 MB Real-ESRGAN super-resolution model entirely in a browser tab, upscaling a 563×449 photo to 1576×1257 in 14.2 seconds without uploading it, growing the file from 147 KB to 515.6 KB. The writeup explains that the network paints statistically plausible detail rather than recovering truth, making it suitable for photos and artwork but wrong for screenshots or text, and that tiled processing with overlap padding is needed to keep memory within what a laptop or phone browser can handle.", "body_md": "I enlarged a 563×449 photo to 1576×1257 without uploading it anywhere. The file was 147 KB before and 515.6 KB after, and it took 14.2 seconds. The interesting part isn't the result, it's the three questions it raises:\n\nLet's answer them with a bit of arithmetic and some small snippets.\n\nA normal resize (bilinear, bicubic, Lanczos) computes every new pixel as a weighted average of its neighbours. It can only blend what is already there, so edges get softer as you enlarge.\n\n```\n// The baseline every \"AI upscaler\" should be compared against\nfunction resizeBaseline(img, scale) {\n  const c = document.createElement('canvas');\n  c.width  = Math.round(img.naturalWidth  * scale);\n  c.height = Math.round(img.naturalHeight * scale);\n  const ctx = c.getContext('2d');\n  ctx.imageSmoothingQuality = 'high';\n  ctx.drawImage(img, 0, 0, c.width, c.height);\n  return c;\n}\n```\n\nA super-resolution network such as Real-ESRGAN (Wang et al., 2021, open source, BSD-licensed) does something different. It was trained on pairs of degraded and clean images, so it has learned what a plausible edge, a hair or a brick texture looks like, and it **paints** those in. The result looks sharper, but the extra detail is a statistically likely guess, not recovered truth. That's why a face can get crisp skin texture it never had, and why the same model is the wrong tool for a screenshot of text, where a \"plausible\" letter shape can be a wrong letter.\n\nRule of thumb I use: photos, artwork, product shots → try the network. Screenshots, charts, scans of text → plain resizing.\n\nCompression ratio depends on how much high-frequency detail an image has. The network adds texture, texture is expensive for JPEG, and the pixel count grew too:\n\n```\n563 × 449   =   252,787 px\n1576 × 1257 = 1,981,032 px   (≈ 7.8× more pixels, scale ≈ 2.8× per side)\n147 KB → 515.6 KB            (≈ 3.5× more bytes)\n```\n\nBytes grew less than pixels because JPEG handles smooth areas cheaply. The takeaway: a bigger file is not a better file, and you should expect to run a compressor afterwards.\n\nThe model itself is small. The tool I tested says its model is about 5 MB. The **tensors** are the problem. Back-of-the-envelope, for a worst-case 2 MP input enlarged 4× (that's 32 MP of output):\n\n```\noutput RGBA bytes:        32e6 * 4            ≈ 128 MB\nfloat32 RGB activations:  32e6 * 3 * 4        ≈ 384 MB  (for the final layer alone)\n```\n\nand intermediate feature maps are many channels wide, so the real peak is far higher. A browser tab on a laptop or a phone will not survive that, so the image is processed in chunks. The generic recipe looks like this (a sketch of the idea, not any particular tool's code):\n\n``` js\nconst T = 128, PAD = 8, SCALE = 4;           // tile size, overlap, model factor\n\nfor (let y = 0; y < h; y += T) {\n  for (let x = 0; x < w; x += T) {\n    // read a little more than the tile so the seams have context\n    const sx = Math.max(0, x - PAD), sy = Math.max(0, y - PAD);\n    const ex = Math.min(w, x + T + PAD), ey = Math.min(h, y + T + PAD);\n\n    const up = await runModel(cropRGB(src, sx, sy, ex, ey)); // SCALE× bigger\n\n    // keep only the inner part, drop the padded border\n    blit(dst, up,\n         (x - sx) * SCALE, (y - sy) * SCALE,\n         Math.min(T, w - x) * SCALE, Math.min(T, h - y) * SCALE,\n         x * SCALE, y * SCALE);\n    onProgress(++done / total);              // \"part 10 of 20\" comes from here\n  }\n}\n```\n\nThe overlap matters. Without it, every tile boundary becomes a faint grid line because the network has no context beyond the edge of its input.\n\nThat also explains the caps you see in these tools: the one I tried accepts JPG/PNG/WebP up to 16 MB and about 2 MP, and limits the output's longest side to 4096 px. Those are not arbitrary; they keep the memory estimate above inside what a normal device can take.\n\nThe same model can run on the GPU through WebGPU or fall back to the CPU. Detecting it is cheap:\n\n```\nasync function pickBackend() {\n  if ('gpu' in navigator) {\n    try {\n      const adapter = await navigator.gpu.requestAdapter();\n      if (adapter) return 'webgpu';\n    } catch { /* fall through */ }\n  }\n  return 'cpu';\n}\n```\n\nThe difference is large. In my test the status line read `Enhancing (WebGPU) — part 10 of 20 · about 8 s left`. The page itself warns that without WebGPU a 1 MP photo \"can take a minute or two\". If you build something like this, show the backend and a time estimate in the UI; people forgive a slow job far more easily than a silent one.\n\n`resizeBaseline` next to the network output. If you can't see a difference at 100% zoom, skip the network and save the battery.\nIf you want to try the browser-only setup yourself without writing it, the tool I used for the numbers above is [here](https://tooltiny.com/image-upscaler.html). Whatever you use, test it with one photo and one screenshot. The contrast between the two tells you more than any benchmark.\n\nWhat's the largest image you've pushed through a model in the browser before the tab gave up? I'd like to know where your limit was.", "url": "https://wpnews.pro/news/what-a-5-mb-super-resolution-model-can-and-can-t-do-inside-a-browser-tab", "canonical_source": "https://dev.to/enlh/what-a-5-mb-super-resolution-model-can-and-cant-do-inside-a-browser-tab-3kk8", "published_at": "2026-11-10 00:45:43+00:00", "updated_at": "2026-11-10 00:52:41.339320+00:00", "lang": "en", "topics": ["computer-vision", "ai-tools", "machine-learning", "generative-ai"], "entities": ["Real-ESRGAN", "WebGPU"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/what-a-5-mb-super-resolution-model-can-and-can-t-do-inside-a-browser-tab", "markdown": "https://wpnews.pro/news/what-a-5-mb-super-resolution-model-can-and-can-t-do-inside-a-browser-tab.md", "text": "https://wpnews.pro/news/what-a-5-mb-super-resolution-model-can-and-can-t-do-inside-a-browser-tab.txt", "jsonld": "https://wpnews.pro/news/what-a-5-mb-super-resolution-model-can-and-can-t-do-inside-a-browser-tab.jsonld"}}