2026-05-03

Window TV had a startup problem that looked worse than it was. On refresh, the poster faded, the player went black for two to five seconds, and then the video appeared. YouTube was usually buffering, initializing, or blocked by browser autoplay policy. To a viewer, black looked broken.

The first useful split was separating three problems that felt identical during manual QA:

local preview drift
page load latency
third-party player startup latency

The player issue needed instrumentation, not more refreshing. I added lifecycle events for embed load, YouTube readiness, first playing, autoplay block, slow start, and reveal. A localhost trace panel showed the actual sequence per item.

One healthy trace looked like this:

yt player ready    926ms
embed loaded       927ms
first playing     1276ms
revealed          2301ms
reason            first_playing

Another showed autoplay policy as a normal runtime state:

yt player ready   1497ms
autoplay blocked  1801ms
revealed          2302ms
reason            autoplay_blocked

The key distinction: iframe loaded, provider API ready, and first visible playback are different states. Revealing on the first two can expose black even when the player is healthy.

The startup policy now depends on the playable item. Observable YouTube videos can reveal on first playing. YouTube playlists and other opaque iframes hold the poster longer. Live-like sources get more conservative timing. Autoplay block triggers muted retry behavior instead of reading as a fatal error.

The lesson: don’t reveal third-party video embeds just because the iframe says it is ready. Reveal when playback is observable, or keep a deliberate masked state when playback is opaque. Fast is worse than slow if the fast path shows the user a black box.