How to combine and minify all loaded css into two files: critical.css and remainder.css? Critical.css should be loaded in the header, remainder.css should be included in the end of the page.


My suggestion is to use a task runner like Gulp or Grunt to do the heavy-lifting for this. With that, there are two ways to handle the critical CSS. The easiest option is to have two endpoint files - one is critical.css where you declare styles that will be added to the head and the other is remainder.css where you have the rest of the styles. Then, configure the task runner to compile those in whatever way works best for your development process. If you use plain CSS, you simply need to minify the files. If you use a preprocessor, just point it to the folder that contains your partials.

The second approach is the one we take with automatically splitting the files out. We use Gulp and the PostCSS Critical Split. We then add comments to the critical portions of our stylesheets and they are automatically removed from the main stylesheet and added to a critical CSS file. We then use Gulp to copy the critical CSS over to the app/.. directory where we inject it directly into a .phtml. We do this by adding a node to layout XML which references the .css file which we include by using the getChildHtml() method.

If you want to include a second stylesheet, the best is to actually use Javascript to make it asynchronous. While most browsers will actually render a styles that were linked to at the end of the body, it is technically not allowed. As a result, an async javascript approach is recommended.

It would look something like this (borrowed from this CSS Tricks article):

function loadCSS(href){
    var ss = window.document.createElement('link'),
        ref = window.document.getElementsByTagName('head')[0];

    ss.rel = 'stylesheet';
    ss.href = href;

    // temporarily, set media to something non-matching to ensure it'll
    // fetch without blocking render
    ss.media = 'only x';

    ref.parentNode.insertBefore(ss, ref);

    setTimeout( function(){
      // set media back to `all` so that the stylesheet applies once it loads
      ss.media = 'all';

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.