Obs.js 通过读取少量的浏览器信号(Navigator 和 Battery API),推断出用户的连接强度、电池状态以及设备性能。它将这些信号以 CSS 类的形式添加到 <html> 元素上,并且以属性的形式暴露在 window.obs 对象中,这样您就可以据此灵活地调整资源交付策略,比如:提供低分辨率的媒体内容、不使用网络字体、禁用自动播放的视频等等,您可以根据需要自由定制。
事实上,如果您的设备电量极低、已开启省电模式,或者网络连接较弱,那么您在上方 <h1> 标题中看到的将不会是那个圆润美观的 Fredoka 字体——而只会显示您系统默认的 system-ui 字体。
(() => {
  
  
  
  
  
  if (window.obs?.shouldAvoidRichMedia === true) {
    return;
  } else {
    const gf = document.createElement('link');
    gf.rel = 'stylesheet';
    gf.href = 'https://fonts.googleapis.com/css2?family=Fredoka:wght@300..700&display=swap';
    document.body.appendChild(gf);
  }
  
  
  
  
  
  
  
})();
Obs.js 由 Harry Roberts 开发并维护,遵循 MIT 许可证。
本页面展示了 Obs.js 为 <html> 元素添加的 .has-* 类,以及它用于存储设备和网络信息的当前 window.obs 对象。
您可以尝试切换 省电模式(Data Saver)、插拔电源 或 切换网络(在支持的设备上),观察这些类和对象的实时更新。
html.classList
- .has-bandwidth-high
- .has-battery-charging
- .has-connection-capability-moderate
- .has-conservation-preference-neutral
- .has-cpu-high
- .has-delivery-mode-cautious
- .has-device-capability-strong
- .has-latency-medium
- .has-ram-high
window.obs
{
  "config": {
    "observeChanges": true
  },
  "dataSaver": false,
  "rttBucket": 150,
  "rttCategory": "medium",
  "downlinkBucket": 10,
  "downlinkCategory": "high",
  "connectionCapability": "moderate",
  "conservationPreference": "neutral",
  "deliveryMode": "cautious",
  "canShowRichMedia": true,
  "shouldAvoidRichMedia": false,
  "ramBucket": 8,
  "ramCategory": "high",
  "cpuBucket": 16,
  "cpuCategory": "high",
  "deviceCapability": "strong",
  "batteryCritical": false,
  "batteryLow": false,
  "batteryCharging": true
}
请注意:各浏览器对这些 API 的支持情况有所不同,其中 Chromium 内核浏览器提供的支持最为全面。
Demo
如果您的当前网络连接允许,您应该可以看到下方的小视频;如果条件不允许,则会显示一张静态的 <img> —— 您看到的是什么?

(() => {
  // 如果网络连接状况良好,就嵌入视频;否则,只嵌入屏幕截图图片。
  const videoWrapper = document.getElementById('jsVideo')
  if (window.obs?.shouldAvoidRichMedia === true) {
    const img = new Image()
    img.src = './assets/poster.png'
    img.alt = ''
    img.width = '1500'
    img.height = '966'
    img.classList.add('c-hero')
    videoWrapper.appendChild(img)
  } else {
    const video = document.createElement('video')
    video.src = './assets/video.min.mp4'
    video.poster = './assets/poster.png'
    video.autoplay = true
    video.loop = true
    video.muted = true
    video.controls = true
    video.preload = 'auto'
    if (window.obs?.deliveryMode === 'cautious') {
      video.preload = 'metadata'
    }
    if (window.obs?.batteryLow === true) {
      video.autoplay = false
    }
    videoWrapper.appendChild(video)
  }
})()
分析
如果您使用的 RUM(真实用户监控) 或 分析服务提供商 能够接收类似 window.obs 格式的数据,那您就可以将这些信息发送给他们! 您 并不一定非要用 Obs.js 来调整或改变您的网站——您完全可以将它作为一个 纯粹的观测工具,借此更深入地了解您的用户群体。

我会把所有数据都发送给我在 SpeedCurve 的朋友们。有了这些数据,我就能开始对 RUM(真实用户监控)数据进行细分,并制定针对不同用户群体的服务策略。
以下是我用来将 Obs.js 数据发送至 SpeedCurve 的具体代码片段:
(() => {
    
    if (!window.LUX || typeof window.LUX.addData !== 'function') return;
    const obs = window.obs || Object.create(null);
    
    const keys = [
        'canShowRichMedia',
        'connectionCapability',
        'conservationPreference',
        'cpuBucket',
        'cpuCategory',
        'dataSaver',
        'deliveryMode',
        'deviceCapability',
        'downlinkBucket',
        'downlinkCategory',
        'ramBucket',
        'ramCategory',
        'rttBucket',
        'rttCategory',
        'shouldAvoidRichMedia'
    ];
    for (const key of keys) {
        if (Object.prototype.hasOwnProperty.call(obs, key)) {
            window.LUX.addData(key, obs[key]);
        }
    }
})();
展示
这些优秀的人正在使用Obs.js:

转自https://juejin.cn/post/7545317605810651136
该文章在 2025/9/8 9:03:53 编辑过