isomorphic-style-loader icon indicating copy to clipboard operation
isomorphic-style-loader copied to clipboard

Integrating with Extract Text Plugin

Open papigers opened this issue 8 years ago • 12 comments

Is there a way to integrate the isomorphic style loader with the extract text plugin, which I currently use on prod? Also, how could you include many styles to single component? (for instance, in my root component, in addition to my style file I also include external styles like font awesome (.less) and bootstrap grid (.scss))

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/34670738-integrating-with-extract-text-plugin?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

papigers avatar May 29 '16 04:05 papigers

@papigers if you need to extract all the CSS into a single file for production, then there is no need in using isomorphic style loader for you, as you can just use regular style-loader provided by Webpack.

The goal of this loader is being able to extract critical path CSS and pre-render that CSS individually for each web page. For example:

<html>
  <head>
    <style>/* critical-path CSS, only what's required to render that page */</style>
    <script async src="/bundle.js"></script>
  </head>
  <body>
    <div id="container"><%-- pre-rendered HTML --%></div>
  </body>
</html>

For more info visit: https://developers.google.com/web/fundamentals/performance/critical-rendering-path/

Regarding your second question, you can include multiple styles as follows:

import React from 'react';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s1 from './Style1.css';
import s2 from './Style2.css';

function MyComponent() {
  return <div className={`${s1.one} ${s2.two}`}>...</div>;
}

export default withStyles(s1, s2)(MyComponent);

koistya avatar May 29 '16 11:05 koistya

Got it, thanks! So, between extract text plugin and isomorphic style loader, what is better, performance wise? On the one hand isomorphic style loader enables you to render only critical path css, as you said. But on the other hand extract text plugin bundles your entire css which can be fetched in parallel along the application code.

papigers avatar May 29 '16 12:05 papigers

The approach with extract text plugin doesn't allow you to embed into the page critical-path CSS thus optimizing the initial page load time, also it requires at least two HTTP requests do download app code - one for bundle.css file and another one for bundle.js file, whereas with isomorphic style loader both CSS and JavaScript code can be downloaded with a single HTTP request that can be started asynchronously, e.g. when you put <script async src="/bundle.js"></script> in the head section of your HTML page.

koistya avatar May 29 '16 14:05 koistya

K, thanks. I'm having difficulties deciding which tools are best for universal/isomorphic web development. I've used extract text plugin so far but I think I'll migrate to this. Any tips or tutorials you found useful? Also, how compatible is it with webpack-somorphic-tools?

papigers avatar May 29 '16 15:05 papigers

What about accomplishing what ExtractTextPlugin does - a separate file, but pull the critical css out and put it inline as you are doing here. This may not be the tool for that... but that seems a good alternative for some use cases.

mjsisley avatar Jun 05 '16 05:06 mjsisley

@mjsisley agreed, trying to accomplish that myself. I want to async load a full css bundle, and inline critical path css. right now I'm running webpack twice. once to build critical path css bundle, and manually inlining, then a second time to produce my main bundle and asyncing loading it.

ezekielchentnik avatar Jun 29 '16 20:06 ezekielchentnik

I've resorted to the same method as you @ezekielchentnik. It does the trick for now :)

horyd avatar Jul 13 '16 17:07 horyd

@ezekielchentnik

Inlining critical css and having the full css-bundle asynchronously loaded definitely seems to be the way to go. I've been experimenting with only using this loader server side and using extract-text-loader on the client, thus avoiding having to run webpack multiple times. Seems to work well enough.

alexanderchr avatar Aug 06 '16 13:08 alexanderchr

@alexanderchr how to you accomplish loading css asynchronously? Does the link element have an async attribute, as the script element? or you just load it in the bottom of the body?

papigers avatar Aug 06 '16 22:08 papigers

I'm by no means an expert on this, but there seems to be a lot of browser inconsistency in how link tags are handled. Putting it in the body will work in some browsers while others will render-block as if it were in the head.

There is something like async, rel='preload' which would be ideal but its browser support is unimpressive. filamentgroup/loadCSS provides a polyfill for it. This is what I use.

More reading:

  • https://codepen.io/tigt/post/async-css-without-javascript
  • https://gist.github.com/scottjehl/87176715419617ae6994

alexanderchr avatar Aug 07 '16 01:08 alexanderchr

@ezekielchentnik or @horyd Do you have a gist of how you are accomplishing this?

...once to build critical path css bundle, and manually inlining, then a second time to produce my main bundle and asyncing loading it.

rossthedevigner avatar Sep 14 '16 16:09 rossthedevigner

@koistya

you can just use regular style-loader provided by Webpack

Wrong! You can't use style-loader on server-side!

wzup avatar Apr 09 '17 23:04 wzup