Skip to content

Dicussinon: CSS loading #3

Open

Description

@fatawesome

Hello again :D

I am not an expert in nextjs, and I don't quite get how it avoids FOUC (Flash of Unstyled Content) problem, as (at least in this example) instead of inlining styles in <head> it only ads <link preload ... >.

Question is does nextjs somehow block render until styles are loaded or not?

Activity

  1. fatawesome commented on Aug 18, 2021

    @fatawesome
    Author

    Yesterday I investigated it a bit and found out that Next simply places display: none; on <body> until everything is loaded. I believe that is not a good idea for a production application (slow FCP and so on), so I'm planning on writing some plugin which will somehow bundle css on remote in a way that it can be easily consumed on host to be injected in html on server-side.

    If anyone here faces the same issue, I hope we can discuss solutions here despite it does not directly relate to node-mf lib and this particular repository.

  2. telenko commented on Aug 18, 2021

    @telenko
    Owner

    Ah, was not aware of this behavior on the next.js side. I think for SSR it is more complicated to ensure that contents can be shown only after everything was loaded successfully. Interested in your solution.

  3. phoenix-ru commented on Oct 14, 2021

    @phoenix-ru

    Coming back at the issue. As to anyone interested, we managed to solve the remotes CSS issue in the Vue 3 SSR by inlining the styles programmatically on the server.

    It might not be the most optimal solution, as inlining styles isn't as good as using extracted CSS. Anyways, the general process for solving the issue for Vue 3 SFC is:

    1. Use the webpack loader to inject CSS into your component's generated code. I did it by adding a injectStyles function which would require all the component's styles and inject them into the renderer context.
    2. The injectStyles function is then linked to the component lifecycle hook which you know would be executed on the server (beforeCreate for Vue). It is important to have access to SSR context inside the component. In Vue 3 it is done by invoking useSSRContext().
    3. Create a renderer context and pass it to the application (e.g. app = createSSRApp(); html = renderToString(app, ctx)).
    4. After rendering, the styles will be on ctx.styles.

    By the way, all the mentioned steps are implemented in Vue 2 already (make sure you have vue-loader v15), but not in Vue 3 (vue-loader v16 doesn't support it, that's pity). For Vue 3, you need to manually add vue-style-loader to automatically collect the styles into a convenient format (of course, you can collect the output of CSSLoader yourself).

    I believe as soon as you treat the remote components as render + script + styles (instead of just render + script which is the default behavior of vue-loader@16), it is a relatively straightforward task.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions