Обзор Browserless: Chrome как сервис с ограниченной пропускной способностью

Последнее обновление: August 14, 2026
Обзор Browserless: Chrome как сервис с ограниченной пропускной способностью
AI-сводка
Browserless — это headless Chrome, упакованный в сервис, который вы разворачиваете у себя. Его Docker-контейнер работает постоянно, принимает задачи по HTTP или WebSocket и управляет доступом через...

Browserless — это headless Chrome, упакованный как сервис, который ты разворачиваешь у себя. Его Docker-контейнер постоянно работает, принимает задачи по HTTP или WebSocket и управляет доступом через общие лимиты, а не встраивается в каждый вызывающий процесс. В REST-тестах здесь у сервиса было 0 процессов Chrome в простое: процессы Chrome появлялись только во время активного запроса и исчезали после него. То, что реально «пулится», — это пропускная способность сервиса и очередь, а не заранее прогретый набор браузерных процессов.

Я прогнал v2.55.0 на контролируемом локальном стенде — разложил запуск по этапам, проверил контроль доступа в трёх конфигурациях, сверил ответы эндпоинтов с известной эталонной картиной, сделал прогон из 30 сессий и проверил границу таймаута. Практическая польза оказалась не в ускорении, а в эксплуатации: лимиты доступа совпадали с тем, что видел клиент, а основные подводные камни были связаны с развёртыванием.

Самый полезный результат — не цифра задержки. Browserless не ускоряет старт Chrome, а ставит Chrome в режим «контрольно-пропускного пункта»: внутри одновременно находится фиксированное число сессий, за ними стоит очередь, а всем остальным возвращается HTTP 429. Этот потолок менялся с 4 до 8 и до 10, когда я менял две переменные окружения, и собственный учёт контейнера полностью совпадал со статус-кодами клиента на каждом запросе.

Что Browserless представляет собой на самом деле

Чаще всего люди ошибаются именно на уровне категории. Browserless — это не библиотека, которую ты импортируешь и вызываешь. Это Docker-образ — ghcr.io/browserless/chromium, — который запускается как долго живущий сервис. Он обслуживает браузерные задачи и отдаёт их двумя способами: через REST-эндпоинты (/content, /scrape, /screenshot, /pdf, а также /function и /unblock) и через CDP/WebSocket-интерфейс, к которому могут подключаться Puppeteer и Playwright с помощью connect().

Я тестировал REST-поверхность. WebSocket-путь тоже рабочий и широко используется, но я его не измерял.

Тестировалась версия v2.55.0, проверка выполнена 27 июля 2026 года.

ПараметрЗначение
Версия образаv2.55.0, опубликована 14 июля 2026
Chrome149.0.7827.0
Node24.18.0
Базовый образUbuntu 24.04
Звёзды GitHubпримерно 13 525 на 27 июля 2026

Количество звёзд меняется со временем, поэтому воспринимай это как снимок на конкретный момент.

Лицензия: SSPL-1.0 или коммерческая

В репозитории Browserless распространяется по лицензии SSPL-1.0 или по коммерческой лицензии Browserless. Перед выбором обязательно прочитай актуальный файл LICENSE и официальные рекомендации по open-source-развёртыванию. В этой статье не проводился юридический анализ коммерческих продуктов, закрытого ПО, CI-систем, хостинговых сервисов или внутренних развёртываний, поэтому конкретные сценарии к лицензии здесь не привязываются. Пусть юрист или тот, кто отвечает за лицензирование ПО, оценит модель поставки и распространения.

Browserless также продаёт облачные планы. Цены и определение единиц использования могут меняться, и в этом self-hosted-тесте они не участвовали, так что проверяй их на официальном сайте, а не используй устаревшую таблицу как доказательство для закупки.

Как работает модель сессий внутри

Измеренный REST-путь вёл себя как браузерная работа на каждый запрос, но этот стенд не заглядывал достаточно глубоко во внутренности Browserless, чтобы отличить новый процесс браузера от любой стратегии повторного использования контекста. Однако удалось установить более простую вещь: 0 процессов Chrome в простое, 11 процессов семейства chrome во время активного запроса и снова 0 после последовательного прогона. В этой конфигурации не было признаков заранее прогретого пула браузеров.

