chromedp je knihovna v čistém Go s licencí MIT, která ovládá skutečný Chrome přes Chrome DevTools Protocol. Z Go programu čte DOM až poté, co se na stránce dokončí JavaScript, a obejde se bez samostatného WebDriveru i bez Node runtime. Go modul se sice zkompiluje přímo do aplikace, ale běhové prostředí stále vyžaduje externí spustitelný Chrome, jehož životní cyklus je řízen pomocí Go contextů.
Instalace byla jen o jednom go get a Chromu, který jsem si musel dodat sám: vytvořit allocator, odvodit context a předat Run seznam akcí. Na tomto hostiteli macOS arm64 s teplým headless shellem na disku měl nový proces do prvního výsledku skriptu medián 102 ms. To je lokální základ, ne obecné tvrzení, že start nikdy nepředstavuje úzké hrdlo. Na testovacím fixture, který vkládá odkaz 800 milisekund po načtení, se dvě ze čtyř čtecích strategií vrátily dřív, než odkaz vůbec existoval.
Prohlížeč byl skutečný, obsah tam byl, a kód na něj prostě nečekal. Právě to je nejdůležitější lekce, kterou mi chromedp předal, a není to chyba — je to rozdíl mezi „stránku jsem vyrenderoval“ a „počkal jsem na to, co jsem skutečně potřeboval“, což je rozdíl, který se v legendách o headless prohlížečích často vytrácí. O tom, zda data dostanete, rozhoduje strategie čekání, ne samotný prohlížeč. Všechna čísla zde pocházejí z lokálního fixture, které mám pod kontrolou, s ground truth zapsanou ještě před jakýmkoli během, a surové souhrny jsou v složce chromedp v našem benchmark repozitáři.
Co chromedp vlastně je
chromedp je záměrně stručný stack. Žádný Selenium server. Žádná WebDriver vrstva. Žádný skrytý Node runtime pod kapotou. Váš Go program otevře WebSocket k instanci Chrome a komunikuje s ní přímo přes CDP, což je v podstatě stejný transportní protokol, jaký používá Puppeteer, jen bez JavaScriptu.
Repozitář měl při mé kontrole 27. července 2026 13 212 hvězdiček a 178 otevřených issues a je pod licencí MIT. Testovaná verze je v0.16.0, tedy nejnovější tag v repozitáři. Stojí za zmínku, aby nedošlo ke zmatení: GitHub Releases stále ukazuje jako nejnovější release objekt v0.15.1 (publikovaný 2026-04-01), zatímco go get github.com/chromedp/chromedp@latest vrací v0.16.0. Go moduly a release objekty GitHubu se tady rozjely. Není to rozbité, jen otravné, když se snažíte zjistit, co vlastně běží.
Mentální model je v podstatě Go contexts až do dna. Vytvoříte allocator context (který ví, jak Chrome spustit), z něj odvodíte browser context a pak zavoláte chromedp.Run(ctx, actions...) se seznamem Actions. Dětský context z browser contextu je nový tab. Zrušíte context a reprezentovaná věc zmizí. Pokud máte zkušenost s Go concurrency, bude vám to hned povědomé; pokud ne, náš návod, jak začít s web scrapingem v Go je mnohem mírnější vstupní rampa než godoc chromedp.
Jedna hranice, kterou je dobré nastavit hned: chromedp vám vrací vyrenderovaný DOM. Nedodá vám strukturovaná data. Cokoli z DOMu vytáhnete — pole, tabulky, ceny — je kód, který si píšete a udržujete sami. Je to driver, ne scrapingový framework.
Co se děje pod kapotou
V chromedp je všechno Action a Run provede jejich slice v pořadí proti cíli. Navigate, Click, Evaluate, OuterHTML, WaitVisible — všechno je stejný interface, všechno se dá skládat, všechno jsou jen CDP příkazy zabalené do Go typů. Tahle uniformita je nejlepší designové rozhodnutí knihovny, protože díky ní stojí cukr i syrový protokol na stejné úrovni.
A právě na tom záleží, protože cukr je schválně jen tenká vrstva. chromedp stojí na cdproto, tedy generované sadě typovaných Go bindingů pokrývajících celý DevTools Protocol, a chromedp godoc dokumentuje obě vrstvy vedle sebe. Když pohodlná akce neexistuje, sáhnete ve stejném Run přímo po doménovém volání — network.Enable(), page.CaptureScreenshot(), runtime.Evaluate() —. Mezi „hezkým API“ a „skutečným API“ tu není žádná zeď, což neplatí u každého browser driveru.
Wait akce jsou místo, kde se v praxi rozhoduje, a je jich víc, než lidé běžně používají:
| Wait akce | Na co čeká |
|---|---|
WaitReady(sel) | dokud není node připojený do DOM |
WaitVisible(sel) | dokud není node opravdu viditelný |
WaitNotPresent(sel) / WaitNotVisible(sel) | opaky, užitečné pro spinnery |
Poll(js, res) | v intervalech vyhodnocuje JavaScriptovou podmínku, dokud není pravdivá |
Správa procesů je druhá část mechanismu, kterou je dobré znát, protože rozhoduje o tom, zda vám po programu nezůstane běžet browser. chromedp spouští Chrome přes Go exec.CommandContext. Zrušení daného contextu proces ukončí. Tenhle jediný detail vysvětluje jak dobré chování, tak ostrý roh, na který jsem při testování narazil.
Instalace je Go binárka plus Chrome, který si musíte dodat sami
go get github.com/chromedp/chromedp se bez potíží vyřešil na v0.16.0 a strom závislostí neobsahuje žádné cgo importy. Tvrzení „pure Go, žádné externí závislosti“, které se opakuje v popisech, je tedy pravdivé — ale jen pro Go modul.
Neplatí to pro runtime. chromedp ovládá externí Chrome, a pokud na stroji žádný Chrome není, běh okamžitě selže. Každé měření, které jsem dělal, explicitně předávalo přes chromedp.ExecPath přesný spustitelný soubor, konkrétně Chrome for Testing 151.0.7922.10 headless shell. To není výtka — pro ovládání prohlížeče potřebujete prohlížeč — ale „bez externích závislostí“ a „musíte vedle binárky dodávat 155 MB Chrome“ jsou dvě velmi odlišné deploymentové story, a v README je vidět jen jedna z nich.
Druhá nástraha při setupu mě stála čas a stojí za to ji znát dřív, než napíšete první řádky kódu. Issue #1591 popisuje, že runner go test na Go 1.25+ ruší NewExecAllocator uprostřed startu; identický kód jako zkompilovaná binárka funguje v pořádku. Pro každé měření jsem proto sestavil probe binárku přes go build a spouštěl ji napřímo, nikdy ne přes go test. Go zde bylo 1.26.5, macOS arm64. Pokud je vaše první zkušenost s chromedp testovací soubor, který padá během startu Chrome, je tohle issue, které si přečtěte dřív, než začnete obviňovat vlastní kód.
Prakticky: čtyři způsoby, jak číst stejnou stránku, dvě z nich vrátí prázdno

