Code Monkey home page Code Monkey logo

Comments (5)

theKashey avatar theKashey commented on June 2, 2024
  1. With "real" interleaving (possible only in stream rendering) moving should be mandatory before hydration to match generated HTML. However I never tested this moment, considering tested by for example emotion - some technical details were borrowed from their transformers.
    However there is another reason to move styles - you have to hoist them above "real" style definitions to let "real" styles override them if needed. This is more bound to how you write your styles.

  2. Removing is optional. However there is assumption, untested for modern browsers, that the less rules you have - the faster it runs.


How you write your styles

Let's imagine you have a critical styles written in BEM notation:

.myStyle {
 color: red;
}
.myStyle--version1 {
 color: blue;
}

And there is also one more modifier in the "real" styles

.myStyle--version2 {
 color: green;
}

If critical styles would be defined in HTML, and "real" style in the header - due to specificity rules .myStyle will always override .myStyle--version2, which is not what you probably want :)

from used-styles.

hnrchrdl avatar hnrchrdl commented on June 2, 2024

Regarding the specificity, it makes sense. Otherwise it might introduce weird css issues. To be safe, I went with moving and removing the interleaved styles.

For anyone interested, I came up with this solution:

In the header template, I introduce a resolved and a count variable for any style tag:

<script>
  window.__styleTagsResolved__ = 0;
  window.__styleTagsCount__ = <%- styleTags.length %>;
</script>
<% styleTags.forEach(function(tag) { %>
  <%- tag %>
<% }); %>

StyleTags are defined like this (pattern for non-blocking style tags adopted from this post):

createNonBlockingStyleTag = (href: string) =>
    `<link rel="stylesheet" media="print" href="${href}" onload="this.onload=null; this.media='all'; window.__styleTagsResolved__++;">
<noscript><link rel="stylesheet" href="${href}"></noscript>`;

Notice that on resolving of any the the style tags, the number of resolved style tags is counted up.

On the client, before any hydration takes place, I do this to move the styles into the head first and then recursively check if the styles can be removed:

import { moveStyles, removeStyles } from 'used-styles/moveStyles';

moveStyles();
function checkRemoveStyles() {
    if (window.__styleTagsResolved__ < window.__styleTagsCount__) {
        setTimeout(checkRemoveStyles, 50);

        return;
    }
    removeStyles();
}
checkRemoveStyles();

from used-styles.

theKashey avatar theKashey commented on June 2, 2024

Speaking of non-blocking style tags - actually webpack mini-css-plugin and friends might inject "used" .css files on JS start, and consume some of network bandwidth in the moments when it's really needed for other resources.
It might be a good idea to prevent such behaviour.

  • create style tags with data-href attribute refererring used style
  • convert them to style tags manually when ready

(like here and here)

from used-styles.

hnrchrdl avatar hnrchrdl commented on June 2, 2024

interesting idea, thanks for sharing. in my case all script tags (which are preloaded) are inserted at the very bottom of the page and attributed async, so rendering should have already been done the browser (using the critical interleaved styles) by the time any JS is executed.

do you think it might still be an issue? what "other resources" are you thinking of? will images be affected? or other chunks of JS which are loaded at runtime?

from used-styles.

theKashey avatar theKashey commented on June 2, 2024

Other scripts might be affected, as long as styles are usually more "important" than everything else, while in this particular case could be delated.

from used-styles.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.