Долго живущий Node-сервис пропускает ограниченное число браузерных задач, ставит в очередь ещё ограниченное число и всё остальное отклоняет. Считай эту модель доступа архитектурным контрактом, который проверяется ниже. Не делай вывод о повторном использовании процессов или контекстов только из слова «pool»; данный стенд не может этого доказать.

У контроля доступа есть две ручки:

  • CONCURRENT — сколько сессий выполняется одновременно.
  • QUEUED — сколько дополнительных запросов может ждать слот.

Эндпоинт контейнера /config показывал значения по умолчанию: CONCURRENT=10, QUEUED=10, TIMEOUT=30000. Всё, что выходит за пределы CONCURRENT + QUEUED, отклоняется сразу.

Аутентификация обязательна. Browserless v2 всегда требует токен — если не задать TOKEN, он сгенерирует случайный и выведет его в stdout при запуске. Каждый REST-вызов должен содержать ?token=.

Для наблюдаемости доступны /pressure (running, queued, CPU, memory, recently rejected), /sessions и /config. Есть ещё JSON-экспорт /metrics, но он требует переменную METRICS_JSON_PATH, а я её не использовал. Кроме того, образ запускает dumb-init как PID 1 — это и есть документированный ответ на жалобы о zombie-процессах, которые уже много лет сопровождают контейнерный Chrome.

Реалии настройки: одна команда и четыре вещи, которые в одну команду обычно не помещают

Та самая команда установки, которую все цитируют, действительно сводится к одному docker run. Но всё, что вокруг, тоже важно учесть.

Размер образа — 4,34 ГБ. Вот эта цифра должна задавать ожидания, а не время старта. Манифест содержит и linux/arm64, и linux/amd64; на моём arm64-хосте Docker скачал нативный arm64-вариант. (User-Agent Chrome внутри контейнера всё равно выглядит как X11; Linux x86_64 — это обычный косметический UA Chrome на Linux, а не эмуляция. uname -m показывает aarch64. На это люди часто жалуются как на баг.)

Для всех измерений я использовал --shm-size=2g. В стенде не было контрольного прогона на стандартном /dev/shm Docker, поэтому эта статья не может утверждать, что 2 ГБ абсолютно обязательны, или точно назвать точку отказа. Размер нужно подбирать под число браузеров и характер нагрузки.

Токен — это не формальность, а вопрос безопасности развёртывания. Без него любой, кто может достучаться до порта 3000, фактически получает браузер в твоей сети.

Сетевое взаимодействие контейнера — твоя зона ответственности. Мой стенд работал на хосте, поэтому контейнер обращался к нему через host.docker.internal (colima подставляет это через --add-host host.docker.internal:host-gateway). Перед тем как доверять измерениям, я отдельно проверил обычным curl, что контейнер действительно видит стенд.

Моя среда: colima 0.10.3 (6 CPU / 11.6 GiB) с Docker 29.2.1 на macOS 26.5.2 arm64. Стенд был только на стандартной библиотеке Python 3. Для PNG и PDF проверялись сигнатуры файлов, а не корректность декодирования, размеры, число страниц, полнота или визуальная точность.

Минимально эквивалентный запуск использует зафиксированный образ, явный токен и то выделение shared memory, которое применялось здесь:

docker run --rm -p 3000:3000 --shm-size=2g \
  -e TOKEN=replace-with-a-secret \
  ghcr.io/browserless/chromium:v2.55.0

После ответа /pressure?token=... аутентифицированный POST /content?token=... с JSON-телом, содержащим целевой URL, проверяет REST-путь. В продакшене клиентам также нужен ограниченный retry с jitter для ответов 429; если повторять сразу, ты просто снова врезаешься в ту же заполненную очередь.

Стоимость запуска, разложенная по этапам

Measured results chart: Observed Browserless startup stages

Три свежих запуска docker run, медиана и диапазон min–max:

ЭтапМедианаДиапазонЧто это на самом деле
docker run/pressure возвращает 2000,78 с0,70–0,87 сHTTP-эндпоинт уже отвечает; запуск браузера этим шагом не подтверждается
готовность → первый рендер /content0,32 с0,28–0,41 спервый наблюдаемый запрос: работа браузера + переход + возврат HTML
последующие вызовы /content0,15 с0,147–0,154 сзадержка последующих запросов в том же контейнере

Среднюю строку легко неправильно интерпретировать. Она не измеряет запуск браузера изолированно и не показывает, что Browserless стартует Chrome быстрее, чем in-process библиотека. Это HTTP-круговой путь в контейнер плюс работа браузера, навигация и передача ответа. Разница примерно в 0,17 секунды между первым и последующими запросами может включать влияние файловой системы, ОС, Chrome, Node или кэша контейнера. Поскольку в простое процессов Chrome не было, а этот стенд не снимал CDP-трейс и таймлайн процессов для этих вызовов, приписать этот зазор повторному использованию браузера или «амортизированному» запуску нельзя.

И ещё: это цифры из colima VM на macOS. На bare-metal Linux будет иначе. Не цитируй 0,78 с своему SRE как переносимую универсальную метрику.

Практика: как найти потолок с обеих сторон

Контракт CONCURRENT + QUEUED → 429 повторяется везде, но почти нигде не демонстрируется.

Схема теста: страница-стенд намеренно спит на сервере 5 секунд, чтобы каждый запрос гарантированно занимал одну сессию известное время. Затем одновременно отправляется CONCURRENT + QUEUED + 4 запросов, и смотрится, что вернётся, — пока отдельный поток-датчик опрашивает /pressure, чтобы читать внутренний учёт контейнера.

Конфигурация (CONCURRENT, QUEUED)ОтправленоHTTP 200HTTP 429Пик по /pressure на сервере (running / queued / recentlyRejected)
(2, 2)8442 / 2 / 4
(3, 5)12843 / 5 / 4
(5, 5)141045 / 5 / 4

Из этого следуют три вещи.

Потолок каждый раз равен ровно CONCURRENT + QUEUED. Успешных ответов было 4, 8 и 10 — то есть сумма настроек в каждом случае. Количество отказов совпадало с избыточным объёмом, а он во всех трёх прогонах был 4.

Потолок меняется. Он не зашит в образ; он такой, как ты его настроил. Переход 4 → 8 → 10 только за счёт переменных окружения — вот что делает это полезным, а не просто любопытным.

И ещё: два сигнала независимы. Статус-коды моего клиента приходили из реальных HTTP-ответов; /pressure — из внутреннего учёта контейнера, который опрашивался другим потоком. В этих трёх коротких прогонах они совпали. Это делает /pressure кандидатом на продакшен-сигнал, но не полноценным контрактом для автоскейлинга: нужно ещё проверять частоту опроса, семантику сброса, агрегацию по нескольким репликам и поведение на более длинных смешанных нагрузках.

Есть один нюанс, который скрывают только counts pass/fail. Запрос в очереди не падает — он ждёт, и иногда довольно долго. При (2, 2) и 5-секундной работе успешные ответы пришли в диапазоне от 5,7 до 11,0 секунды, медиана — 8,3 секунды. Значит, полная задержка доходила примерно до двух длительностей сессии. Стенд не снимал отдельные метки времени для момента допуска и момента выполнения, поэтому полностью отнести задержку именно к ожиданию в очереди нельзя.

Как это выглядит на реальной задаче

Допустим, ты ночью рендеришь в PDF 4 000 карточек товаров, и на каждую уходит около 5 секунд. Ты ставишь CONCURRENT=5, QUEUED=5. Верхний предел пропускной способности — 5 страниц за 5 секунд, то есть одна страница в секунду, а значит вся задача займёт примерно 67 минут, если держать поток ровно заполненным. Это арифметика на основе измеренного поведения, а не бенчмарк, но именно такую арифметику стоит делать до развёртывания.

Любой запрос, который приходит после того, как все рабочие и очередные слоты заняты, может сразу получить 429; одновременная отправка не гарантирует, какой по счёту запрос проиграет гонку. Исполнитель задач должен воспринимать такой ответ как backpressure и делать ограниченный retry с jitter. Иначе можно потерять страницы, пока верхнеуровневый учёт задач продолжит жить как ни в чём не бывало — это операционный риск, а не сценарий сбоя, продемонстрированный этим стендом.

Практика: что на самом деле видят эндпоинты

Чтобы честно проверить точность рендера, тестовая страница прячет маркерный текст от любого, кто не запускает настоящий браузер. Видимая строка Runtime Injected Marker 88 собирается из JavaScript-фрагментов во время загрузки, так что непрерывного литерала для неё нет ни в одном байте, отправляемом сервером. Обычный статический fetch этой страницы возвращает 702 байта, в которых нет ни одного из маркеров.