Fixture je lokální server na 127.0.0.1, který servíruje tři druhy obsahu lišící se jen tím, kdy se dostanou do DOM: statický <a> přímo v odeslaných bajtech, <a> vytvořený inline <script> během úvodního parsování a <a> vytvořený přes setTimeout s nastavitelným zpožděním po události load. Markery a hrefy dvou odkazů vytvořených skriptem se skládají z fragmentů řetězců v JavaScriptu, takže v odeslaných bajtech neexistuje žádný souvislý literál. „Nalezeno“ tedy dokazuje, že Chrome skutečně provedl JavaScript, ne že někdo četl HTML.
Recall se počítá v Pythonu proti předem zaregistrovaným ground-truth markerům, ne uvnitř Go probe, takže probe nemůže podvádět tím, že zná odpověď. Každá strategie běžela třikrát; sady nalezených výsledků byly ve všech třech bězích identické.
| Strategie čtení | Odkaz ve statickém HTML | Vložený při parsování | Vložený 800 ms po load | Čas |
|---|---|---|---|---|
Navigate + čtení bez čekání | found | found | missed | 317 ms |
WaitReady("body") | found | found | missed | 107 ms |
WaitVisible("#delayed-injected") | found | found | found | 912 ms |
| Poll, dokud se marker neobjeví | found | found | found | 972 ms |
Dva řádky se vrátí se dvěma odkazy ze tří. Naivní čtení selže proto, že Navigate vrací po události load a třetí odkaz ještě neexistuje. WaitReady("body") selže z jemnějšího důvodu, který je v praxi ještě horší: body je při load připojený, takže wait je splněný okamžitě a máte pocit, že jste udělali správnou věc. Vrátil se za 107 ms, rychleji než cesta bez čekání, a přinesl stejnou neúplnou stránku.
Abych ověřil mechanismus místo pouhého předpokladu, procházel jsem zpoždění injekce a znovu spustil oba extrémy (recall-summary.json):
| Zpoždění injekce po load | Čtení bez čekání odkaz vidí | WaitVisible odkaz vidí | WaitVisible elapsed |
|---|---|---|---|
| 0 ms | ano (race) | ano | 109 ms |
| 100 ms | ne | ano | 208 ms |
| 400 ms | ne | ano | 519 ms |
| 800 ms | ne | ano | 911 ms |
| 1500 ms | ne | ano | 1625 ms |
WaitVisible na tomto fixture svým elapsed časem sleduje zpoždění injekce — 100 až 208, 400 až 519, 800 až 911, 1500 až 1625 — což je důkaz, že opravdu čekalo na objevení nodu, místo aby četlo příliš brzy. Řádek s 0 ms je hraniční: setTimeout(…, 0) může proběhnout dřív než okamžité čtení, takže bezčekací cesta ho může stihnout. Při 100 ms a výše v tomhle sweepu ho no-wait cesta v každém běhu minula.
V produkci může stejná chyba v načasování vyrobit validní HTML s nulovým počtem extrahovaných řádků a návratovým kódem 0, pokud pipeline neověří počet výsledků. To je pravděpodobný failure mode podložený chováním fixture, ne incident, který bychom zde přímo měřili. Rendering je jen polovina požadavku; čtení musí čekat na aplikační podmínku navázanou na požadovaná data.
WaitReady a WaitVisible nejsou seřazené — odpovídají na různé otázky
Běžně se říká, že WaitVisible je „spolehlivější“ než WaitReady. To je dost nepřesné na to, aby to škodilo. Na stránce s node připojeným do DOM, ale stylovaným jako display: none, se oba stavy jasně rozcházejí (waitsem-summary.json, tři stejné běhy):
| Cílový node | Akce | Výsledek | Čas |
|---|---|---|---|
připojený, display:none | WaitReady | vrátí se | ~6 ms |
připojený, display:none | WaitVisible | timeout, context deadline exceeded | 4000 ms |
| viditelný node | WaitVisible, default query | vrátí se | 4–12 ms |
| viditelný node | WaitVisible, ByID | vrátí se | 1–2 ms |
| viditelný node | WaitVisible, ByQuery | vrátí se | 1 ms |
WaitReady znamená připojený. WaitVisible znamená viditelný. Když se ptáte na špatnou věc, buď projdete kolem obsahu, který se nikdy nezobrazil, nebo se zaseknete na celý timeout na nodu, který stejně nikdy viditelný být neměl. Deadline chování je samo o sobě čisté — správný context deadline exceeded přesně po 4 s, bez zaseknutí, bez zombie stavu — což je víc, než umí některé jiné drivery.
Jeden z hlášených problémů se neprojevil. Issue #440 popisuje WaitVisible("#id"), které se s default query zasekne, a na v0.16.0 se to nereprodukovalo — default query, ByID i ByQuery se na viditelném nodu ve všech bězích vrátily. „Nepodařilo se reprodukovat“ ale není totéž co „opraveno“: jde o jeden tvar selektoru na jedné stránce, což issue samo o sobě neuzavírá.
Ten defer cancel(), který jste vynechali, drží střechu
Počty procesů, ne návratové hodnoty. Každý lifecycle běh používal jedinečný --user-data-dir a počítal skutečné browser procesy Chrome přes pgrep, přičemž filtroval renderer děti. Každá cesta běžela třikrát (lifecycle-summary.json).
| Cesta ukončení (macOS, 3 běhy každá) | Co se stalo se spuštěným chrome-headless-shell | Čas |
|---|---|---|
| Zrušit context i allocator | pryč | 13, 13 a 12 milisekund |
| Ukončit Go proces bez zrušení | přežije váš program — před exitem probe bylo 0 browser procesů, po exitu 1; orfanizováno ve všech třech bězích | — |
Zrušení je čisté, rychlé a přesně to, co exec.CommandContext slibuje. (Všichni osiřelí procesy byly poté harnessem násilně ukončeny; hostitel byl vyčištěn.)
Tohle je známé, zdokumentované, platformně omezené chování — měření je moje, objev ne. Tracker chromedp to pokrývá z několika stran: #774 popisuje stejné neukončení na FreeBSD, #752 hlásí visící procesy Chromia na macOS a #562 spolu s #1566 vysvětlují mechanismus. Co jsem přidal, jsou počty procesů a časování na obou stranách kontrastu, což kvalitativní hlášení neobsahují.
Samotný mechanismus je dobré znát na úrovni build tagů. Ve zdrojích v0.16.0 allocate_linux.go nastavuje pro child process Pdeathsig = SIGKILL, takže Linux dostává kernelový signál o smrti rodiče. allocate_other.go, který se kompiluje na macOS, toto volání dělá jako no-op. Na darwinu neexistuje ekvivalentní signál, takže nic nezabije Chrome, když váš program skončí. Mezitím zní prose v godoc jako obecný slib — výchozí příkaz „sends SIGKILL to any open browsers when the Go program exits“ — ale Linuxové omezení je jen ve zdrojích s build tagem, které si musíte přečíst sami. Tvrdit, že dokumentace přehání, je fér; tvrdit, že je to chyba chromedp, fér není.
Praktický důsledek ale platí v obou případech: na macOS je defer cancel() nosný prvek. Vynecháte ho a každý běh po sobě zanechá browser proces. Linux jsem netestoval, takže výsledek s orfanizací tam negeneralizuji — zdroj napovídá, že se Linux chová jinak, ale nápověda není měření.
Cold start, konkurence a nudné věci, které rozhodují o nasazení

102 ms byl medián od nového procesu, allocatoru, contextu, navigace na localhost a prvního Evaluate napříč pěti procesy, s rozsahem 98 až 111 ms (coldstart-summary.json). Na tomto fixture macOS arm64 s teplým headless shellem na disku byl start malý ve srovnání se čekáním na opožděný obsah. Kontejnery, studené filesystemy, CI, serverless prostředí ani produkční navigace měřeny nebyly.
V oblasti concurrency vám chromedp dává dvě podoby — jeden browser s několika dětskými contexty (tabe), nebo několik samostatných browserů. Čtyři navigace, tři běhy každá (concurrency-summary.json):
| Režim | Celkový čas (p50) | Rozsah | Maximální počet Chrome browser procesů |
|---|---|---|---|
| Sdílený browser, 4 child contexty | 214 ms | 209–219 | 1 |
| 4 samostatné browsery | 264 ms | 261–278 | 4 |
Měřeným zjištěním je počet procesů: jeden Chrome browser proces versus čtyři pro tyto čtyři triviální lokální navigace. Rozsahy wall-time se nepřekrývaly, ale stále jde spíš o směrový výsledek než o benchmark propustnosti. RSS ani PSS se neměřily, takže tento test neprokazuje úsporu paměti.
Malý probe na chybové cesty zde není dost podrobný na to, aby dovolil tvrzení o robustnosti: draft neuvádí, zda se jednotlivé stavy projevily jako HTTP status, navigační chyba, event nebo harness logika. Považujte proto zpracování 500/dead-link za nezdokumentované, dokud nebude zveřejněn přesný výsledek API i surový artefakt.
Netestováno, a tedy mimo rozsah těchto čísel: chování lifecycle na Linuxu, konkurence nad N=4 nebo s reálnou prací na stránce, rozdíly v paměti (počítal jsem procesy, ne RSS), network interception a capture požadavků, a otevřené hlášení WaitReady timeoutů v #168 a #1593 — ty popisují občasné timeouty, zatímco já jsem měřil semantiku čekání, což je jiná otázka. Jeden stroj, jeden build Chromu.
chromedp není jediný Go CDP driver na tomto stole: rod prošel stejným fixturem, harness, hostitelem i buildem Chromu ve stejné session a dostal vlastní článek.
Klady a zápory
Klady:
- Skutečný přístup k CDP — pohodlné akce i syrové
cdprotodoménové volání lze skládat ve stejnémRun, takže nenarazíte na API strop. - Lokální základní cold-cycle 102 ms p50 s rozptylem 98–111 ms na testovaném macOS fixture.
- Zrušení reálně sebere Chrome zhruba za 13 ms, konzistentně, při každém běhu.
- Child contexty sdílejí jeden browser proces pro N tabech (1 proces místo 4 u samostatných browserů).
- Deterministické v testech — recall sady, semantika čekání i lifecycle výsledky byly ve třech opakováních vždy stejné.
- Čisté zacházení s deadlinem:
WaitVisiblena nesplnitelné podmínce vrátilo přesně po 4 s správnýcontext deadline exceeded, místo aby se zaseklo. - Modul v čistém Go (bez cgo), s licencí MIT; při běhu je ale stále potřeba externí spustitelný Chrome.
Zápory:
- Vyžaduje externí Chrome za běhu; pověst „bez závislostí“ platí jen pro Go modul.
WaitReady("body")je past, která vypadá správně a potichu mine obsah načtený po loadu — vrátila se za 107 ms s neúplnou stránkou.- Naivní cesta
Navigate+ čtení mine vše, co se injektuje zhruba ≥ 100 ms po loadu, deterministicky a bez chyby. - Na macOS ukončení bez
cancel()zanechá browser jako osiřelý proces (3/3 běhy). Je to známé a platformně omezené chování, ale snadno se na něm spálíte. - Formulace godoc o SIGKILL při ukončení působí univerzálně, ale mechanismus je ve skutečnosti jen v Linuxu přes build-tagované zdroje.
go testna Go 1.25+ může rušit start allocatoru (#1591); raději buildněte binárku.- Vrací DOM, ne strukturovaná data — každý požadovaný field je parsovací kód, který si musíte napsat a udržovat sami.
- Nejnovější tag (v0.16.0) je před nejnovějším GitHub Release objektem (v0.15.1), což může krátce mást při ověřování verzí.
Pro koho je chromedp vhodné a kdo by se mu měl vyhnout
Pokud už vaše služba běží v Go a potřebujete v ní skutečný prohlížeč, chromedp je téměř očividná volba. Žádný Node proces k hlídání, žádný WebDriver server k udržování při životě, jedna zkompilovaná binárka plus Chrome, který si dodáte nebo nainstalujete. Context model se přímo mapuje na Go concurrency primitivy, takže životnost browseru nakonec řídí stejná disciplína defer jako zbytek kódu. A pokud potřebujete něco, co pohodlné API nepokrývá — CDP network eventy, přesné lifecycle hooky stránky, trikové operace na úrovni protokolu — jednoduše přejdete do cdproto bez opuštění knihovny.
Je to také dobrá volba, když chcete explicitně řídit čekání. Wait akce jsou primitiva, ne heuristiky; dělají přesně to, co říkají, což je výhoda, jakmile přijmete, že správná volba je už váš úkol.
Vyhněte se mu, pokud váš tým nepíše v Go — závazek k jazyku je skutečný náklad, ne knihovna. Vyhněte se mu, pokud chcete ergonomii s automatickým čekáním, která za vás správně hádá, protože chromedp nebude hádat; udělá přesně to, co jste řekli, a vrátí stav stránky v ten okamžik. Vyhněte se mu, nebo si na něj vyhraďte pořádný rozpočet, pokud ve skutečnosti potřebujete strukturované záznamy a ne DOM: každý field je selector, který píšete, testujete a opravujete, jakmile se web změní. A pokud celé zadání zní jen „dej mi data z těchto 500 URL“, je spuštění browser orchestrace v Go na takovou práci dost těžká mašinerie. Náš průvodce browser automation ukazuje, kdy se tahle mašinerie vyplatí a kdy ne.
Alternativy a místo našeho vlastního stacku
V kategorii browser driverů je rod další Go CDP driver, zatímco Playwright a Puppeteer jsou Node-side možnosti, které rozebíráme v článku Playwright vs Puppeteer. Jejich waiting kontrakty nejsou zaměnitelné. Playwright před mnoha akcemi automaticky čeká na actionability; ani to ale neříká, kdy přestala přicházet aplikační data po akci. chromedp vám dává nízkoúrovňová wait primitiva a nechává na volajícím jak actionability, tak podmínky připravenosti na úrovni aplikace. Pokud mapujete širší terén, náš přehled open-source scraperů, které jsme testovali pokrývá statické crawlery a extrakční knihovny na druhé straně této hranice.
Související recenze: recenze Browserless.
Spravovaná extrakční služba je jiná kategorie. Vyměňuje kontrolu nad browserem a selektory za outsourcované renderování a tvarování schématu. To se může hodit, když je výstupem strukturovaný záznam a ne DOM, zatímco chromedp je lepší volba tehdy, když prohlížeč musí zůstat pod kontrolou vaší Go služby. Vyvíjíme Thunderbit, takovou službu, ale na tento fixture jsme ji nespouštěli; tento test tedy nepodporuje žádné tvrzení o ekvivalenci, latenci, kvalitě extrakce ani ceně ve srovnání s chromedp.
Vyzkoušet Thunderbit pro extrakci webových dat
Verdikt
Měli byste použít chromedp? Ano, pokud píšete v Go a chcete mít skutečný prohlížeč pod kontrolou. V tomto lokálním fixture se dostal k prvnímu výsledku skriptu za 102 ms p50, po zrušení sebral Chrome asi za 13 ms a pro čtyři současné tabe používal jeden browser proces. To jsou ohraničená pozorování, ne univerzální sliby výkonu; trvalá přitažlivost spočívá v přímém přístupu k CDP z Go, když pohodlná vrstva dojde na limity.
Jen je potřeba správně nastavit očekávání, protože reputace přehání dvě věci. „Pure Go, bez závislostí“ popisuje modul; za běhu ale dodáváte a spravujete binárku Chromu. A „použij headless browser a dostaneš dynamický obsah“ platí jen tehdy, když je vaše čekání navázané na konkrétní node, který chcete — naivní čtení i WaitReady("body") mi opakovaně vrátily stránku bez obsahu vloženého 800 ms po loadu, bez jakékoli chyby. Na macOS není defer cancel() stylová preference; vynechte ho a při každém běhu vám uteče browser, což je známé platformní chování, ale pořád váš problém k řešení. Pokud tyto tři věci uděláte správně, je chromedp jedním z nejpředvídatelnějších browser driverů, které jsem měřil. Pokud je uděláte špatně, bude selhávat potichu, a to je pro scraper ten nejhorší typ selhání.
Vyzkoušet Thunderbit pro extrakci webových dat Get Started Free
Časté dotazy
Vidí chromedp opravdu obsah vykreslený JavaScriptem?
Ano — ale jen tehdy, když čekání cílí na node, který chcete. Na fixture, kde byl odkaz vložen 800 ms po události load, Navigate plus čtení ho minuly a WaitReady("body") ho minulo také, zatímco WaitVisible na daném nodu a JavaScript polling ho oba zachytily, ve třech ze tří běhů. Když jsem procházel různá zpoždění, čtení bez čekání minulo node při každé hodnotě od 100 ms výše. Renderování je nutné; správné čekání z něj dělá dostatečnou podmínku.
Jaký je rozdíl mezi WaitReady a WaitVisible?
WaitReady čeká, až je node připojený do DOM. WaitVisible čeká, až je opravdu viditelný. Na nodu, který je připojený, ale má display: none, se WaitReady vrátil asi za 6 ms, zatímco WaitVisible čekal až do 4sekundového deadlinu a vrátil čisté context deadline exceeded. Ani jedno není „spolehlivější“ — odpovídají na různé otázky a skutečná past je vybrat špatně.
Opravdu potřebuji s chromedp defer cancel()?
Na macOS ano. Zrušení contextu i allocatoru v každém běhu vyčistilo spuštěný Chrome za 12–13 ms; ukončení Go procesu bez zrušení ponechalo ve všech třech bězích osiřelý browser proces. Jde o známé chování omezené na platformu — tracker chromedp dokumentuje stejný vzorec neukončení i na jiných ne-Linux systémech a parent-death kill, který to řeší, je jen v Linux build-tagovaných zdrojích. Linux jsem netestoval, proto výsledek s osiřelým procesem berte jako omezený na macOS.
Potřebuje chromedp nainstalovaný Chrome zvlášť?
Ano. Samotný Go modul je v čistém Go bez cgo, ale ovládá externí browser a bez něj okamžitě selže. Explicitně jsem dodal headless shell Chrome for Testing 151.0.7922.10 přes chromedp.ExecPath. Výhoda je, že náklad na start je malý: celý cold cycle k prvnímu výsledku skriptu měl medián 102 ms napříč pěti novými procesy, v rozmezí 98–111 ms.
Mám sdílet jeden browser mezi tably, nebo spouštět samostatné browsery? Pokud je cílem minimalizovat počet browser procesů, preferujte child contexty. Čtyři navigace na localhost přes jeden browser použily 1 Chrome browser proces; čtyři samostatné browsery použily 4. I wall time vyšel lépe pro sdílené nastavení (medián 214 ms proti 264 ms), ale čtyři triviální lokální stránky nejsou benchmark propustnosti. Paměť se neměřila. Samostatné browsery ale mohou být správnou volbou, pokud potřebujete silnější izolaci session, různé proxy nebo menší dopad pádu; tyto kompromisy byly mimo tento test.


