Loading

Everything has its shape. The wait is the mark’s own.

How OpenVibe waits: the page arrives drawn, a list shows its own shape until it fills in, the mark works while a page moves, and a slow load says so. The same parts on every site, from openvibe-shared.

Placeholders shaped like the content

Seven shapes cover the network’s lists. Press Fill in: the real content takes the placeholder’s place, and the page says how far everything below it moved.

  • Card

    A video or stream: its 16:9 picture and two lines.

    kit.skeleton({ kind: 'card', count: 3 })
  • Row

    A person or a result: an avatar and two lines.

    kit.skeleton({ kind: 'row', count: 3 })
  • Tile

    A square in a grid: an emote, an icon, a cover.

    kit.skeleton({ kind: 'tile', count: 6 })
  • Chip

    A tag or a filter.

    kit.skeleton({ kind: 'chip', count: 6 })
  • Line

    Text that is on its way.

    kit.skeleton({ kind: 'line', count: 3 })
  • Chat

    A chat message: a dot and a line.

    kit.skeleton({ kind: 'chat', count: 3 })
  • Stat

    A number and what it counts.

    kit.skeleton({ kind: 'stat', count: 3 })

The mark at work

For a stream or a player that takes a moment: its own picture blurred behind, the V bobbing and the O breathing, one word of status and a line that fills with each step. Slow, it explains; failed, it says what happened.

Press Start
const l = OpenVibeLoading.mount(player, { poster, label: 'Connecting', sub: 'Getting your viewer ready', steps: 4 });
l.update({ step: 1, label: 'Joining' });
l.slow({ hint: 'Still connecting', actions: [{ label: 'Try again', onClick: retry }] });
l.fail({ title: 'The stream ended', actions: [{ label: 'Retry', onClick: retry }] });
l.done();

The rules

What every OpenVibe site does while you wait. Live’s measurements are in its performance audit.

  1. The page arrives drawn. Server-rendered HTML with its icons already drawn (no icon font to wait for), and only the CSS the first screen needs before it paints.
  2. A list shows its shape at once. Its placeholders are in the first HTML, the same size as what replaces them, so filling in moves nothing (each demo above measures it).
  3. A picture sits on its own colour first. Its dominant colour, or a tiny blurred copy, until it arrives. The first picture asks for itself first (fetchpriority="high"); the rest wait until they are near (loading="lazy").
  4. Moving between pages feels like one app. The mark works in the navbar with a two-pixel line under it. Links are fetched when pointed at (speculation rules), and the navbar and app bar stay still while the page cross-fades (view transitions).
  5. The wait is the mark’s own. Its O goes round as dots while it works, three dots rise inside it while an agent thinks, and a line fills when the length is known. Calm plays it slower; only motion off keeps it still.
  6. Slow says so. After a few seconds a load explains itself and offers what to do. A failure says what happened and offers Retry, never an endless wait.
  7. Off screen costs nothing. Long lists skip the work for what is not on screen yet (content-visibility: auto).

Use it

On an OpenVibe site the navbar brings all of it. Anywhere else, the files are free (MIT).

Placeholders, on the server

const kit = require('openvibe-shared/kit');
kit.skeleton({ kind: 'card', count: 6, label: 'Loading streams' });
// card · row · tile · chip · line · chat · stat

The loader, in a page

<link rel="stylesheet" href="https://openvibe.design/shared/kit.css">
<script src="https://openvibe.design/shared/loading.js" defer></script>

App-like page moves

<script src="https://openvibe.design/shared/boost.js" defer></script>
<meta name="ov-boost" content="mysite@1">