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

non-fastboot UX -- options for eager loading of known needed assets / default languages? #17

Closed
NullVoxPopuli opened this issue Sep 2, 2023 · 5 comments

Comments

@NullVoxPopuli
Copy link

NullVoxPopuli commented Sep 2, 2023

tl;dr: I think for the best non-fastboot UX, the primrary languages someone is working with should be eagerly loaded, so there is no async behavior to wait on. This is solved by specifying defaultLanguages and defaultThemes (if applicable) in the environment.js under the ember-shiki ENV config.

This eagerness helps prevents a sort of "flash of unstyled content", which can be jarring to folks looking at the exact place where formatting/highlighting/etc are about to take place.

Also big caveat: I'm working with a very atypical app, a REPL.


I've been exploring ember-shiki and the idea of lazy load everything here: NullVoxPopuli/limber#1303

But I have a problem where the loading experience is noticeably worse than what I had with highlight.js (which was effectively synchronous)

Compare by clicking through a few of the tutorial chapters and paying close attention to how the codeblocks are highlighted

I noticed that there is some config: https://ember-shiki.pages.dev/#configure-(optional)
that maybe sounds like it could solve my problem -- but it's not explicitly stated in the docs? should it be?

    'ember-shiki': {
      defaultLanguages: ['gjs', 'gts', 'css', 'bash', 'js', 'ts', 'markdown'],
      defaultThemes: ['one-dark-pro'],
    },

The config did help my rendering UX be less async.


However, because I'm now using ember-repl in the tutorial to generate a component (which is async), there is a bit of a de-sync now between my "scroll-to-top" behavior and rendering of the next page (which, when I used the modifier, highlighting was instant and I could compile just markdown synchronously) 😅 -- but this is probably a timing a thing I need to work out anyway. But the compilation stuff is very heavy (babel, template-compiler, etc) -- previously I was only using the unified pipeline with remark and triple-curlies -- so it was very fast 🙃


Some pagespeed insights costs that occurred due to me needing to change how I render prose:

The Tutorial

55 on Mobile -- Today (I still have quite a bit to improve on here) https://pagespeed.web.dev/analysis/https-tutorial-glimdown-com/y2voonddn1?form_factor=mobile
43 on Mobile -- the branch where everything is loaded (babel, ember-repl, etc) https://pagespeed.web.dev/analysis/https-fbfe8dfe-limber-glimmer-tutorial-pages-dev/mgcgkfiwcj?form_factor=mobile

The REPL
63 on Mobile -- babel is deferred until JS is rendered https://pagespeed.web.dev/analysis/https-limber-glimdown-com/37ehzcf3e4?form_factor=mobile
56 on Mobile -- babel is loaded eagerly https://pagespeed.web.dev/analysis/https-845396c8-limber-glimdown-pages-dev/ksll922uk9?form_factor=mobile


Additionally, I noticed (before I set the above config) on the REPL (which is fixed now, due to specifying explicit languages), that if you wait for the preview text to highlight (in the editor area) (before you move the mouse, trackpad, or have any touch/keyboard inputs (at which point the editor would load and replace the preview)), the tab freezes, where it didn't previously 🤔
I also noticed that for Markdown, it seems shiki loads every language language ever? it takes quite a while!
Is there a way to configure which markdown languages and aliases are loaded (while using async everything?)? maybe this is just something to "be aware of" when not specifying pre-loaded languages?
image

@IgnaceMaes
Copy link
Owner

Currently the functionality offered by CodeBlock is to encapsulate all async behaviour to ease integration, as you can use the component without configuring anything else and it just works.

The API offered by Shiki is async, so if there would be an synchronous way to use CodeBlock it would expect that Shiki is already properly initialized and themes/languages are loaded before it's invoked. Initializing Shiki once before rendering anything could be achieved by e.g. doing the initializing in an application initializer, or in a beforeModel hook on a route.

This is something you could already do:

async beforeModel() {
  await this.shiki.initialize.perform();
}

That would load all predefined languages and themes already. The CodeBlock component would still not render 100% synchronously due to the way it currently uses the modifier which performs an async task. Perhaps here there should be a way to make it render instantly assuming the theme/language is loaded.

Overall Shiki would still be less performant compared to Highlight.js in the sense that it uses vscode-oniguruma for tokenization which is quite heavy. It's more optimized for correctness and features, rather than file size in browser.


Regarding Markdown loading all languages, this is expected behaviour as all those languages are defined as embeddedLanguage in Shiki. One way to solve this would be to use a custom grammar definition as mentioned in #18 (comment).

@NullVoxPopuli
Copy link
Author

NullVoxPopuli commented Sep 3, 2023

Sounds good!
I just thought also that it'd be a good idea to make sure that padding, margin, and font properties (family, size, line height, kerning, etc) all match the theme that's about to be loaded (likely only if not using a custom theme) -- that'd probably help quite a bit with the noticeable content shift once highlighting happens.

Do you think it'd be good to have a tiny section in the docs about this? Or is it something people should just know, and i forgot? Lol

@IgnaceMaes
Copy link
Owner

I was actually just working on that! Added CSS variables for padding and updated the docs (although it could use further elaboration 😄): #19 (comment)

Not sure what you mean with adjusting the properties bases on the theme? As the themes don't include these settings, only the color styling.

@NullVoxPopuli
Copy link
Author

ah ok, maybe it's more that I needed to make
https://github.com/IgnaceMaes/ember-shiki/blob/main/ember-shiki/src/styles.css#L8
match my current font?

anywho, thanks for the additional docs!

@IgnaceMaes
Copy link
Owner

ah ok, maybe it's more that I needed to make https://github.com/IgnaceMaes/ember-shiki/blob/main/ember-shiki/src/styles.css#L8 match my current font?

Yes, that would be the intended way to style the CodeBlock!

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