fix(website): refresh the intro video and stop its white flash - #1434
Conversation
vivek7405
left a comment
There was a problem hiding this comment.
Reviewed the full diff: one line in website/app/page.ts, swapping the embed id from iz23lVMvlVY to XghCghezod4.
Checks done:
- The id matches the target
https://youtu.be/XghCghezod4. - No other reference to the old id survives anywhere in the repo, so nothing is left pointing at the previous upload (no test, no doc, no metadata).
- The page carries no
og:videoorVideoObjectmarkup, so the embed is the only surface naming a video and there is no second place to keep in sync. - Every other iframe attribute is untouched: the
youtube-nocookiehost,loading="lazy",referrerpolicy, theallowlist,allowfullscreen, and thetitle. Theaspect-videowrapper still supplies the box, so the missingwidth/heightstay correct. - Verified against a local dev server: the served HTML carries the new id and neither prior id appears.
No correctness findings. One note on the changed line itself, inline.
vivek7405
left a comment
There was a problem hiding this comment.
Reviewed the whole diff myself: website/app/page.ts plus one new SSR test file.
No correctness findings. What I checked, beyond reading it:
- The reveal actually happens, and is not vacuous. Under Slow 3G on a cold frame the element measured
visibility: hiddenat t=19936ms, firedloadat t=23086ms, and measuredvisible. So it is concealed for the ~3.1s window the white was appearing in. - The JS-off path was tested with scripting genuinely disabled, not inferred: with JS on the section renders at 390x256; with JS off it has no box at all.
- The noscript rule is inert with JS on. It has to be, or the first measurement above could never have read
hidden. - No class collision.
.intro-videoand.intro-video-frameappear nowhere else in the app or ininput.css. - A failed frame does not strand the box. I reproduced a request that cannot load: the element still fires
load(browsers fire it for the error page) and reveals. See the inline note for the one case that does not.
Four observations inline. None of them block the merge; the last two are judgement calls that are yours, not defects.
| <iframe | ||
| class="w-full h-full" | ||
| src="https://www.youtube-nocookie.com/embed/iz23lVMvlVY?rel=0" | ||
| class="intro-video-frame w-full h-full invisible" |
There was a problem hiding this comment.
The one way this can strand: a request that never settles, firing neither load nor error, leaves the frame hidden permanently. I checked the adjacent case and it is fine, since a connection failure still fires load on the error page and reveals.
Worth stating rather than fixing, because the failure mode is benign: a request that never settles has nothing to show either way, so the reader sees a black box where they would previously have seen an empty or white one. If you want belt and braces it is one attribute, onerror="this.classList.remove('invisible')", and I am happy to add it. I left it out rather than add an attribute for a case I could not actually produce.
| is safe in a PAGE, which never hydrates, so the client never | ||
| rebuilds this noscript body as live nodes. The same construct | ||
| inside a COMPONENT would apply on every JS-enabled visit. --> | ||
| <noscript><style>.intro-video { display: none }</style></noscript> |
There was a problem hiding this comment.
Worth knowing what this does not do: display: none suppresses painting, not fetching. A JS-off reader still issues 3 requests to youtube-nocookie.com before this rule hides anything, so the embed is invisible but not absent from the network.
There is no way to fix that from here, since the server cannot know whether scripting is on. The only markup that avoids the requests entirely is markup with no iframe in it until a click.
| so the black only lands once that stylesheet applies. Until then | ||
| some engines paint an opaque white canvas, which no background on | ||
| the iframe ELEMENT can cover, since the element background sits | ||
| behind that canvas. Hiding the frame sidesteps the whole question: |
There was a problem hiding this comment.
bg-black is a deliberate break from the theme tokens, and it is the right call here even though the original ask was theme consistency: the player itself settles on black in both themes, so a black box makes the reveal invisible, while --bg-sunken would step from near-white to black in light theme. Flagging it only so the literal is not later "corrected" to a token by someone reading it as an oversight.
| const render = () => renderToString(LandingPage()); | ||
|
|
||
| test('the intro frame ships hidden, over a black box', async () => { | ||
| const out = await render(); |
There was a problem hiding this comment.
These pin the SSR markup, which is the part that can silently rot: I confirmed the first fails when the invisible class is removed, so it is not passing vacuously.
What they deliberately do not cover is the reveal itself, since asserting it needs a real load event from a third-party host and that is exactly the sort of test that fails on a plane. I verified that behaviour by hand instead (timings in the summary). Calling it out so the gap is a known one rather than an assumed pass.
The embedded intro clip was replaced with a re-recorded version, so the old video id serves the outdated walkthrough.
A cross-origin iframe paints the UA default canvas until its document arrives, and color-scheme on :root does not propagate into it, so the embed showed a white box through lazy-load and through the fetch. Paint the frame and its wrapper with --bg-sunken, which carries a light-dark() pair and therefore tracks whichever theme the reader is on.
The embed came up as a white rectangle on a dark phone. A cross-origin frame paints its own canvas, and YouTube's embed sets its black background on body with no color-scheme declared, so the black lands only once that stylesheet applies. Until then the engine paints the UA default, and an opaque canvas hides any background the embedding page puts on the element, which is why painting the iframe did not help. Nothing the embedder declares reaches inside a cross-origin frame, so put no frame on screen until the reader wants one. A poster image is an ordinary replaced element with no canvas, so the box shows our own themed background in every engine, and the player arrives on click already playing. It also keeps the embed's third-party script off a page load for the readers who never start the video. A noscript fallback keeps the plain player for the JS-off path, along with a rule hiding the inert server-rendered poster button.
Two defects in the facade, both of which made the embed invisible. The host collapsed to 0px. A custom element is display:block here but its height is auto, so the poster sized h-full resolved against auto and the button measured 0x0. The element now renders its own aspect-video box instead of borrowing height from whatever wraps it. The noscript fallback hid the poster. SSR emitted a style element inside noscript, which is inert raw text to a browser parsing the page with scripting on. The CLIENT render rebuilt the same markup in a template, where scripting is disabled, so the style became a real element and its rule applied, hiding the button on every JS-enabled visit. The fallback is now server-only, which is the only side that can use it. Tests split along the same seam: SSR asserts the fallback is present and no live frame ships, the browser suite asserts the client render emits neither noscript nor style and leaves the poster visible.
The backdrop token and the click-to-load facade are both reverted. The branch is back to the single line it started as, so the flash question can be settled separately on its own merits.
The embed came up as a white rectangle on a dark phone. A cross-origin frame paints its own canvas, and YouTube's embed sets its black background on body with no color-scheme declared, so the black lands only once that stylesheet applies. Before then some engines paint an opaque white canvas, and no background on the iframe element can cover it, since the element background sits behind the canvas. Hiding the frame until it fires load sidesteps the canvas entirely: what it paints early is not on screen, and the box underneath is already the black the player settles on, so the reveal is invisible. Measured under Slow 3G: hidden for 3.1s, then visible on load. onload is a plain HTML attribute because an @event hole drops at SSR and this page never hydrates. A noscript rule keeps the player visible with JS off, where the handler never runs; the page not hydrating is what makes that safe, since the client never rebuilds the noscript body as live nodes.
Revealing the frame on the JS-off path showed YouTube's own noscript error, since their player needs JS INSIDE the frame and nothing this page can do supplies it. An empty space reads better than a broken player, so the noscript rule now hides the section rather than the frame. Verified with scripting genuinely disabled: the section renders at 390x256 with JS on and is absent with JS off.
57e6366 to
e1f2032
Compare
Two changes to the landing page's intro video.
The video. The embed now points at
XghCghezod4, replacing theiz23lVMvlVYclip.The white flash. On a dark phone the embed came up as a white rectangle before the player painted. A cross-origin iframe paints its own canvas, and YouTube's embed sets its black background on
bodywith nocolor-schemedeclared, so the black only lands once that stylesheet applies. Until then some engines paint an opaque white canvas, and no background on the iframe element can cover it, because the element background sits behind that canvas.The fix hides the frame until it fires
load, over a black box. What it paints early is not on screen, and the box underneath is already the black the player settles on, so the reveal is invisible. Measured under Slow 3G: hidden for 3.1s, then visible on load.onloadis a plain HTML attribute rather than a template hole, because an@eventdrops at SSR and this page never hydrates.JS off. The section is hidden entirely. Revealing the frame there showed YouTube's own noscript error, since their player needs JS inside the frame and nothing this page can do supplies it. Verified with scripting genuinely disabled: the section renders at 390x256 with JS on and is absent with JS off. Note that
display: nonesuppresses painting, not fetching, so a JS-off reader still issues the frame's requests.Three SSR tests pin the hidden class, the
onloadattribute, and the noscript rule.