Obs.js 通過讀取少量的瀏覽器信號(Navigator 和 Battery API?),推斷出用戶的連接強度、電池狀態(tài)以及設備性能。它將這些信號以 CSS
類的形式添加到 <html>
元素上,并且以屬性的形式暴露在 window.obs
對象中,這樣您就可以據(jù)此靈活地調(diào)整資源交付策略,比如:提供低分辨率的媒體內(nèi)容、不使用網(wǎng)絡字體、禁用自動播放的視頻等等,您可以根據(jù)需要自由定制。
事實上,如果您的設備電量極低、已開啟省電模式,或者網(wǎng)絡連接較弱,那么您在上方 <h1>
標題中看到的將不會是那個圓潤美觀的 Fredoka
字體——而只會顯示您系統(tǒng)默認的 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 開發(fā)并維護,遵循 MIT 許可證。
本頁面展示了 Obs.js 為 <html>
元素添加的 .has-*
類,以及它用于存儲設備和網(wǎng)絡信息的當前 window.obs
對象。
您可以嘗試切換 省電模式(Data Saver)、插拔電源 或 切換網(wǎng)絡(在支持的設備上),觀察這些類和對象的實時更新。
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
內(nèi)核瀏覽器提供的支持最為全面。
Demo
如果您的當前網(wǎng)絡連接允許,您應該可以看到下方的小視頻;如果條件不允許,則會顯示一張靜態(tài)的 <img>
—— 您看到的是什么?

(() => {
// 如果網(wǎng)絡連接狀況良好,就嵌入視頻;否則,只嵌入屏幕截圖圖片。
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
(真實用戶監(jiān)控) 或 分析服務提供商 能夠接收類似 window.obs
格式的數(shù)據(jù),那您就可以將這些信息發(fā)送給他們! 您 并不一定非要用 Obs.js
來調(diào)整或改變您的網(wǎng)站——您完全可以將它作為一個 純粹的觀測工具,借此更深入地了解您的用戶群體。

我會把所有數(shù)據(jù)都發(fā)送給我在 SpeedCurve 的朋友們。有了這些數(shù)據(jù),我就能開始對 RUM
(真實用戶監(jiān)控)數(shù)據(jù)進行細分,并制定針對不同用戶群體的服務策略。
以下是我用來將 Obs.js
數(shù)據(jù)發(fā)送至 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]);
}
}
})();
展示
這些優(yōu)秀的人正在使用Obs.js:

轉自https://juejin.cn/post/7545317605810651136
該文章在 2025/9/8 9:03:53 編輯過