ЭндпоинтРезультатБайт
/contentruntime-вставленный маркер присутствует, плюс оба статических маркера811
/scrape на #scrape-me (узел, вставленный JS)вернул SCRAPE_TARGET_VALUE_CC422
/screenshotответ с PNG-сигнатурой 89 50 4E 4718 621
/pdfответ с PDF-сигнатурой %PDF-40 974
все четыре без токенаHTTP 401 (не 403)

То, что /content возвращает 811 байт с внедрённым маркером, означает: страницу реально отрендерил Chromium, прежде чем HTML вернулся обратно. /scrape вытащил значение из узла, которого не существует до выполнения JavaScript. Оба сценария сработали без клиентского automation-кода — достаточно одного аутентифицированного POST.

В этом и есть суть. В той же серии проверок статический crawler полностью пропустил такой класс контента, а in-process браузерные библиотеки (chromedp, rod, Selenium) справились только после того, как я явно добавил ожидание. Browserless справился запросом формата curl. Ты меняешь automation-код на вес развёртывания.

Две оговорки к этому тезису. Доказательства относятся к классам контента моего стенда, а не ко всему современному вебу. И /unblock, антидетект-эндпоинт, я сознательно не трогал — ни один из результатов не следует трактовать как подтверждение антибот-возможностей. /function, /download и /performance тоже не тестировались.

Практика: короткая проверка на остатки

У контейнерного Chrome есть репутация оставлять трупы процессов, поэтому я прогнал 30 последовательных сессий с CONCURRENT=3 и посчитал процессы внутри контейнера.

Прежде чем доверять результатам, я откалибровал детектор. Пока сессия была активна, перечислитель /proc видел 11 процессов семейства chrome (браузер, zygote, GPU, рендереры, утилиты). Это важно: инструмент действительно видит Chrome, значит ноль после прогона — это измерение, а не слепота. Тест на утечку, который просто пишет «0 процессов» без доказательства, что он вообще умеет считать, бесполезен.

После 30 сессий: 0 процессов chrome, 0 zombie-процессов. Единственными оставшимися были dumb-init, node, Xvfb, start.sh и sh. /sessions в простое показывал 0.

Память контейнера по данным docker stats — это число, видимое оператору, а не RSS одного процесса:

После N сессий051015202530
Память контейнера (MiB)294300301302302303303

Чистый рост за 30 сессий — около 9,5 МБ, а кривая на выборке плато после 10-й сессии. Это не похоже на простой линейный leak на коротком отрезке. Одно из правдоподобных объяснений — прогрев Node, но эти счётчики процессов и памяти не могут это доказать.

Ограничение по масштабу: 30 последовательных сессий — это небольшой soak, а не endurance и не параллельный прогон. Давние предупреждения EventEmitter listener в issue tracker — как раз тот тип проблем, который может проявиться через часы и тысячи сессий, а я такого теста не делал. Подтверждённый вывод только один: в этом окне на v2.55.0 накопления процессов Chrome или zombie-процессов не наблюдалось.

Граница таймаута

TIMEOUT документирован как настраиваемый параметр. Мне хотелось увидеть, как он срабатывает.

СлучайСтраница удерживаласьСтатусВремя
В пределах бюджета2 000 мс2002,406 с
За пределами бюджета15 000 мс4085,007 с

При TIMEOUT=5000 сессия, которая пыталась удерживать страницу 15 секунд, вернула HTTP 408 ровно на 5,007 секунды, а не зависла. Это единичное наблюдение подтверждает, что ограничение работает рядом с заданной границей. Оно не раскрывает реализацию таймера и не доказывает освобождение слота; более сильный тест повторил бы попытку, проверил бы возврат /sessions и /pressure в idle и затем подтвердил бы, что следующий запрос забирает освободившийся слот.

Ловушка при миграции: PREBOOT молча ничего не делает, но не сообщает об этом

Из всего, что я измерил, это тот результат, который я бы сам хотел получить до апгрейда.

В Browserless 2.0.0 были удалены PREBOOT и KEEP_ALIVE — в changelog сказано, что их убрали, потому что они путали, мало что давали и создавали баги. Решение разумное. Проблема начинается, когда конфигурацию v1 просто копируют в v2 — а это, пожалуй, самый распространённый путь обновления.

Я запускал контейнер с -e PREBOOT=true и сравнивал его с настройками по умолчанию:

СигналPREBOOT=trueПо умолчанию, флаг не задан
Время готовности0,716 с0,776 с
Cold render0,314 с0,318 с
Warm render0,163 с0,150 с
Процессов Chrome в простое00

Все тайминги лежат внутри собственного диапазона min–max у базового варианта — это шум, а не эффект. И ничего не было прогрето: контейнер с PREBOOT=true в простое держит ноль браузеров, ровно как и контейнер без этого флага. Ещё два сигнала, но не цифры:

  • /config вообще не содержит ключа preboot. Там есть concurrent, queued, timeout, token, maxCPU, maxMemory, retries и т. д.
  • Нет ошибки. Нет предупреждения. В логах контейнера — тоже ничего.

То есть конфигурация v1 с PREBOOT на v2 превращается в тихий no-op при обычном старте и проверке логов. Отсутствие ключа в /config плюс неизменившееся поведение — это и есть обнаруживаемый сигнал; Browserless не выдаёт явного отказа или предупреждения. При миграции нужно проверять, что конфигурация действительно применилась, а не считать зелёный старт доказательством того, что каждая переменная окружения сработала.

KEEP_ALIVE — обратный случай, и смешивать его с PREBOOT нельзя. В той же версии его тоже удалили, но он не молчит: точечная проверка контейнера показывает строку Environment variable of "KEEP_ALIVE" is deprecated and ignored. прямо в stdout. Это уже нормальное предупреждение для оператора. Я не прогонял KEEP_ALIVE через тот же измерительный стенд, что и PREBOOT, поэтому сообщаю о нём как о проверке, а не как об измерении. Но направление понятно и важно: тихий ловушкой является только PREBOOT. Browserless честнее сообщает о KEEP_ALIVE, чем это выглядело бы в упрощённой формулировке «v2 игнорирует все ваши флаги v1».

Плюсы и минусы

Плюсы

  • Контроль доступа работает ровно так, как задокументировано, и меняется вместе с конфигурацией — это подтверждено на трёх разных потолках одновременно по статусам клиента и внутреннему учёту сервера.
  • /pressure в трёх коротких прогонах совпал с клиентски видимыми значениями running, queued и rejected; его можно рассматривать как один из входов для автоскейлинга и алертинга.
  • Реальный рендер Chromium без клиентского automation-кода: один аутентифицированный POST показал JS-инжектированный DOM, который статический fetch той же страницы не увидит.
  • За 30 последовательных сессий не накопилось процессов Chrome; после прогона было 0 процессов Chrome и 0 zombie-процессов.
  • Один тест TIMEOUT вернул 408 на 5,007 секунды при бюджете 5,000 секунды; очистка и освобождение слота отдельно не подтверждались.
  • Аутентификация включена по умолчанию: все четыре REST-эндпоинта без токена возвращают 401.
  • Один docker run — и готовый сервис примерно за 0,78 с; первый рендер после этого — ещё через 0,32 с.

Минусы

  • Образ 4,34 ГБ. Это честная цена входа, и она заметна в registry, в CI-кэше и во времени холодного развёртывания.
  • SSPL-1.0 или коммерческая лицензия Browserless. Нужно проверять конкретные условия применительно к твоей модели поставки и распространения.
  • PREBOOT из v1 на v2 принимается и молча игнорируется — без ошибки, без предупреждения, без ключа в /config.
  • Ты разворачиваешь сервис, а не просто подключаешь зависимость: контейнер, токен, сетевой путь, потолок доступности и ответственность за обновления.
  • Запросы в очереди увеличивали end-to-end задержку примерно до двух длительностей сессии в прогоне (2, 2); отдельное время ожидания в очереди не измерялось.
  • Измеренное REST-время включает HTTP-обмен и не выделяет стоимость запуска браузера и не доказывает повторное использование браузера.

Кому это подойдёт, а кому нет

Browserless оправдывает себя, когда браузер нужен не одному компоненту. Общий сервис рендеринга для нескольких приложений, команда, которой нужны скриншоты и PDF через HTTP-эндпоинт вместо зависимости на Chrome в каждом сервисе, пайплайн задач, которому нужен измеряемый потолок и backpressure — вот формат, под который это сделано. Если у тебя уже есть Docker и есть тот, кто отвечает за развёртывание, картина ясна: предсказуемый admission, наблюдаемый backpressure и отсутствие накопления процессов Chrome или zombie-процессов в проверке на 30 сессий.

Это также разумный выбор, если альтернатива — чтобы каждый сервис в стеке ставил себе собственный Chromium. Централизация этого в одном контейнере с токеном и потолком — действительно хороший архитектурный компромисс.

Не стоит брать его, если ты пишешь один скрипт. Тянуть 4,3 ГБ и поднимать контейнер ради одного Python-файла, которому нужно получить отрендеренную страницу, — это слишком много церемоний для маленькой задачи; библиотека браузера в твоём процессе делает то же самое без отдельного сервиса. Не стоит брать его, если условия SSPL не подходят твоему коммерческому продукту и ты не можешь это урегулировать. Не стоит брать его, если тебе нужен браузер, который приходит уже прогретым и без холодного старта: PREBOOT в v2 этого не даст. И не стоит брать его, если твоя настоящая задача — борьба с антиботом, потому что это относится к эндпоинту, который я сознательно не тестировал и за который не ручаюсь.

Альтернативы, и где здесь место Thunderbit

Сравнивать Browserless стоит не с другим контейнером, а с тем, где живёт браузер и кто отвечает за его постоянную работу.

Похожий обзор: обзор Browsertrix Crawler.

Похожий обзор: обзор chromedp.

Браузерная библиотека (chromedp, rod, Selenium, Playwright)Browserless self-hostedУправляемое извлечение Thunderbit
Где работает браузерВ твоём процессеВ твоём контейнереНа чужой инфраструктуре
Стоимость стартаУстановка пакетаОбраз 4,3 ГБ + контейнер + токенAPI-ключ
Тайминг, измеренный здесьВ этой статье не измерялсяПервый рендер через 0,32 с после HTTP-ready; последующие вызовы — медиана 0,15 сВ этой статье не измерялся
Что ты пишешьAutomation-код с явными ожиданиямиОдин аутентифицированный POSTОдин HTTP-вызов
Что возвращаетсяТо, что ты сам запрограммировалHTML, PNG/PDF по сигнатурам, извлечённые узлыСтруктурированный JSON или Markdown под конкретный продукт
Лимит мощностиТвой компьютерCONCURRENT + QUEUED, затем 429План провайдера
Кто дежуритТыТыОни

Если тебе нужен браузер внутри собственного процесса и тебя не пугает писать ожидания, библиотека легче и без отдельного развёртывания. Эту сторону я разобрал в сравнении Playwright и Puppeteer и в более широком обзоре open-source-проектов для веб-скрейпинга.

Если же ты не хочешь вообще обслуживать браузер, наш Thunderbit — это один из управляемых вариантов. Browserless возвращает отрендеренный материал, который интерпретирует твой код; Thunderbit может возвращать Markdown или данные, совпадающие со схемой, а инфраструктуру рендеринга берёт на себя провайдер. В этой статье не измерялись задержка Thunderbit, пропускная способность, поведение при сбоях, качество извлечения или стоимость, поэтому таблица описывает границы ответственности, а не сравнение производительности.

Ещё одно чтение из той же серии тестов: обзор Crawl4AI описывает браузерный Markdown-пайплайн, который ты запускаешь сам, а обзор инструментов для веб-скрейпинга показывает более широкую картину категории.

Попробовать Thunderbit для извлечения веб-данных

Итог

Стоит ли запускать Browserless? Да — если браузерная работа нужна нескольким потребителям, кто-то может обслуживать контейнер, а проверка лицензии одобряет такую модель развёртывания. В трёх синтетических прогонах admission число принятых запросов совпадало с CONCURRENT + QUEUED, лишние получали 429, а /pressure совпадал с тем, что видел клиент. В отдельной проверке на 30 последовательных сессиях не накопилось ни процессов Chrome, ни zombie-процессов. Один тест на timeout вернул 408 рядом с заданной границей. Это полезные ограниченные наблюдения, но не универсальные гарантии.

