Использование Battery Status API в веб-приложениях
Большинство веб-приложений понятия не имеют, что пользователь находится в поезде с 8% заряда батареи и без зарядного устройства. Battery Status API меняет это — по крайней мере, в некоторых браузерах. Он позволяет вашему JavaScript-коду считывать уровень заряда батареи устройства, состояние зарядки и оценочное оставшееся время, чтобы вы могли соответствующим образом адаптировать поведение приложения.
В этой статье объясняется, как работает API, что вы реально можете с ним делать, и почему нужно быть осторожным в том, где и как его использовать.
Ключевые выводы
- Battery Status API предоставляет уровень заряда батареи, состояние зарядки и временные оценки через
navigator.getBattery(), возвращая объектBatteryManagerс четырьмя доступными для чтения свойствами и четырьмя соответствующими событиями изменения. - Всегда используйте проверку поддержки функции и обработку ошибок перед вызовом API, поскольку он доступен только в безопасных контекстах (HTTPS) и только в браузерах на базе Chromium.
- Firefox удалил API из-за проблем с фингерпринтингом, а Safari никогда его не реализовывал, поэтому рассматривайте поведение с учётом батареи строго как прогрессивное улучшение — никогда как основную функцию.
- Практические применения включают приостановку фоновой синхронизации, уменьшение анимаций и напоминание пользователям сохранить работу при низком заряде батареи.
Что такое Battery Status API?
Battery Status API предоставляет информацию о батарее через метод navigator.getBattery(), который возвращает Promise, разрешающийся в объект BatteryManager. Этот объект даёт вам четыре свойства:
level— число от0до1(например,0.72означает 72%)charging—true, если устройство подключено к питанию,false, если нетchargingTime— оценочное количество секунд до полной зарядкиdischargingTime— оценочное количество секунд до разрядки батареи
Оба временных свойства могут возвращать Infinity — когда устройство является настольным компьютером без батареи, когда оценка ещё не готова, или когда браузер намеренно скрывает точность для ограничения риска фингерпринтинга.
Как безопасно использовать navigator.getBattery()
Всегда проверяйте поддержку перед вызовом API. Он доступен только в безопасных контекстах (HTTPS), и даже тогда только в браузерах, которые его предоставляют.
Во встроенных контекстах доступ также может быть ограничен Permissions Policy battery.
async function initBatteryMonitor() {
// Feature detection — don't assume the API exists
if (!('getBattery' in navigator)) {
console.warn('Battery Status API not supported in this browser.')
return
}
let battery
try {
battery = await navigator.getBattery()
} catch (err) {
console.error('Failed to access battery information:', err)
return
}
// Read initial values
console.log(`Level: ${battery.level * 100}%`)
console.log(`Charging: ${battery.charging}`)
// Handle Infinity gracefully before displaying
const formatTime = (seconds) =>
seconds === Infinity ? 'Unknown' : `${Math.round(seconds / 60)} min`
console.log(`Charging time: ${formatTime(battery.chargingTime)}`)
console.log(`Discharging time: ${formatTime(battery.dischargingTime)}`)
// Listen for changes
battery.addEventListener('levelchange', () => {
console.log(`Battery level updated: ${battery.level * 100}%`)
})
battery.addEventListener('chargingchange', () => {
console.log(`Charging state changed: ${battery.charging}`)
})
}
initBatteryMonitor()
Четыре события, которые вы можете отслеживать: levelchange, chargingchange, chargingtimechange и dischargingtimechange. Каждое срабатывает при изменении соответствующего значения.
Практические варианты использования
API наиболее полезен, когда вы хотите снизить потребление ресурсов для пользователей с низким зарядом батареи:
- Приостановка фоновой синхронизации или опроса, когда
battery.levelпадает ниже порога, например0.2 - Уменьшение сложности анимации или отключение автовоспроизведения видео
- Напоминание пользователям сохранить работу до разрядки батареи
- Настройка поведения PWA — например, отсрочка некритичных сетевых запросов
Это прогрессивные улучшения. Ваше приложение должно нормально работать и без них.
Discover how at OpenReplay.com.
Поддержка браузерами и вопросы конфиденциальности
Здесь Battery Status API становится сложным.
| Браузер | Поддержка | Примечания |
|---|---|---|
| Браузеры на базе Chromium | Поддерживается с ограниченной доступностью | Только HTTPS; значения могут быть уменьшены, округлены или заменены значениями по умолчанию |
| Firefox | Нет | Удалён из-за проблем с конфиденциальностью |
| Safari | Нет | Никогда не был реализован |
Текущая поддержка браузерами ограничена. Firefox удалил API, потому что исследователи продемонстрировали, что его можно использовать как вектор фингерпринтинга — комбинация уровня заряда батареи и временных значений была достаточно специфичной, чтобы помочь отслеживать пользователей между сайтами. В ответ браузеры на базе Chromium могут снижать точность или предоставлять значения по умолчанию для ограничения этого риска.
Это означает, что вы никогда не должны полагаться на Battery API как на основную функцию. Рассматривайте его как приятное дополнительное улучшение и всегда пишите резервное поведение на случай, когда он ничего не возвращает.
Тестирование Battery API в процессе разработки
Chrome DevTools в настоящее время не предоставляет встроенный симулятор батареи в разделе Sensors. Для тестирования поведения, связанного с батареей, во время разработки у вас есть несколько практических вариантов:
- Использовать реальное мобильное устройство, подключённое через USB для удалённой отладки, и наблюдать за фактическими изменениями состояния батареи.
- Имитировать API в вашем коде, заменив
navigator.getBatteryфункцией, которая возвращает поддельный объектBatteryManagerсо свойствами и событиями, которые вам нужно протестировать. - Использовать переопределения браузера или библиотеки для тестирования, такие как Sinon или Jest, чтобы заглушить
navigator.getBattery()в вашем тестовом наборе.
Вот минимальная имитация, которую вы можете добавить в свою среду разработки:
function mockBattery({ level = 0.15, charging = false } = {}) {
const fake = {
level,
charging,
chargingTime: charging ? 3600 : Infinity,
dischargingTime: charging ? Infinity : 1800,
addEventListener: () => {},
}
navigator.getBattery = () => Promise.resolve(fake)
}
// Simulate a low-battery, unplugged device
mockBattery({ level: 0.08, charging: false })
Этот подход даёт вам полный контроль над значениями, которые получает ваш код, без зависимости от специфичных для браузера инструментов.
Заключение
Battery Status API — это нишевый инструмент с реальными ограничениями. Поддержка браузерами узкая, значения намеренно неточны, а последствия для конфиденциальности означают, что его будущее неопределённо. Но в контролируемых средах — внутренних инструментах, PWA, ориентированных на известные браузеры на базе Chromium, или киоск-приложениях — он может значительно улучшить пользовательский опыт.
Используйте проверку поддержки функции, явно обрабатывайте значения Infinity, очищайте слушатели событий, когда они больше не нужны, и никогда не создавайте критическую функцию на его основе.
Часто задаваемые вопросы
Только в мобильных браузерах на базе Chromium, таких как Chrome для Android, и даже там доступность может варьироваться в зависимости от окружения. Safari на iOS никогда его не реализовывал, а Firefox полностью удалил поддержку. Всегда используйте проверку поддержки функции перед вызовом navigator.getBattery() и предоставляйте резервное поведение для неподдерживаемых браузеров.
Может быть. Исследователи показали, что комбинация уровня заряда батареи и значений времени разрядки была достаточно точной для фингерпринтинга пользователей между веб-сайтами. Это привело к тому, что Firefox полностью удалил API. Браузеры на базе Chromium могут снижать точность или предоставлять значения по умолчанию для ограничения этого риска, но проблема остаётся причиной, по которой некоторые браузеры избегают его реализации.
Сохраните ссылки на ваши функции-обработчики и вызовите removeEventListener, когда они больше не нужны, например, при размонтировании компонента. Поскольку объект BatteryManager сохраняется, неудаление слушателей может вызвать утечки памяти или неожиданное поведение, если ваше приложение повторно инициализирует монитор несколько раз.
Он работает в поддерживаемых браузерах на базе Chromium для настольных компьютеров, но значения могут быть неинформативными. Настольные компьютеры без батарей часто сообщают уровень заряда 1 и состояние зарядки true, причём оба временных свойства установлены в Infinity. API наиболее полезен на ноутбуках и мобильных устройствах, где состояние батареи действительно меняется.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.