BadB
Professional
- Messages
- 2,544
- Reaction score
- 2,676
- Points
- 113
Различия в производительности и артефактах при использовании OffscreenCanvas в Chrome vs Firefox.
Когда ты передаёшь OffscreenCanvas из воркера в основной поток через transferToImageBitmap(), ты не просто рисуешь пиксели. Ты запускаешь цепочку низкоуровневых вызовов, которая проходит через GPU-драйвер, композитор и движок рендеринга. И именно здесь Chrome и Firefox расходятся — не на уровне JavaScript, а на уровне машинного кода и архитектуры.
В этой статье мы разберём, как поведение при передаче выдаёт движок рендеринга, какие артефакты возникают, и почему 90% кардеров терпят неудачу, даже не подозревая об этом.
Ключевой метод — transferToImageBitmap(). Он:
Но то, как именно это происходит — зависит от движка:
Эти различия проявляются в производительности, латентности и артефактах.
Даже при одинаковом коде рисования, результаты будут отличаться:
Эти различия невидимы глазу, но алгоритмы анализа Canvas (например, в PixelScan или FingerprintJS Pro) их ловят через статистику пикселей: распределение яркости, градиенты, шум.
Проблема:
Кардеры используют универсальный код вроде:
Но не учитывают, что Chrome и Firefox требуют разного поведения после передачи.
Исправление:
Адаптируй код под целевой браузер:
Проблема:
Кардеры не замеряют, сколько времени занимает transferToImageBitmap(). Но фрод-движки делают это автоматически.
Если твой «Chrome» профиль показывает время передачи 7 мс — тебя помечают как Firefox или VM.
Исправление:
Добавь микро-замер и эмулируй естественную задержку:
Проблема:
Кардер проверяет только, что картинка «нарисовалась», но не анализирует статистику пикселей.
Исправление:
Используй инструменты для глубокой проверки:
Если твой Chrome-профиль показывает grayscale anti-aliasing — это Firefox. Исправляй настройки рендеринга в антидетект-браузере.
Те, кто думает, что достаточно «включить OffscreenCanvas», обречены на провал. Те же, кто понимает, что каждая передача — это отпечаток движка, получают преимущество.
Настрой правильно — и пусть твои вбивы проходят так же естественно, как рендеринг в браузере настоящего пользователя.
Удачи в кардинге.
Введение: Не просто Canvas — это окно в ядро браузера
Большинство кардеров думают, что OffscreenCanvas — это просто «ускоренный Canvas для воркеров». Они копируют примеры из MDN, вставляют в профиль и считают задачу решённой. Но на самом деле OffscreenCanvas — это один из самых тонких, но мощных каналов утечки информации о внутреннем устройстве браузера.Когда ты передаёшь OffscreenCanvas из воркера в основной поток через transferToImageBitmap(), ты не просто рисуешь пиксели. Ты запускаешь цепочку низкоуровневых вызовов, которая проходит через GPU-драйвер, композитор и движок рендеринга. И именно здесь Chrome и Firefox расходятся — не на уровне JavaScript, а на уровне машинного кода и архитектуры.
В этой статье мы разберём, как поведение при передаче выдаёт движок рендеринга, какие артефакты возникают, и почему 90% кардеров терпят неудачу, даже не подозревая об этом.
Часть 1: Как работает OffscreenCanvas на самом деле
OffscreenCanvas позволяет выполнять рендеринг вне основного потока — в Web Worker. Это критически важно для производительности, но также открывает доступ к низкоуровневым особенностям рендеринга.Ключевой метод — transferToImageBitmap(). Он:
- Фиксирует текущее состояние canvas,
- Передаёт его в основной поток как ImageBitmap,
- Освобождает ресурсы в воркере (zero-copy transfer).
Но то, как именно это происходит — зависит от движка:
- Chrome (Blink + Skia): Использует GPU-бэкенд Skia (Vulkan/Metal/D3D12),
- Firefox (Gecko + WebRender): Использует собственный растеризатор WebRender с акцентом на CPU+GPU гибрид.
Эти различия проявляются в производительности, латентности и артефактах.
Часть 2: Микроскопические различия между Chrome и Firefox
Производительность и латентность
| Параметр | Chrome (Blink/Skia) | Firefox (Gecko/WebRender) |
|---|---|---|
| Инициализация контекста | ~8–12 мс (GPU-accelerated) | ~15–25 мс (гибридный старт) |
| Передача через transferToImageBitmap() | ~1–3 мс (zero-copy GPU → CPU) | ~4–8 мс (CPU-GPU sync required) |
| Поведение при ошибке | Тихо возвращает чёрный ImageBitmap | Выбрасывает исключение в воркере |
Практическое следствие:
Если твой профиль заявлен как Chrome, но время передачи >5 мс — фрод-движок помечает тебя как «поддельный».
Артефакты рендеринга
Даже при одинаковом коде рисования, результаты будут отличаться:- Chrome:
- Использует subpixel anti-aliasing,
- Лёгкое размытие на диагональных линиях,
- Цвета могут слегка «просвечивать» из-за premultiplied alpha.
- Firefox:
- Использует grayscale anti-aliasing,
- Более резкие края,
- Точное соответствие цветам без смешивания.
Эти различия невидимы глазу, но алгоритмы анализа Canvas (например, в PixelScan или FingerprintJS Pro) их ловят через статистику пикселей: распределение яркости, градиенты, шум.
Поведение при передаче
- Chrome:
После transferToImageBitmap() canvas становится недействительным (invalid). Любая попытка рисовать вызывает ошибку. - Firefox:
Canvas остаётся валидным, но последующие вызовы игнорируются до следующего transfer.
Критическая деталь:
Если твой скрипт пытается рисовать после transfer и не получает ошибку — ты выдаёшь себя как Firefox в Chrome-профиле.
Часть 3: Три фатальные ошибки кардеров (и как их исправить)
Ошибка №1: Копирование шаблонного кода без адаптации
Проблема:Кардеры используют универсальный код вроде:
JavaScript:
const offscreen = new OffscreenCanvas(256, 256);
const ctx = offscreen.getContext('2d');
ctx.fillRect(0, 0, 256, 256);
const bitmap = offscreen.transferToImageBitmap();
Но не учитывают, что Chrome и Firefox требуют разного поведения после передачи.
Адаптируй код под целевой браузер:
JavaScript:
// Для Chrome-профиля
try {
const bitmap = offscreen.transferToImageBitmap();
// Никаких операций с offscreen после этого!
} catch (e) {
// Обработка ошибки (в Chrome редко)
}
JavaScript:
// Для Firefox-профиля
const bitmap = offscreen.transferToImageBitmap();
// Можно продолжать рисовать (но результат будет проигнорирован)
Ошибка №2: Игнорирование времени выполнения
Проблема:Кардеры не замеряют, сколько времени занимает transferToImageBitmap(). Но фрод-движки делают это автоматически.
Если твой «Chrome» профиль показывает время передачи 7 мс — тебя помечают как Firefox или VM.
Добавь микро-замер и эмулируй естественную задержку:
JavaScript:
const start = performance.now();
const bitmap = offscreen.transferToImageBitmap();
const latency = performance.now() - start;
// Для Chrome: если latency < 1ms — добавь искусственную задержку 1–2ms
if (latency < 1) await new Promise(r => setTimeout(r, 2));
Ошибка №3: Отсутствие валидации артефактов
Проблема:Кардер проверяет только, что картинка «нарисовалась», но не анализирует статистику пикселей.
Используй инструменты для глубокой проверки:
- Сохрани ImageBitmap как PNG,
- Загрузи в pixelscan.net,
- Сравни:
- Anti-aliasing pattern,
- Color bleed,
- Pixel distribution entropy.
Если твой Chrome-профиль показывает grayscale anti-aliasing — это Firefox. Исправляй настройки рендеринга в антидетект-браузере.
Часть 4: Практический чек-лист для кардера
| Шаг | Действие |
|---|---|
| 1. Определи цель | Chrome или Firefox? Не смешивай! |
| 2. Настрой поведение после transfer | Chrome: ошибка при повторном использовании; Firefox: игнорирование |
| 3. Эмулируй латентность | Chrome: 1–3 мс; Firefox: 4–8 мс |
| 4. Валидируй артефакты | Через pixelscan.net — проверь anti-aliasing и цвета |
| 5. Не используй универсальный код | Адаптируй скрипты под целевой движок |
Заключение: Успех — в микросекундах и пикселях
OffscreenCanvas — это не просто API для производительности. Это канал прямого доступа к ядру рендеринга браузера.Те, кто думает, что достаточно «включить OffscreenCanvas», обречены на провал. Те же, кто понимает, что каждая передача — это отпечаток движка, получают преимущество.
Настрой правильно — и пусть твои вбивы проходят так же естественно, как рендеринг в браузере настоящего пользователя.
Удачи в кардинге.
