Obs.js reads a handful of
browser signals
(Navigator
and Battery
APIs) to infer connection strength, battery status, and device capability. It
exposes those signals as CSS classes on the <html>
element,
and as properties on window.obs
, so you can adapt delivery
accordingly: serve lower-resolution media, forgo web fonts, disable
auto-playing video… you name it.
In fact, if you have critically low battery, data saver mode
enabled, or a weak connection, you won’t see the nice rounded
Fredoka
in the <h1>
above—you’ll just see your
system-ui
font:
Obs.js is built and maintained by Harry Roberts under the MIT license.
This page shows the .has-*
classes that Obs.js adds to the
<html>
element, and the current window.obs
object where it stores device and network information.
Try toggling Data Saver, plugging/unplugging power, or changing networks to see updates (where supported).
html.classList
window.obs
Note: API support varies by browser; Chromium has the broadest coverage.
Obs.js must be placed early in the <head>
as an inline
<script>
, much like Google Tag Manager. Any attempt to
install Obs.js any other way—via a package manager, as an external file—will
cause Obs.js to self-terminate.
In order for Obs.js to provide its key function, it needs to run before any
other HTML, CSS, or JS that might depend on it. Thus, Obs.js must be installed
early and synchronously. Early and synchronously
, usually means
slow, but by pasting Obs.js as an inline <script>
,
it takes about 1.5ms to run on a real
Samsung Galaxy A54.
Get the snippet on GitHub.
<video>
DemoIf your connection allows it, you should see a small video below. If not,
you will see a static <img>
—what can you see?
If your RUM
or analytics provider accepts window.obs
-style data, you can send
it off to them! You don’t need to use Obs.js to adapt or change your
site—you can use it as a purely observational tool to learn more about
your audience:
I send all of my data off to my friends at SpeedCurve. With that, I can begin segmenting my RUM data and designing strategies to serve different demographics.
Here’s the exact snippet I use to send Obs.js data to SpeedCurve:
These fine folk are using Obs.js: