Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code runs twice on first load: "flash of non-COI code" #14

Open
jcbhmr opened this issue Jul 10, 2023 · 2 comments
Open

Code runs twice on first load: "flash of non-COI code" #14

jcbhmr opened this issue Jul 10, 2023 · 2 comments

Comments

@jcbhmr
Copy link

jcbhmr commented Jul 10, 2023

image
image

Why this is bad. a lot of this is UX-based which is very subjective.

  • Big error screen from "SharedArrayBuffer not defined" shocks user since javascript runs on first page load, only to immediately be replaced by a working site. The user is left wondering "why did it not work, but then work? is this site prone to random errors?"
  • websites can queue up many assets via js on load only to be canceled by the reload. all of which takes time
  • there's a flash of content that the user wants to interact with but as soon as they move their mouse towards the button or scroll down the blog post; BOOM it reloads. they start to think "what did i do to cause that??? is this site broken? did i touch it wrong?"

Why this is good and should stay as-is

  • javascript that doesn't care about COI runs ASAP to do things like change BG color to match the user's theme preference from localStorage and such
  • user has full responsibility to manage content hiding; they can do it however they want
  • user is free to add their OWN loader icon instead of whatever the coi-serviceworker lib does

it seems like the general "feel" of things is that "flash of ____ content" (like "flash of unstyled content") is generally discouraged as bad UX.

if this is actually intentional and the way that you want this library to be used, I think that adding a blurb about this double-execution in the readme would be good. 😊

@jcbhmr jcbhmr changed the title Code runs twice on first load & "flash of non-COI content" Code runs twice on first load: "flash of non-COI code" Jul 10, 2023
@jcbhmr
Copy link
Author

jcbhmr commented Jul 21, 2023

To continue from #16...

Could you help me understand why a top level await that blocks forever is better than

if (!window.crossOriginIsolated) {
  throw new Error("Oh no!")
}

The core reason is so that you don't get a flash of errored content. That's the whole reason 🤣 Take a game for instance that uses SharedArrayBuffer as a core WASM Unity Unreal Engine whatever backend. If there's no SharedArrayBuffer on load, it errors. Thus, to hide said error, you want the page to only load if there's SharedArrayBuffer and otherwise whiteout with a blank page or a loading symbol.

The "throw an error" technique is basically what the app already does, my suggestion is that there be some kind of way to make it so that you avoid those errors potentially making false UI flashes of "oh no there's an err- oh now it refreshed and there's no error"

Basically just a AiO toolkit idea to take that UI/UX burden of managing a <div id=loading> off the end-user and putting it in the .js file.

@WebReflection
Copy link
Contributor

strictly speaking, the code doesn't run twice, it looks like you have persistent logs in your devtools so you see there 2 different page loads.

installing Service Workers is inevitably asynchronous and you can easily bootstrap anything you like once with little extra code:

const COI = Promise[crossOriginIsolated ? 'resolve' : 'reject']();

Now you can await that COI anywhere/anyhow you like and make your logic run only when that resolves instead of rejecting.

The same orchestration can be used to land any other script on the page to avoid counting visits twice, as example ... but the gist is: it's pretty trivial to avoid duplicated code execution and in the worst case scenario, the very first run will already cache some network request so that the reload will be faster once the Service Worker is up and running.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants