Giter Club home page Giter Club logo

css-in-js-101's Issues

RFC: A better way to describe frontend setup (HTML, JS, CSS)

Problem

I try to understand all tradeoffs of different CSS-in-JS approaches. One of the problems is to understand what the setup assumed by the solution and how it affects performance. By "setup" I mean - do we use SSR or Snapshots, do we serve CSS as separate files, do we have critical CSS, do we have async components (dynamic import), etc.

Representation matters

To solve the problem, I want to introduce "language" (symbolic representation) which will be able to describe all cases in a dense form. Representation is important, take a look this talk by Bret Victor to understand why.

Alphabet

We have three major "axis" of a web application, they are HTML, CSS, JS. They will be represented by squares with a letter inside:

  • |J| - JavaScript
  • |H| - HTML e.g. Server-Side Rendering or Snapshot
  • |C| - CSS

On the diagram, they always go in the same order: |J|H|C.

If "axis" is missing it is represented by an empty box. For example, c-r-a doesn't have SSR out of the box, so there is no prerendered HTML: |J| |C|

--- - "browser" line, everything which is above the line is content loaded in the browser. Everything below the line is not loaded content, for example async components. Example react-loadable (or any other async library):

|J| <-- React app
---
|J| <-- async components

~~~ - "browser" line, but loading happens in none-blocking manner. For example loadCSS :

|C|
~~~

Important note: all content of that type should be loaded in the asynchronous mode to be considered as async. So if you have two script tags (with src) in HTML, both should be async.

One box of the type represents 100% of the required content for the current page to work. If there are two boxes of the same type (above the line), it means there is dead code, which is not needed for the current page. For example, a dead code in CSS in a big library, like bootstrap:

|C|
|C|
---

CSS-in-JS in this dieagram will be represented by CSS square (|C|) in JS "axis".

|C|
|J|
---

Note: linaria is CSS-in-JS, but will be drawn other way.

Critical CSS inlined in HTML wil be represented by CSS square (|C|) in HTML "axis".

|C|
|H|
---

Strictly speaking, every React application carries HTML inside, so it should be drawn as HTML square (|H|) in JS axis, but this will create more noise and confusion, so I prefer to omit it.

So now you know the alphabet.

Practical example

Let's analyze one setup, so you catch the idea.

Assume we have c-r-a project with bootstrap, like this one. Let's draw it:

    |C| <-- dead code from bootstrap
|J| |C|
-------
   ^------- no prerendered HTML

What does this tell us? It has pretty poor load performance, there is no HTML, so nothing will be loaded till JS execution. Slow first time to paint. Also slow TTI - everything loaded synchronously.

Let's use react-snap - a small tool for prerendering SPAs, very useful for small mostly static websites.

    |C|
|J|H|C|
-------

This will improve time to first paint. But still we have huge CSS (with dead code) loaded synchronously, let's enable inlineCss option, which will inline critical CSS and make CSS load async:

  |C|C|
|J|H|C|
-----~~

Ah much better - first paint now much faster. HTML and critical CSS are delivered with the first request, so the browser will start to render ASAP. Nice but TTI still can be a problem, there is a JS which is loaded in a synchronous manner. On the other side given website is pretty usable without JS - content is present via prerendered HTML. Filters will not work without JS, but this is not a big issue. So we can use asyncScriptTags: true

  |C|C|
|J|H|C|
~~---~~

Now website will be way faster to load.

Weak sides

You need to be aware that this setup does not represent all aspects of a web application. For example:

  • it does not show capabilities of CSS-in-JS (see @MicheleBertoli list for this)
  • it doesn't communicate developer experience. It feels so nice to work with styled-components
  • and probably it misses a lot of different stuff which I forgot to mention

Did I miss something? This diagram doesn't show web fonts for example, which is known performance bottleneck. Comments are welcome.

Related: https://mntr.dk/2014/getting-started-with-assetgraph/

Variable scope

First of all, nice work, it was a great read!

I discuss some of the issues touched in this repository in my library freestyler. Interesting discussion to explore could be the variable scope CSS template has access to. For example, I split those libraries in 1-5th generation.

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.