Но и обязательства нужно оценивать честно. Это образ размером 4,34 ГБ и сервис, которым нужно управлять, а не просто зависимость; этот тест не доказал, что он быстрее in-process браузерной библиотеки. Его ценность в том, что браузер можно нормировать: известный потолок и измеряемый backpressure. В проверке на 30 сессий не наблюдалось накопления процессов Chrome или zombie-процессов. Цена — вес развёртывания и лицензия, которую нужно прочитать. Если ты рендеришь несколько страниц из одного скрипта, такой обмен не окупается. Если же ты строишь слой рендеринга, от которого зависят несколько сервисов, — тогда да; только проверь свои переменные окружения v1 при миграции, потому что PREBOOT будет выглядеть занятым, но ничего не делать.

Попробовать Thunderbit для извлечения веб-данных Get Started Free

Частые вопросы

Ускоряет ли Browserless headless Chrome? Этот тест не позволяет так утверждать. HTTP-эндпоинт стал доступен через 0,78 с после docker run; первый вызов /content занял 0,32 с, а последующие вызовы в том же контейнере — около 0,15 с. Эти цифры включают HTTP-обмен, работу браузера, навигацию и передачу ответа. Стенд не выделял отдельно время запуска, не отслеживал повторное использование процессов и не публиковал сопоставимый in-process бенчмарк. Используй Browserless как сервис с общим контуром и контролем доступа, а затем измеряй именно свой путь задержки.

Что происходит при превышении лимита параллельности в Browserless? Ты сразу получаешь HTTP 429. Потолок точно равен CONCURRENT + QUEUED, и я подтвердил это в трёх конфигурациях: (2,2) приняла 4 и отклонила 4, (3,5) приняла 8 и отклонила 4, (5,5) приняла 10 и отклонила 4. Эндпоинт /pressure на сервере каждый раз показывал согласованные значения running, queued и recentlyRejected. Важно помнить: запросы в очереди не падают, они ждут — при (2,2) и 5-секундной работе успешные ответы приходили от 5,7 до 11,0 секунды. Клиент должен трактовать 429 как backpressure и делать retry с backoff.

Работает ли PREBOOT в Browserless v2? Нет. PREBOOT был удалён в 2.0.0, и v2 принимает -e PREBOOT=true без ошибки и предупреждения, но ничего с ним не делает. Я подтвердил это тремя способами: задержки не отличались от дефолтных, у простоявшего PREBOOT=true контейнера было 0 ожидающих процессов Chrome, а /config вообще не содержит ключа preboot. Если ты мигрировал конфигурацию v1, твои экземпляры не прогреты. Заметь, что KEEP_ALIVE, удалённый в той же версии, всё же пишет предупреждение "deprecated and ignored" — то есть проблема тихого отказа относится именно к PREBOOT.

Бесплатен ли Browserless для коммерческого использования? В репозитории доступны SSPL-1.0 или коммерческая лицензия Browserless, но эта статья не сопоставляет конкретные коммерческие или закрытые сценарии с тем или иным вариантом. Изучи текущие LICENSE и официальные рекомендации по развёртыванию, а затем пусть человек, ответственный за лицензирование ПО, оценит твою модель поставки и распространения.

Остаются ли за Browserless zombie-процессы Chrome? В протестированном коротком окне — нет. После 30 последовательных сессий в контейнере было 0 процессов Chrome и 0 zombie-процессов; оставались только dumb-init, node, Xvfb, start.sh и sh. Детектор видел 11 процессов семейства chrome, пока сессия была активна, так что он не был «слепым». Память контейнера выросла с 294 MiB до 303 MiB и затем вышла на плато в выборке. Это не результат многчасовой, параллельной или тысячесессионной проверки на устойчивость.

Ke
Ke
Технический директор в Thunderbit | Senior Data Scientist и эксперт по ML Имея почти десятилетний опыт в машинном обучении и data science, Кэ Шэнь — выпускник Колумбийского университета и бывший Senior Data Scientist в Walmart Labs. Обладая глубокой, признанной коллегами экспертизой в Python, R, Java и статистике, он делится проверенными на практике наблюдениями о том, как переводить сложные AI-алгоритмы из теории в production-grade архитектуру.
Содержание
Thunderbit · AI-агент для веб-данных

Извлеки данные с любой страницы за 1 клик

Доверяют более 250 000 пользователей
есть бесплатный план
От веб-страницы к таблице
Опиши, что тебе нужно — AI Agent Thunderbit соберет данные и экспортирует их в Excel, Google Sheets, Airtable или Notion. Начать можно бесплатно.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week