Collect styles used on to create a page
npm install used-styles

> πVersion 3 migration notice: import { discoverProjectStyles } from 'used-styles/node'. That's it
---
> Bundler and framework independent CSS part of SSR-friendly code splitting
Detects used css files from the given HTML, and/or inlines critical styles. Supports sync or stream rendering.
Read more about critical style extraction and this library: https://dev.to/thekashey/optimising-css-delivery-57eh
- π Super Fast - no browser, no jsdom, no runtime transformations
- πͺ API - it's no more than an API - integrates with everything
- π€ Works with strings and streams
- β³ Helps preloading for the "real" style files
Works in two modes:
- π inlines style rules required to render given HTML - ideal for the first time visitor
- ποΈββοΈinlines style files required to render given HTML - ideal for the second time visitor (and code splitting)
Critical style extraction:
- π§± will _load_ all used styles at the beginning of your page in a string mode
- π will _interleave_ HTML and CSS in a stream mode. This is the best experience possible
1. Scans all .css files, in your build directory, extracting all style rules names.
2. Scans a given html, finding all the classes used.
3. Here there are two options:
3a. Calculate all style rules you need to render a given HTML. 3b. Calculate all the style files you have
send to a client.
4. Injects or
5. After the page load, hoist or removes critical styles replacing them by the "real" ones.
For the performance sake used-styles inlines a bit more styles than it should - it inlines everything it would be "not
fast" to remove.
- inlines all @keyframe animations
- inlines all html, body and other tag-based selectors (hello css-reset)
- undefined behavior if @layer a,b,c is used multiple times
> Speed, I am speed!
For the 516kb page, which needs 80ms to renderToString(React) resulting time for the getCriticalRules(very
expensive operation) would be around 4ms.
Use it to scan your dist/build folder to create a look up table between classNames and files they are described in.
1. discoverProjectStyles(buildDirrectory, [filter]): StyleDef - generates class lookup table
> you may use the second argument to control which files should be scanned
filter is very important function here. It takes fileName as input, and returnsfalse, true, or a number as result. False value would exclude this file from the set, true - add it,
and number
would change the order of the chunk. Keeping chunk ordered "as expected" is required to preserve style declaration
order, which is important for many existing styles.
``js`
// with chunk format [chunkhash]_[id] lower ids are potentialy should be defined before higher
const styleData = discoverProjectStyles(resolve('build'), (name) => {
// get ID of a chunk and use it as order hint
const match = name.match(/(\d)_c.css/);
return match && +match[1];
});
> β οΈ generally speaking - this approach working only unless there are no order-sensive styles from different chunks applied to a single DOM Element.
> Quite often it never happen, but if you are looking for a better way - follow to #26 β£οΈ
1. loadStyleDefinitions is a "full control API", and can used to feed used-styles with any custom data, for example
providing correct critical css extraction in dev mode (no files written on disk)
`tshttp://localhost:${process.env.DEV_SERVER_PORT}/${file}
return loadStyleDefinitions(
/list of files/ async () => cssFiles,
/data loader/ (file) => fetchTxt()`
/filter and order / // (file) => order.indexOf(cssToChunk[file])
);
Use to get used styled from render result or a stream
2. getUsedStyles(html, StyleDef): string[] - returns all used files, you will need to import themgetCriticalStyles(html, StyleDef) : string
3. - returns all used selectors and other applicable rules, wrappedstyle
with getCriticalRules(html, StyleDef): string
4. - the same, but without