# Performance Tips

Optimize nokap for batch processing and high-throughput screenshot capture. nokap is designed to be fast by default (it reuses a single Chrome instance across calls and communicates over a low-overhead WebSocket connection) but there are additional strategies that can dramatically improve throughput when processing many pages. This page covers browser reuse, batch workflows, viewport tuning, and other techniques for getting the most out of nokap.

## Browser Reuse

nokap keeps Chrome running between calls via a module-level singleton. The first call pays the startup cost (~200ms); subsequent calls skip browser launch entirely:

``` python
import nokap

# First call: launches Chrome (~200ms overhead)
nokap.webshot("page1.html", "out1.png")

# Second call: reuses Chrome (just navigation + capture)
nokap.webshot("page2.html", "out2.png")
```

**Tip:** Don't call [nokap.close()](../reference/close.md#nokap.close) between sequential captures.

**Tip:** `chrome-headless-shell` (installed with `nokap install-chrome`) usually starts faster than full Chrome, which helps when every run launches a fresh browser, as in CI jobs or short scripts.

## Batch Processing

For many screenshots, keep Chrome alive across the entire batch:

``` python
import nokap
from pathlib import Path

html_files = Path("reports/").glob("*.html")

for html_file in html_files:
    out = html_file.with_suffix(".png")
    nokap.webshot(html_file, out, selector="table", zoom=2)

# Clean up once at the end
nokap.close()
```

## Minimize Delay

The default `delay=0.2` adds 200ms per capture. For static HTML content (no animations, no lazy loading), set it to zero:

``` python
nokap.from_html(html, "out.png", selector="table", delay=0)
```

## Viewport Optimization

A smaller viewport means less content to render. If you're capturing a small element with a selector, a narrow viewport is fine:

``` python
# Only capturing a table so no need for a wide viewport
nokap.from_html(html, "table.png", selector="table", vwidth=600, vheight=400)
```

## Choose the Right Format

| Format | Speed | File Size | Use When                              |
|--------|-------|-----------|---------------------------------------|
| PNG    | Fast  | Large     | Need lossless quality or transparency |
| JPEG   | Fast  | Small     | Photos, complex backgrounds           |
| WebP   | Fast  | Smallest  | Modern pipelines that support WebP    |
| PDF    | Fast  | Varies    | Need vector/print output              |

## Connection Recovery

If Chrome becomes unresponsive, nokap automatically restarts it on the next call. This adds one-time latency but requires no manual intervention:

``` python
# If Chrome crashed, this transparently relaunches
nokap.webshot("https://example.com", "recovery.png")
```

## Memory Considerations

Each [webshot()](../reference/webshot.md#nokap.webshot) or [from_html()](../reference/from_html.md#nokap.from_html) call creates and closes a browser tab. This prevents memory buildup from accumulated page state. For very long batch jobs, Chrome's memory usage stays stable.

## Timing Summary

| Operation                  | Typical Duration |
|----------------------------|------------------|
| Chrome launch (first call) | ~200ms           |
| Tab creation + navigation  | ~50ms            |
| Page load (local HTML)     | ~20ms            |
| Screenshot capture         | ~30ms            |
| PDF generation             | ~50ms            |
| Tab cleanup                | ~10ms            |

For local HTML content with `delay=0`, expect ~100ms per capture after the initial Chrome launch.

## Next Steps

With browser reuse, minimal delay, and the right format choices, nokap can process hundreds of captures efficiently. The key insight is that Chrome stays warm between calls (you only pay the startup cost once, and each subsequent capture is just a tab open, navigate, capture, and close cycle).

You now have all the tools to build high-throughput capture pipelines. Combine what you've learned here with the error handling patterns from the previous page to build robust batch workflows that recover from transient failures without losing progress.
