Obs.js:面向所有人的上下文感知 Web 性能

本篇依然来自于我们的 《前端周刊》 项目!

由团队成员 田八 翻译,欢迎大家 进群 持续追踪全球最新前端资讯!!

原文地址:csswizardry

Obs.js 通过读取少量的浏览器信号(NavigatorBattery API),推断出用户的连接强度、电池状态以及设备性能。它将这些信号以 CSS 类的形式添加到 <html> 元素上,并且以属性的形式暴露在 window.obs 对象中,这样您就可以据此灵活地调整资源交付策略,比如:提供低分辨率的媒体内容、不使用网络字体、禁用自动播放的视频等等,您可以根据需要自由定制。

事实上,如果您的设备电量极低、已开启省电模式,或者网络连接较弱,那么您在上方 <h1> 标题中看到的将不会是那个圆润美观的 Fredoka 字体------而只会显示您系统默认的 system-ui 字体。

javascript 复制代码
(() => {

  // 只有在能够展示富媒体内容时,才加载 Google Fonts。
  // 在不支持相关 API 的浏览器中,我们则会直接加载字体文件。
  //
  // 此外,我们将字体脚本挂载到 body元素的末尾,而不是 head,
  // 这样就不会意外阻塞页面渲染。

  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);
  }

  // 有趣的是:由于这个 <script>标签是一个典型的、内联的、同步执行的脚本,
  // 所以在这个代码片段中提到的"body元素的末尾",实际上就是您此刻正在阅读的这段文字的紧后面。
  // 打开浏览器的开发者工具(DevTools),
  // 您会发现 Google Fonts 的样式表并不是位于 </body>标签之前,而是紧接在这个代码块之后。
  //
  // 还有一个有趣的地方:您此刻正在阅读的这段文字,其实就是浏览器刚刚执行过的 确切代码内容。
  // 只不过我们给它加上了 display: block;样式,让它以块级元素的形式显示出来而已。是不是很巧妙!
})();

Obs.jsHarry 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

json 复制代码
{
  "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> ------ 您看到的是什么?

ini 复制代码
(() => {

  // 如果网络连接状况良好,就嵌入视频;否则,只嵌入屏幕截图图片。

  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 的具体代码片段:

javascript 复制代码
/**
 * 此前由 Obs.js 捕获的所有数据,现在都会发送至 SpeedCurve 了!
 *
 * I ❤️ SpeedCurve!
 */

(() => {
    // 如果 SpeedCurve 不可用,则直接退出
    if (!window.LUX || typeof window.LUX.addData !== 'function') return;

    const obs = window.obs || Object.create(null);

    // 我们计划发送的键值。请与 Obs.js 保持同步。
    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

站点:

  • csswizardry.com 用法:
  • 在受限网络上提供低分辨率的英雄图像;
  • 在低电量模式下禁用过渡和动画。

提交您的网站

相关推荐
2501_9209317043 分钟前
React Native鸿蒙跨平台采用ScrollView的horizontal属性实现横向滚动实现特色游戏轮播和分类导航
javascript·react native·react.js·游戏·ecmascript·harmonyos
0思必得02 小时前
[Web自动化] Selenium处理动态网页
前端·爬虫·python·selenium·自动化
东东5163 小时前
智能社区管理系统的设计与实现ssm+vue
前端·javascript·vue.js·毕业设计·毕设
catino3 小时前
图片、文件的预览
前端·javascript
2501_920931704 小时前
React Native鸿蒙跨平台实现推箱子游戏,完成玩家移动与箱子推动,当所有箱子都被推到目标位置时,玩家获胜
javascript·react native·react.js·游戏·ecmascript·harmonyos
掘根5 小时前
【jsonRpc项目】发布/订阅模块
github
layman05285 小时前
webpack5 css-loader:从基础到原理
前端·css·webpack
半桔5 小时前
【前端小站】CSS 样式美学:从基础语法到界面精筑的实战宝典
前端·css·html
AI老李5 小时前
PostCSS完全指南:功能/配置/插件/SourceMap/AST/插件开发/自定义语法
前端·javascript·postcss
_OP_CHEN5 小时前
【前端开发之CSS】(一)初识 CSS:网页化妆术的终极指南,新手也能轻松拿捏页面美化!
前端·css·html·网页开发·样式表·界面美化