Battery API
Battery API в JavaScript — интерфейс, позволяющий веб-разработчикам получать и отслеживать состояние заряда аккумулятора устройства.
Battery API в JavaScript: мониторинг заряда аккумулятора
Battery API в JavaScript — это интерфейс, позволяющий веб-страницам считывать состояние аккумулятора устройства: уровень заряда, идёт ли зарядка и сколько времени осталось до полного заряда или разрядки. Используя эту информацию, веб-приложение может адаптировать своё поведение — например, снижать интенсивность фоновых задач или отключать тяжёлые анимации при низком уровне заряда. В этой статье объясняется, что такое Battery API, какие данные он предоставляет, в каких случаях его стоит использовать и как правильно работать с ним через промисы и события.
Примечание: Поскольку уровень заряда аккумулятора является сильным сигналом для отслеживания (fingerprinting) — это почти уникальное число, меняющееся медленно, — браузеры постепенно ограничили поддержку Battery API. Он был удалён из Firefox и Safari, а navigator.getBattery() доступен только в браузерах на базе Chromium (Chrome, Edge, Opera) в защищённом контексте (HTTPS). Воспринимайте его как прогрессивное улучшение и всегда проверяйте наличие API перед вызовом — ваш код должен работать и при его отсутствии.
Что такое Battery API?
Battery API предоставляется через единственный метод navigator.getBattery(), который возвращает Promise, разрешающийся в объект BatteryManager. Этот объект содержит четыре свойства только для чтения, описывающих текущее состояние, и четыре события, срабатывающих при изменении любого из этих значений. Поскольку getBattery() является асинхронным, его читают с помощью .then() или async/await.
Свойства BatteryManager
| Свойство | Тип | Значение |
|---|---|---|
charging | boolean | true, когда устройство заряжается (или не имеет аккумулятора, например настольный компьютер). |
level | number | Уровень заряда от 0 (пусто) до 1 (полный). Умножьте на 100 для получения процентов. |
chargingTime | number | Секунды до полного заряда. 0, если уже заряжен, Infinity, если не заряжается. |
dischargingTime | number | Секунды до разрядки. Infinity, если заряжается или время неизвестно. |
События BatteryManager
| Событие | Срабатывает, когда |
|---|---|
chargingchange | Устройство начинает или прекращает заряжаться (изменяется charging). |
levelchange | Изменяется значение level. |
chargingtimechange | Изменяется расчётное значение chargingTime. |
dischargingtimechange | Изменяется расчётное значение dischargingTime. |
Каждое событие является обычным DOM-событием, поэтому подписка на него осуществляется через addEventListener на объекте BatteryManager.
Преимущества Battery API
- Улучшение пользовательского опыта: Получая информацию о состоянии аккумулятора, веб-приложения могут адаптировать своё поведение для экономии энергии при работе от аккумулятора или предоставлять расширенные функции при подключении к зарядке.
- Энергоэффективность: Используя данные о состоянии аккумулятора, веб-приложения могут оптимизировать ресурсоёмкие операции для снижения потребления энергии и продления срока службы аккумулятора.
- Обновления в реальном времени: API предоставляет обновления состояния аккумулятора в режиме реального времени, позволяя веб-приложениям немедленно реагировать на такие события, как отключение от сети или низкий уровень заряда.
- Поддержка браузеров: Battery API доступен в ряде современных браузеров, однако разработчикам следует применять обнаружение функций для обеспечения совместимости в разных окружениях.
Когда использовать Battery API
Рассмотрите использование Battery API, когда вашему веб-приложению необходимо:
- Предоставлять функции с учётом энергопотребления: Адаптировать функциональность и поведение приложения в зависимости от того, работает ли устройство от аккумулятора, заряжается или полностью заряжено.
- Экономить заряд аккумулятора: Оптимизировать ресурсоёмкие операции при работе устройства от аккумулятора, чтобы снизить потребление энергии и продлить его работу.
- Отображать статус аккумулятора: Показывать пользователям информацию, связанную с аккумулятором, например текущий уровень заряда или расчётное время до полного заряда.
- Реагировать на события аккумулятора: Выполнять определённые действия при изменении состояния аккумулятора, например показывать предупреждение о низком заряде или приостанавливать ресурсоёмкие задачи.
Практические сценарии использования
- Предупреждение о низком заряде: С помощью Battery API можно выводить предупреждение о низком заряде, когда уровень аккумулятора падает ниже определённого порога, призывая пользователей экономить энергию или подключить устройство к зарядке.
- Энергоэффективные анимации: Веб-приложения могут регулировать интенсивность и частоту анимаций в зависимости от состояния аккумулятора, чтобы снизить его расход.
- Управление фоновыми процессами: Оптимизировать фоновые процессы, такие как синхронизация данных или отправка уведомлений, уменьшая их частоту при работе устройства от аккумулятора для экономии энергии.
- Динамическая загрузка ресурсов: Загружать изображения высокого разрешения или ресурсоёмкий контент только при зарядке или когда уровень заряда выше определённого порога, улучшая производительность и энергоэффективность.
Обнаружение функций
Никогда не предполагайте, что getBattery() существует. Защищайте каждый вызов, чтобы неподдерживающие браузеры корректно откатывались, а не выбрасывали TypeError:
async function readBattery() {
if (!('getBattery' in navigator)) {
return 'Battery API not supported';
}
const battery = await navigator.getBattery();
const percent = Math.round(battery.level * 100);
return `${percent}% — ${battery.charging ? 'charging' : 'on battery'}`;
}'getBattery' in navigator — это канонический способ проверки: он равен true только там, где API присутствует. Форма с async/await читает разрешённый BatteryManager точно так же, как и форма с .then(), но выполняется сверху вниз.
Базовый пример: мониторинг состояния аккумулятора
Пример ниже считывает информацию об аккумуляторе один раз, а затем поддерживает текст на экране в актуальном состоянии, прослушивая соответствующие события. Обратите внимание на вспомогательную функцию toHours — chargingTime и dischargingTime возвращаются в секундах, поэтому деление на 3600 переводит их в читаемые часы. Оба значения могут быть равны Infinity, поэтому этот случай обрабатывается явно.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Battery Time Estimation</title>
</head>
<body>
<h1>Battery Time Estimation</h1>
<div>Time Remaining: <span id="timeRemaining">Calculating...</span></div>
<script>
if ('getBattery' in navigator) {
navigator.getBattery().then(function(battery) {
const output = document.getElementById('timeRemaining');
function toHours(seconds) {
return (seconds / 3600).toFixed(1);
}
function updateTimeRemaining() {
if (battery.charging) {
if (battery.chargingTime === Infinity) {
output.textContent = 'Plugged in, charge time unknown';
} else {
output.textContent = `Charging, ${toHours(battery.chargingTime)} hours until full`;
}
} else if (battery.dischargingTime === Infinity) {
output.textContent = 'On battery, time remaining unknown';
} else {
output.textContent = `On battery, ${toHours(battery.dischargingTime)} hours remaining`;
}
}
updateTimeRemaining();
battery.addEventListener('chargingchange', updateTimeRemaining);
battery.addEventListener('levelchange', updateTimeRemaining);
battery.addEventListener('chargingtimechange', updateTimeRemaining);
battery.addEventListener('dischargingtimechange', updateTimeRemaining);
}).catch(function(error) {
document.getElementById('timeRemaining').textContent = 'Battery API not available or access denied.';
console.error('Battery API error:', error);
});
} else {
document.getElementById('timeRemaining').textContent = 'Battery API not supported in this browser.';
}
</script>
</body>
</html>Как это работает:
- Оценка времени: Скрипт проверяет, заряжается аккумулятор или разряжается, и отображает расчётное время до полного заряда или разрядки.
- Слушатели событий: Отображение обновляется в реальном времени по мере изменения состояния аккумулятора.
Этот пример наглядно показывает, как Battery API может предоставлять детальную информацию об использовании аккумулятора, включая оценку времени, что особенно полезно для мобильных устройств и ноутбуков при управлении энергопотреблением и планировании использования.
Реакция на низкий заряд аккумулятора
Распространённый паттерн — переключение страницы в режим «экономии энергии», когда заряд падает ниже порога при работе от аккумулятора. Прослушивайте levelchange и chargingchange вместе, чтобы переоценивать режим при каждом из этих сигналов:
async function watchPowerSaver(onChange) {
if (!('getBattery' in navigator)) return;
const battery = await navigator.getBattery();
function evaluate() {
// Save power only when on battery and below 20%.
const lowPower = !battery.charging && battery.level < 0.2;
onChange(lowPower);
}
evaluate();
battery.addEventListener('levelchange', evaluate);
battery.addEventListener('chargingchange', evaluate);
}
// Usage: pause heavy animations when low on power.
watchPowerSaver((lowPower) => {
document.body.classList.toggle('reduce-motion', lowPower);
});Это намного экономичнее, чем периодический опрос с помощью таймера: колбэк выполняется только при фактическом изменении состояния аккумулятора.
Распространённые подводные камни
- API может так и не вернуть полезные данные. На настольном компьютере без аккумулятора
chargingравноtrue,levelравно1, а оба временных свойства равны0илиInfinity. Не воспринимайте API как надёжный признак работы на ноутбуке. Infinity— это нормально.chargingTimeравенInfinity, когда устройство не заряжается, аdischargingTimeравенInfinity, когда время невозможно оценить. Всегда проверяйте это значение перед форматированием.- Оценки грубые и округлённые. Для снижения возможностей отслеживания браузеры округляют
levelи временные значения, поэтому не стройте на них точные обратные отсчёты. - Требуется защищённый контекст.
getBattery()доступен только на страницах с HTTPS (иlocalhost). На обычном HTTP он равенundefined, что улавливается проверкой наличия функции. - Удаляйте ненужные слушатели. Если вы добавляете слушатели внутри компонента, удаляйте их с помощью
removeEventListenerпри демонтаже, чтобы избежать утечек памяти.
Заключение
Battery API в JavaScript предоставляет веб-разработчикам инструмент для получения информации о состоянии аккумулятора устройств пользователей и реагирования на его изменения. Применяя этот API, веб-приложения могут улучшать пользовательский опыт, экономить заряд аккумулятора и повышать энергоэффективность. Хотя поддержка браузерами различается из-за соображений конфиденциальности, Battery API позволяет создавать энергоэффективные интерфейсы там, где он поддерживается, — при условии обнаружения функций, корректной обработки значений Infinity и восприятия данных как приблизительной подсказки, а не гарантии.
Связанные темы
- Промисы —
getBattery()возвращает промис. - async / await — наиболее удобный способ работы с ним.
- Введение в события браузера — как работают события
BatteryManager. - Geolocation API — ещё один API статуса устройства со схожими паттернами разрешений и обнаружения функций.