{"action":"created","issue":{"url":"https://api.github.com/repos/tkh44/emotion/issues/133","repository_url":"https://api.github.com/repos/tkh44/emotion","labels_url":"https://api.github.com/repos/tkh44/emotion/issues/133/labels{/name}","comments_url":"https://api.github.com/repos/tkh44/emotion/issues/133/comments","events_url":"https://api.github.com/repos/tkh44/emotion/issues/133/events","html_url":"https://github.com/tkh44/emotion/issues/133","id":242216380,"number":133,"title":"feature: static sheet cacheable by browsers (and with IE11 support)","user":{"login":"faceyspacey","id":154732,"avatar_url":"https://avatars3.githubusercontent.com/u/154732?v=3","gravatar_id":"","url":"https://api.github.com/users/faceyspacey","html_url":"https://github.com/faceyspacey","followers_url":"https://api.github.com/users/faceyspacey/followers","following_url":"https://api.github.com/users/faceyspacey/following{/other_user}","gists_url":"https://api.github.com/users/faceyspacey/gists{/gist_id}","starred_url":"https://api.github.com/users/faceyspacey/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/faceyspacey/subscriptions","organizations_url":"https://api.github.com/users/faceyspacey/orgs","repos_url":"https://api.github.com/users/faceyspacey/repos","events_url":"https://api.github.com/users/faceyspacey/events{/privacy}","received_events_url":"https://api.github.com/users/faceyspacey/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2017-07-11T23:47:22Z","updated_at":"2017-07-12T00:05:31Z","closed_at":null,"body":"Hey @tkh44 we talked on Twitter, I figured I formalize what I was talking about somewhere.\r\n\r\nBasically, I have an opinionated vision for CSS, and I had planned to do it myself, but if it belongs in a package that already is fighting the \"extract css\" fight, then that may make more sense. So here are the opinions:\r\n\r\n- forgoing statically-generated stylesheets cacheable by browsers is a *mistake*\r\n- *any* render time \"work\" for styles that are otherwise static is a *mistake*\r\n\r\nBrowsers and CDNs cache stylesheets for a reason. Performance. Forgoing cacheable stylesheets means larger javascript bundles, more work on the server, and more work in each update on the client. \r\n\r\nThe last point is especially important when it comes to a style library since it's closely related to animations, and anyone who's made thoroughly animated apps with React knows dropping frames in conjunction with component instance updates is a constant battle. So for a style library to be adding extra *render time* cycles is a mistake.\r\n\r\nI love the APIs of Styled Components, Glamorous, and now Emotion. It makes a lot of things stupid simple. But then you're missing off on these traditional perf wins. So what's the in-between solution?\r\n\r\n- compile static styles into stylesheets at build time\r\n- focus on writing your styles in javascript (i personally think the future is just javascript). Evaluate that javascript at build time--i.e. giving you the full power of javascript--and generate sheet(s).\r\n- since your styles no longer have access to runtime/render time variables, you're left with environment variables (such as whether your platform is React Native or web, but not things like `window` size--use percentanges, calc, `vh` and `vw` instead). This is fine, because:\r\n- for dynamic styles proceed as normal assigning them to `style` within your components\r\n- use something like [extract-css-chunks-webpack-plugin](https://github.com/faceyspacey/extract-css-chunks-webpack-plugin) to insure you're getting a stylesheet per javascript chunk (this handles the 80% case for not sending useless styles, and also results in ***less bytes sent than render-path solutions since you have to send the definition of your CSS as javascript anyway*** ).\r\n\r\n\r\nNot sure if you read my Webpack \"dual-import\" article:\r\nhttps://medium.com/@faceyspacey/webpacks-import-will-soon-fetch-js-css-here-s-how-you-do-it-today-4eb5b4929852\r\n\r\nBut basically the *extract-css-chunks-webpack-plugin* and *babel-plugin-dual-import* allow you to do what Webpack will be doing soon, which is: fetching both a CSS + JS chunk per call to `import()`. My opinion is obviously that's the way it's supposed to be. That means the past, *present*, and future is bright for cacheable stylesheets.\r\n\r\n\r\n**V2:**\r\n- those dynamic styles could in fact be accounted for (and should). Basically, if you have a function that takes props and returns a style, the babel-plugin should keep that in JS, and combine the class of the static style with its result in the created `<StyleComponent />`. \r\n\r\nSo from the user's perspective, the API would be the same to what you have now. They just also have to do some work to insure they serve those stylesheets to the browser (both on initial load in in calls to `import()`, which my tools make super easy).\r\n\r\nAs for no IE11 support. I mean who can use that besides people building tools for developers, like CodeSandbox? It basically can only be used for developer-only products. You can't make a serious product and forgo modern IE. The above static solution (which should no longer generate CSS variables will handle that). \r\n\r\n**V3**:\r\n- React Native support always has to be in the back of our heads. In RN, `StyleSheet.create` is called with the styles instead of generating anything at build time. Ultimately RN will be less time-consuming.\r\n- various transformations back and forth between RN style definitions and traditional css definitions. ideally vice versa as much as possible\r\n- for this solution to wear the \"crown\" and finally put to rest *the CSS problem*, your styles have to be used as interchangeably as absolutely possible between web and RN.\r\n\r\nSo that's my take. Obviously a lot of what's gone on in the React/CSS world has to do with server-rendering, minimizing CSS bytes size, and making it extremely easy to serve CSS while simultaneously code-splitting. But it's been done wrong in my opinion. Browser-cacheable stylesheets cannot be left out. Sokra's plan as described in the *dual-import* article is the correct one. What this does is also solve the \"bytes size\" problem that render-path solutions try to solve--i.e. where they send the most minimal amount of CSS as consumed during the render path. In short render path solutions aren't the only way to solve that. In fact, it's worse--you're sending the style definitions in your JS anyway. So the total bytes sent is *more* than dynamic split css chunks. And you're also losing cacheability in other more advanced ways too: with render-path solutions, if either ur js or css changes, the cache is busted for both. Whereas if they are independent (and say you don't touch your styles as much), changes to js won't cache bust the css. \r\n\r\n**Final benefit:**\r\nIf you've read Dan Abramov's take on CSS modules in CRA (which are not supported), you will see he's against incorporating it (for several smart reasons, given their aims of targeting non-power-users in a non-webpack-specific way that will future-proof them if they ever leave webpack). I haven't tried, but I assume Glamorous and this work nicely with CRA. Well, the above technique will still work in CRA, and then when you eject and want to go \"pro\" you can add a babel-plugin (loader, etc) that creates the stylesheets for you. So your same code from CRA still can get professional cacheability and all the benefits of this solution. More importantly it still achieves what CSS Modules do (well, after you eject) in a way CRA can support. I think the CRA team would be very excited about that. That way you don't have to use CRA and feel like you're doing it the baby way. You have a future-proof way to do your CSS (and a more professional way compared to having to use global styles). \r\n\r\nSo that's my take. I love the interface, but I don't like the performance costs. I'm also earnestly unclear why the performance benefits are something everyone was so keen to forgo. Why has this happened?\r\n"},"comment":{"url":"https://api.github.com/repos/tkh44/emotion/issues/comments/314606076","html_url":"https://github.com/tkh44/emotion/issues/133#issuecomment-314606076","issue_url":"https://api.github.com/repos/tkh44/emotion/issues/133","id":314606076,"user":{"login":"faceyspacey","id":154732,"avatar_url":"https://avatars3.githubusercontent.com/u/154732?v=3","gravatar_id":"","url":"https://api.github.com/users/faceyspacey","html_url":"https://github.com/faceyspacey","followers_url":"https://api.github.com/users/faceyspacey/followers","following_url":"https://api.github.com/users/faceyspacey/following{/other_user}","gists_url":"https://api.github.com/users/faceyspacey/gists{/gist_id}","starred_url":"https://api.github.com/users/faceyspacey/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/faceyspacey/subscriptions","organizations_url":"https://api.github.com/users/faceyspacey/orgs","repos_url":"https://api.github.com/users/faceyspacey/repos","events_url":"https://api.github.com/users/faceyspacey/events{/privacy}","received_events_url":"https://api.github.com/users/faceyspacey/received_events","type":"User","site_admin":false},"created_at":"2017-07-12T00:05:31Z","updated_at":"2017-07-12T00:05:31Z","body":"Anyway, the \"crown\" could be yours my friend lol. It's yours for the taking. You're clearly the closest anyone has gotten to attaining this \"best of all worlds\" path.\r\n\r\nps. I planned to call it \"Crown CSS\" when I got around to making it. That's the joke--but I think it's only in my head :)"}}
{"actor":{"display_login":"faceyspacey"}}