Из-за чего зависает виджет в OBS?
По вводным: у меня сейчас в разработке проект полноэкранного виджета для OBS, для использования на своих стримах в будущем.
По вводным: это "монолит" почти на 9 тысяч кода (учитывая PHP вставки, HTML, CSS, и большая часть - JavaScript). По большому счёту занимается просто показом уведомлений (красочных, иногда с анимацией, иногда с QR кодом, если есть - проигрывание звука) через какой-то промежуток времени. При этом каждое уведомление представляет из себя "сессию" и работает в несколько фаз: красивая canvas 2d анимация (filling), показ и скрытие уведомления (баннера) (showing), завершающая красивая canvas 2d анимация (outro), фаза ожидания (idle).
По вводным: при этом скрипт должен работать долго.
Сейчас ситуация такая: как например тот-же DonationAlerts - работает, не виснет, и работает сколько нужно. При этом я слегка анализировала его работу - там куча вебсокетов, событий, подгрузка ресурсов, и прочее прочее прочее. Грубо говоря - сделано ещё сложнее.
Мой скрипт - виснет.
По вводным: стабильно виснет именно в OBS.
По вводным: через довольно длительный промежуток времени, например 8 часов, 11 часов, 14 часов, и даже 21.5 час (рекорд).
По вводным: а может зависнуть и через 32 минуты, например. Или через 3 часа.
Сейчас ситуация такая: при этом, обычно зависает на фазе filling или showing, реже idle, ещё реже outro (на самом деле давно не видела).
По вводным: нет никакой стабильности, даже в зависаниях.
По вводным: по сути может зависнуть в любой момент.
По вводным: в браузере раньше тоже зависал, но я каждый день работаю над улучшениями, уже долгое время работает хорошо.
Немного скриншотов:
По вводным: (прошу прощения за плохое качество, но это скриншот с уже зависшего OBS, крупнее сделать или скопировать уже нет возможности)
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Виджет OBS на HTML/CSS/JS может зависать из-за тяжёлого главного потока, утечек памяти, бесконечных таймеров, частых DOM-перерисовок, тяжёлого canvas, WebSocket-реконнектов или накопления объектов. Если файл уже почти 9000 строк монолитом, первым делом нужно не гадать, а поставить диагностику производительности.
Откройте виджет не только в OBS, но и в обычном браузере/Chrome через тот же URL. В DevTools проверьте Performance и Memory. Если в браузере тоже растёт память или FPS падает, проблема в коде виджета, а не в OBS.
Проверьте таймеры. Частая ошибка — создавать
setIntervalили обработчики событий повторно при каждом обновлении состояния:setInterval(updateWidget, 1000); // плохо, если вызывается много раз
Нужно хранить id таймера и не создавать новый без очистки:
let timerId = null; function start() { if (timerId) return; timerId = setInterval(updateWidget, 1000); } function stop() { clearInterval(timerId); timerId = null; }let timerId = null; function start() { if (timerId) return; timerId = setInterval(updateWidget, 1000); } function stop() { clearInterval(timerId); timerId = null; }
Для анимаций используйте
requestAnimationFrame, а не частые интервалы. Для canvas не перерисовывайте всё без необходимости. Для DOM не меняйте тысячи узлов каждую секунду; лучше обновлять только изменившиеся элементы.Если есть WebSocket/API, проверьте, не запускаются ли десятки reconnect-подключений. Логируйте количество активных соединений и обработчиков.
Итог: вынесите логику в модули, проверьте таймеры/обработчики, измерьте Performance/Memory в браузере и отдельно в OBS. В 90% случаев зависание такого виджета — это накопление таймеров, слушателей или слишком частая перерисовка DOM/canvas.