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

Usage as render-blocking script #20

Closed
kctdfh opened this issue Apr 14, 2021 · 3 comments
Closed

Usage as render-blocking script #20

kctdfh opened this issue Apr 14, 2021 · 3 comments
Assignees
Labels
question Further information is requested

Comments

@kctdfh
Copy link

kctdfh commented Apr 14, 2021

Is your feature request related to a problem? Please describe.
My issue is that every new page always loads in light mode initially. Meaning that there's a very short flicker when the browser renders the light mode before finding out the user wants dark mode. This makes the implementation look a little unprofessional and is actually annoying when using the site in total darkness.

Describe the solution you'd like
I've looked around and it seems that the solution would be to initialize the dark mode and do all the checks in a script tag placed in <head>. This way, the check is blocking the render for a few extra milliseconds until it figures out the right theme.

Describe alternatives you've considered
I tried to place my darkmode = new darken(options, callback) function in the <head> right after calling the CDN but the browser says Uncaught TypeError: Cannot read property classList of null which occurs 3 times (lines 31, 36, and 96 of the prettified Chrome console).

My options object doesn't set a toggle target nor a container as the DOM is not rendered yet. So I don't know what the issue is.

Additional context
Any other solution that could help me eliminate the flicker would also be appreciated! Cheers

@ColinEspinas
Copy link
Owner

Hello @kctdfh,

The flash that you see happens because your CSS does not use the dark mode at the time you load the DOM.
To prevent that issue, you can use the CSS variables option to change your theme. CSS variables are cached by the browser for the next time you'll load the page. Any other option can lead to the DOM being loaded with wrong styles and having that flash occur.

I tried to place my darkmode = new darken(options, callback) function in the right after calling the CDN but the browser says Uncaught TypeError: Cannot read property classList of null which occurs 3 times (lines 31, 36, and 96 of the prettified Chrome console).

That is a normal behavior as you are trying to apply changes and reference DOM elements before the DOM is loaded. If you want to link the library in the head of your document you can use the defer attribute. Note that this will not block the render (blocking the render of your page to load a script is a very bad practice and you will generally want to avoid it at all cost).

Feel free to ask if you encounter other issues, have a great day.

@ColinEspinas ColinEspinas self-assigned this Apr 14, 2021
@ColinEspinas ColinEspinas added the question Further information is requested label Apr 14, 2021
@kctdfh
Copy link
Author

kctdfh commented Apr 14, 2021

Hey @ColinEspinas

Thank you for taking the time. I was already using variables but made the following changes that eliminated the flash for subsequent page visits. There's still an even shorter stutter when you visit the page with a cleared cache but that's really not an issue. I'll leave my solution here for anyone who may be interested in the future:

  • moved the darken initialization code to its own script tag (instead of loading it with a request) and placed it above all other script tags before closing the body (but after the darken js file). This saved around 200ms due to my single js file approach taking ~200ms to request/download/resolve.
  • Instead of using https://unpkg.com/darken to call the script, I now use https://unpkg.com/darken@1.5.0/dist/darken.umd.js as my framework script's src. The former method leads to at least one redirect which costs ~200ms and most importantly is not cached by the browser. Now the framework code is cached and does not need to be fetched again which saves ~300ms on each page load.
  • I also hadn't defined root variables previously. The variables were referenced in the CSS and were solely the responsibility of darken to define. Now I've placed my root variables in the head.
  • my css file was hosted on Dropbox, with the direct link to it as the src. This meant that it was never cached. I've now uploaded this (and all of my other custom script files) in a Google Cloud Storage bucket with cache_control set to public so that they are always cached. This saves another ~400ms.

The combination of the above measures have fully eliminated the stutter/flicker. They may not all be necessary but the overall load time improvements is an added bonus anyways.

Thanks for making this simple and feature-complete framework 🙏

@ColinEspinas
Copy link
Owner

ColinEspinas commented Apr 14, 2021

I am happy that you've eliminated your flicker issue, I didn't mention it in my previous answer but it obviously is better to link the script to initialize darken as soon as the DOM is loaded and to keep your latency low as this might impact non-cached styles.

All your points seems to make sense to me and I didn't know that the redirection made by unpkg was that slow.

You've made a really great job to go through all the possibilities and I think your answer will help a lot of people passing by, thanks a lot.

As you might seem to have resolved your issues I'll close this issue, do not hesitate to open another one if you need supplementary help.

I am happy to hear that you like this little project, have a great day.

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

No branches or pull requests

2 participants