OpenPWAStore
Back to News
Guide · May 19, 2026

Screen wake lock requires battery-conscious strategies, not just always-on screens

How to responsibly keep screens on in PWAs without draining battery excessively.

OpenPWA Editorial3 min read
Screen wake lock requires battery-conscious strategies, not just always-on screens cover

为什么屏幕唤醒锁对 PWA 很重要

默认情况下,设备会在一段时间后关闭屏幕以延长电池寿命。这虽然有用,但某些应用需要屏幕保持开启才能发挥最大效用。

屏幕唤醒锁(Screen Wake Lock)API 防止屏幕关闭、变暗或锁定,提供简单的基于平台的解决方案。

典型用例

  • 电子书阅读:防止翻页时屏幕突然变暗
  • 地图导航:保持路线可见,不要锁屏干扰导航
  • 菜谱/教程:避免操作中途屏幕熄灭
  • 演示/演讲:演示时保持屏幕常亮
  • QR/条码扫描:确保相机持续预览
  • 语音/手势控制:无需触控输入时保持屏幕活跃

MDN 文档指出,唤醒锁请求可能因多种原因拒绝,包括系统设置(省电模式、低电量)或文档不活跃/不可见。

如何实施屏幕唤醒锁

步骤 1:功能检测

检查浏览器是否支持:

if ('wakeLock' in navigator) {
  console.log('Screen Wake Lock API supported');
  // 启用相关 UI 控件
  enableWakeLockButton();
} else {
  console.log('Wake Lock not supported');
  // 禁用或隐藏相关功能
  wakeLockButton.disabled = true;
}

步骤 2:请求唤醒锁

使用 navigator.wakeLock.request('screen') 异步请求:

let wakeLock = null;

async function requestWakeLock() {
  try {
    wakeLock = await navigator.wakeLock.request('screen');
    console.log('Wake Lock is active!');
    updateUI('Wake Lock Active');

    // 监听自动释放事件
    wakeLock.addEventListener('release', () => {
      console.log('Wake Lock released');
      wakeLock = null;
      updateUI('Wake Lock Inactive');
    });

  } catch (err) {
    console.error(`${err.name}, ${err.message}`);
    // 处理失败(如低电量、省电模式)
    showErrorMessage('Wake Lock request failed');
  }
}

关键 API

  • navigator.wakeLock.request('screen'):请求屏幕唤醒锁
  • WakeLockSentinel:返回的对象,代表底层系统唤醒锁
  • wakeLock.release():手动释放唤醒锁
  • wakeLock.addEventListener('release', callback):监听自动释放事件

步骤 3:处理文档可见性变化

当文档变得不可见时(如切换标签页),唤醒锁会自动释放。文档重新可见时需要重新请求:

let autoReacquire = false; // 用户可配置

document.addEventListener('visibilitychange', async () => {
  if (wakeLock === null && document.visibilityState === 'visible' && autoReacquire) {
    try {
      wakeLock = await navigator.wakeLock.request('screen');
      updateUI('Wake Lock Reacquired');
    } catch (err) {
      console.error('Failed to reacquire wake lock:', err);
    }
  }

  // 如果文档变得不可见,wakeLock 可能已被系统自动释放
  if (document.visibilityState !== 'visible' && wakeLock !== null) {
    updateUI('Wake Lock Will Release');
  }
});

步骤 4:手动释放唤醒锁

用户主动结束需要常亮屏幕的活动时,应立即释放:

function releaseWakeLock() {
  if (wakeLock) {
    wakeLock.release()
      .then(() => {
        wakeLock = null;
        updateUI('Wake Lock Released');
      })
      .catch((err) => {
        console.error('Error releasing wake lock:', err);
      });
  }
}

// 为用户提供释放按钮
releaseButton.addEventListener('click', releaseWakeLock);

性能和电池优化策略

何时使用唤醒锁

MDN 文档提供了明确指导:

  • 票据应用:显示 QR 码时请求唤醒锁,扫描完成后立即释放
  • 演示应用:仅在演示活跃时保持唤醒锁,编辑时不应请求

推荐模式:仅在需要时请求唤醒锁,并在活动结束时立即释放。

不应使用唤醒锁的场景

| 场景 | 原因 | 替代方案 | |------|------|----------| | 长时间下载 | 唤醒锁耗电 | ✅ Background Fetch / Periodic Background Sync | | 数据同步 | 不需要屏幕 | ✅ Background Sync | | 后台音乐播放 | 屏幕无需常亮 | ✅ Media Session API(设备支持后台播放) | | 社交 IM 消息应用 | 不需要常亮 | ✅ Push Notifications 提醒用户 |

电池意识最佳实践

  1. 监听电池状态(如果浏览器支持 navigator.getBattery()):
   if ('getBattery' in navigator) {
     navigator.getBattery().then((battery) => {
       // 低电量时避免请求唤醒锁
       if (battery.level < 0.2 && !battery.charging) {
         return;
       }
       requestWakeLock();
     });
   }
  1. 监听充电状态变化
   battery.addEventListener('chargingchange', () => {
     if (battery.charging) {
       requestWakeLock(); // 充电时可请求
     } else {
       releaseWakeLock(); // 停止充电且电量低时释放
     }
   });

- 检测浏览器是否处于省电模式(如果 API 可用) - 提示用户是否允许保持屏幕常亮

  1. 避免在省电模式下请求唤醒锁

安全性和权限

Permissions Policy 控制访问

MDN 文档指出,访问 Screen Wake Lock API 由 Permissions-Policy 头控制:

Permissions-Policy: screen-wake-lock=(self)

默认行为self):

  • ✅ 同源嵌套 frame 可使用唤醒锁
  • ❌ 第三方内容阻止使用刷新锁

允许特定第三方

Permissions-Policy: screen-wake-lock=(self "https://b.example.com")

然后在 iframe 中添加 allow 属性:

<iframe src="https://b.example.com" allow="screen-wake-lock"></iframe>

系统级限制

浏览器可能因特定原因在文档中阻止屏幕锁定:

  • 用户设置(如"永不锁定屏幕"被禁用)
  • 平台限制(如省电模式)
  • 低电量警告

用户通知:浏览器应提供不显眼的机制通知用户唤醒锁处于活动状态,并提供用户移除应用屏幕锁的能力。

实施检查清单

在产品化前:

技术实现

  • [ ] 功能检测(navigator.wakeLock)
  • [ ] 异步错误处理(低电量、省电模式、文档不活跃)
  • [ ] 监听 release 事件以处理自动释放
  • [ ] 处理 visibilitychange 事件重新请求唤醒锁(可选)

用户体验

  • [ ] 清晰的 UI 状态指示("屏幕常亮已开启"/"屏幕常亮已关闭")
  • [ ] 提供用户手动释放唤醒锁的按钮/开关
  • [ ] 活动结束后自动释放唤醒锁(如计时器、任务完成)
  • [ ] 提供禁用/偏好设置(用户可完全关闭此功能)

性能和电池

  • [ ] 避免长时间持有唤醒锁(如背景播放视频)
  • [ ] 结合电池状态 API 优化唤醒锁请求时机
  • [ ] 提供收集电池使用量反馈的机制
  • [ ] 文档说明唤醒锁对电池续航的影响

对开发者意味着什么

产品机会

  • 阅读/导航类 PWA:提供流畅的沉浸体验,无屏幕关闭干扰
  • 教育/教程应用:确保学生在操作教程时不会因锁屏分心
  • 演示/会议应用:演讲者无需担心设备突然锁屏

技术债务

  • 调试困难:唤醒锁效果在真实设备上才能触发,开发者工具模拟效果有限
  • 跨平台差异:不同浏览器/操作系统对唤醒锁处理可能不同
  • 状态管理复杂度:需要正确处理唤醒锁获取、释放、自动释放、重新请求的生命周期

用户体验风险

  • 电量焦虑:用户可能担心唤醒锁会快速耗电
  • 误解用途:用户可能不理解为何需要"保持屏幕常亮"
  • 控制权:用户可能无法觉察唤醒锁处于活动状态

决策框架

| 场景 | 使用唤醒锁 | 不使用唤醒锁 / 替代方案 | |------|------------|-----------------------| | 电子书阅读 | ✅ 提升阅读体验 | ⚠️ 改为自动翻页但允许锁屏 | | GPS 导航 | ✅ 保持路线可见 | ⚠️ 使用后台 Geolocation 音频提示 | | QR 码扫描 | ✅ 确保相机持续预览 | ⚠️ 改用短暂的闪光引导 | | 在线课程播放 | ⚠️ 视频内容锁屏不影响播放 | ✅ 允许屏幕关闭,后台播放 | | 音频播客 | ❌ 视频无需常亮 | ✅ 完全依赖 Media Session API | | 社交 IM | ❌ 无需常亮 | ✅ Push Notifications 提醒 | | 游戏活动 | ⚠️ 可选性功能 | ⚠️ 提供设置禁用唤醒锁 |

下一步

  1. 需求审查:确定你的应用场景真的需要常亮屏幕,而非通过其他方式(如音频、通知)满足需求
  2. 原型测试:在真实设备上体验唤醒锁效果,评估电池影响
  3. 用户反馈:收集用户对"屏幕常亮"功能的反馈,调整产品策略
  4. 性能监控:在应用 中添加电池使用量监控和用户报告机制

屏幕唤醒锁是提升用户体验的有力工具,但必须负责任地使用。仅在必要时请求,并在活动结束时立即释放,才是平衡电池续航和用户体验的最佳实践。