17.08.2026 456 материалов

Браузер против железа: что реально можно узнать о своём оборудовании из браузера — а что нет

Разработчик собрал набор браузерных инструментов для диагностики железа и выяснил, где веб-платформа честна с пользователем, а где тихо врёт. Оказывается, проверить дрифт стика или мёртвые пиксели можно прямо из Chrome — но нативное разрешение экрана браузер не покажет принципиально.

Браузер против железа: что реально можно узнать о своём оборудовании из браузера — а что нет

Браузер не умеет читать паспорт вашего железа — но умеет неплохо измерять его поведение. И это, как ни странно, полезнее.

Диагностика без установки: почему это вообще работает

Каждый, кто хоть раз покупал б/у ноутбук или проверял геймпад перед покупкой, знает ритуал: скачать CPU-Z, запустить AIDA64, найти тестер клавиатуры. Всё это требует установки, прав администратора и доверия к скачанному софту. А что если делать то же самое прямо в браузере?

Разработчик, собравший набор из десяти браузерных инструментов для диагностики, показал, что веб-платформа способна на удивительно многое. Но за каждым «может» стоит оговорка, а за каждым «не может» — осознанное решение разработчиков браузеров. Вот что из этого получилось.

Частота обновления: единственный способ — хак

В браузере нет API, который скажет «у вашего монитора 144 Гц». Нет поля screen.refreshRate, нет веб-стандарта, ничего. Единственный рабочий подход — замерять интервалы между вызовами requestAnimationFrame и вычислять медиану.

Почему медиана, а не среднее? Потому что один пропущенный кадр ломает среднее значение полностью. Медиана устойчива к выбросам — и это единственный способ получить хоть сколько-то надёжную цифру.

Ещё одна ловушка: браузер замедляет requestAnimationFrame в фоновых вкладках. Забыл проверить document.visibilityState — и получаешь показания, не имеющие отношения к реальности. Инструмент, который автор собрал, обрабатывает обе проблемы. Результат — рабочий тестер частоты экрана, не требующий ничего, кроме отрытой вкладки.

Разрешение экрана: четыре правильных ответа — и ни один не тот

Вот где начинается настоящий хаос. screen.width, window.innerWidth, devicePixelRatio, screen.availWidth — каждое свойство возвращает что-то своё, и каждое «правильное». Но не то, что нужно.

Кажется логичным: перемножаем screen.width на devicePixelRatio — получаем нативное разрешение панели. На деле это значение всё ещё производное от CSS-пикселей. На экране со скейлингом оно может не совпадать с физическим разрешением матрицы. Браузер принципиально не раскрывает аппаратное разрешение — и это не баг, а осознанное ограничение.

Для диагностики это значит: проверить, работает ли экран на заявленном разрешении, через браузер можно только косвенно. Точную панельную спецификацию веб не покажет.

Клавиатура: event.code vs event.key и клавиши-призраки

Для тестирования клавиатуры критично понимать разницу между event.key и event.code. Первое зависит от раскладки: нажал A на QWERTY — получил a, переключился на йцукен — получил ф. Второе — физическая позиция клавиши, не зависящая от раскладки. Для аппаратной диагностики нужен именно event.code.

Но настоящая проблема — клавиши, которые браузер вообще не видит. PrintScreen часто не генерирует keydown. Комбинации с Meta перехватываются операционной системой раньше, чем добираются до JavaScript. Клавиша Fn на большинстве ноутбуков невидима для браузера на уровне протокола — она обрабатывается контроллером клавиатуры до того, как сигнал уходит в USB.

Зато тестирование N-key rollover работает отлично: достаточно отслеживать размер множества одновременно зажатых клавиш. Дешёвая клавиатура начинает «глотать» нажатия уже на 3–4 одновременных клавишах — и это видно невооружённым глазом. Простой и эффективный способ проверить качество мембранной клавиатуры прямо в магазине.

Мышь и тачпад: Pointer Events побеждают, но есть подвох

События pointerdown/pointerup объединяют мышь, тачскрин и стилус в единую модель. Свойство pointerId позволяет отслеживать мультитач корректно. Для диагностики — золотой стандарт.

Классическая проблема износа микропереключателя (двойной клик вместо одинарного) определяется элементарно: замеряем интервал между двумя последовательными pointerdown на одной кнопке. Если пауза меньше ~80 миллисекунд без промежуточного движения — это почти наверняка аппаратный дефект, а не человек, кликнувший дважды.

Но есть нюанс: вызов preventDefault() на pointerdown убивает последующие совместимые события мыши. Любой код, который их ждёт, молча сломается. Ловушка, в которую легко попасть при разработке тестеров.

Геймпад: опрос только вручную и спящий при старте

API геймпадов работает только через поллинг — нет событий для движения осей, нужно вызывать navigator.getGamepads() вручную в каждом кадре анимации. Неудобно, но терпимо.

А вот что реально сбивает с толку: контроллер не появляется в списке устройств до первого нажатия кнопки. Это ограничение защиты от фингерпринтинга — и оно сработало даже на самом авторе: массив null-значений выглядит так, будто ничего не подключено. Пришлось потратить час, прежде чем стало понятно, что контроллер просто «спит».

Для диагностики дрифта стика этого API достаточно: ось в покое показывает значение, отличное от нуля. Всё, что превышает примерно 0.08 — изношенный потенциометром, и это видно без специального софта.

Микрофон и камера: сначала разрешение — потом названия

navigator.mediaDevices.enumerateDevices() перечислит устройства до запроса разрешений. Но каждое поле label будет пустой строкой. Читаемые названия устройств появляются только после успешного вызова getUserMedia(). Это значит, что интерфейс выбора устройства вынужден либо запрашивать доступ заранее, либо показывать бесполезный список без имён.

Для измерения уровня микрофона автор рекомендует AnalyserNode с getByteTimeDomainData и вычислением RMS — это стабильнее, чем анализ частотного спектра. Подход рабочий, хотя и требует от разработчика ручной обработки аудиопотока.

Мёртвые пиксели: API нет — и это правильно

Нет программного способа обнаружить мёртвый пиксель. Единственный рабочий подход — развернуть окно на весь экран через Fullscreen API и залить его сплошными цветами: красным, зелёным, синим, белым, чёрным. А дальше — человеческие глаза.

И это, пожалуй, самый здоровый пример в подборке. Не каждая проблема требует программного решения. Иногда рендер #ff0000 на весь экран и есть инструмент.

Общий паттерн: безопасность важнее точности

За каждым ограничением, описанным выше, стоит одна и та же причина: защита от фингерпринтинга. Браузеры намеренно «затупляют» любые API, которые могут точно идентифицировать железо пользователя. Вы получаете относительные измерения, имена устройств только после разрешения, списки контроллеров только после ввода.

Это правильный компромисс — но он означает, что задача «определить характеристики оборудования пользователя» через браузер в большинстве случаев нерешаема напрямую. Честные инструменты — те, которые измеряют поведение, а не притворяются, что читают спецификации.

Практический итог

Все десять инструментов работают целиком на стороне клиента, ничего не отправляя на сервер. Для покупателя б/у техники — реальная альтернатива установке десяти разных утилит. Для разработчика — наглядная карта того, что веб-платформа умеет, а где заканчивается.

Частоту экрана — можно приблизительно. Разрешение — только косвенно. Клавиатуру и мышь — отлично, с оговорками на невидимые клавиши. Геймпад — хорошо, но нужен первый ввод. Камеру и микрофон — после получения разрешения. Мёртвые пиксели — только глазами.

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