CSS Optimizations
yshterev opened this issue ยท 15 comments
Some suggestions to make CSS build better:
-
Change
.postcss
extensions to.pcss
. It has been recommended by PostCSS dev team and already there are plugins for its syntax. -
Add
cssnano
- Keep in mind that both, cssnext and cssnano have build-in autoprefixer. Autoprefixer of cssnano should be disabled, while cssnext autoprefixer should enabled according to this issue. -
Add
postcss-import
plugin to work with cssnext. Global PostCSS file should be more organized by importing whatever is required in one file, instead of loading multiple global PostCSS files in js. Also global is good place to importCSS
files from npm packages. Direct import of css inside postcss file works. Check out this guide.
I think we can consider to remove cssnext and use separated plug-ins.
I think cssnext is good. CSS variables already work on modern browsers (excluding IE11), but cssnext adds more features like nesting, mixins by allowing us to use (according to them) latest CSS syntax today. If this is correct cssnext syntax should become part of CSS standards in future. It makes a strong point for long-term use to me.
@equinusocio What would you replace it with?
@yshterev CSSNext is just a wrapper, it use other postcss plugins under the hood that can be used directly. If you check the cssnext features page you can see that each feature have his related postcss plugin.
By using plugins directly we can have more control of updates and plugins versions and, for example, we can use postcss-css-variables over postcss-custom-properties (used by cssnext) because the first one follow the spec and allow custom properties declaration inside any valid css selector.
@equinusocio Good :) I agree. I thought cssnext plugins were future-proof :(
Change .postcss extensions to .pcss. It has been recommended by PostCSS dev team and already there are plugins for its syntax.
- Done
Add postcss-import plugin to work with cssnext. Global PostCSS file should be more organized by importing whatever is required in one file, instead of loading multiple global PostCSS files in js. Also global is good place to import CSS files from npm packages. Direct import of css inside postcss file works. Check out this guide.
@yshterev I'm not sure if i understood what do you mean. Are you talking about moving css dependencies inside the .pcss file? What do you mean for "Also global is good place to import CSS files from npm packages", a global css file ๐?
About cssnano, i don't think we must add this plugin, i use it almost everywhere, but it add an heavy optimisation step that can be very arguable.
Anyway we are switching to postcss-easy-import
(removing cssnext) so we can import styles from the local folder, from the project root and from node_modules. I'm moving css deps outside the js and add them in each pcss file.
@equinusocio Sorry... I read it now and I agree what I wrote is confusing ๐. I pretty much meant what you actually did. I called it global css because the folder holding the files is called global-style
, but its not really global because it is scoped to the sk-app
component.
global-style
contains global reusable css like basic elements styling and animations. These files should be included in each component style, when needed. In our demo template, we need those files only inside sk-app
. But they can actually be imported inside each scoped component.
I understand what you are trying to achieve and it is not bad, but I think there is a pitfall.
All styles are compiled into the js bundle for each component individually. If you have a complex app and you import same CSS into many components the way you suggest, each component will have a copy of the same CSS in the bundle. This will result in a significantly bigger bundle size and also violates the DRY principle.
Polymer 1 had shared-styles to solve that. I can't find anything similar for Polymer 3 - no more HTML imports.
By real global CSS I mean CSS that stays at document level, like this. It can be used to overwrite variables for themes and layouts for the entire application.
Regarding cssnano - It can be used for production builds only by passing options to config.
What do you think @LasaleFamine ?
@yshterev I agree with you but with Shadow DOM (not polymer) there is no way to avoid this and violate the DRY principle. You will have same CSS inside each component, but this follow the component dependencies management. So, if a component (or a set of components) doesn't need a specific keyframe, the css should not exist globally inside the document, but it should live inside the component. I can't find out a perfect solution, right now having a single source of global style is the best solution i found since we have duplicated output but one "source of truth" to edit.
Maybe importing css files inside js can solve this problem? IDK
It is ok for now I guess. There is an open issue for API implementation.
I think currently there isn't a perfect solution for this problem. I think for sure the issue linked by @yshterev must be watched, also maybe we can achieve something similar to that registerStyleModule
with the help of Webpack. I need to investigate more about this.
Anyway in a world of components, the shared CSS should be really small or maybe not present at all.
I rendered my shared styles to a css file and used the <link rel="stylesheet" href="/path/to/style.css>
is there any negative to using <link>
over including a shared string in a style tag?
Well I think this is more a question about the standards of using the tag inside the body.
There are a bunch of answers about this question (like https://webmasters.stackexchange.com/a/55133).
Talking about how this could affect the skeleton, in this case, I think the CSS won't be processed by the postcss-loader, but of course you can process your CSS as you want and load it with the link tag if you prefer.
@stagfoo You are talking about linking the css inside an element or inside the document root (index.html)?
If we are talking about adding <link>
inside an element, external stylesheets are deprecated from polymer 2.0. I suggest you to don't use this method. You can read more info about this deprecation here:
https://www.polymer-project.org/2.0/docs/devguide/style-shadow-dom#external-stylesheets
If you want, you can define a style-module that is an alternative way, but i think that this solution does not have much sense with polymer 3 + webpack, when you can directly import the css file inside the element when you need it.
If you mean linking css inside the document root, this method break the polymer global style shim and the custom properties shadow-root piercing.
BTW, @LasaleFamine i think we can close this issue, since we made all the optimisations.