You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+79-1Lines changed: 79 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@ An exceptionally fast, thorough and tiny unused-CSS cleaner _(MIT Licensed)_
7
7
8
8
DropCSS is an exceptionally fast, thorough and tiny ([~9 KB min](https://github.com/leeoniya/dropcss/tree/master/dist/dropcss.min.js)) unused-CSS cleaner; it takes your HTML and CSS as input and returns only the used CSS as output. Its custom HTML and CSS parsers are highly optimized for the 99% use case and thus avoid the overhead of handling malformed markup or stylesheets, so you must provide well-formed input. There is minimal handling for complex escaping rules, so there will always exist cases of valid input that cannot be processed by DropCSS; for these infrequent cases, please [start a discussion](https://github.com/leeoniya/dropcss/issues).
9
9
10
-
As a bonus, DropCSS will also remove unused `@keyframes` and `@font-face` blocks - an out-of-scope, purely intra-CSS optimization. Speaking of which, it's a good idea to run your CSS through a structural optimizer like [clean-css](https://github.com/jakubpawlowicz/clean-css), [csso](https://github.com/css/csso), [cssnano](https://github.com/cssnano/cssnano) or [crass](https://github.com/mattbasta/crass) to re-group selectors, merge redundant rules, etc. It probably makes sense to do this after DropCSS, which can leave redundant blocks, e.g. `.foo, .bar { color: red; }; .bar { width: 50%; }` -> `.bar { color: red; }; .bar { width: 50%; }` if `.foo` is absent from your markup.
10
+
As a bonus, DropCSS will also remove unused `@keyframes` and `@font-face` blocks - an out-of-scope, purely intra-CSS optimization. Speaking of which, it's a good idea to run your CSS through a structural optimizer like [clean-css](https://github.com/jakubpawlowicz/clean-css), [csso](https://github.com/css/csso), [cssnano](https://github.com/cssnano/cssnano) or [crass](https://github.com/mattbasta/crass) to re-group selectors, merge redundant rules, etc. It probably makes sense to do this after DropCSS, which can leave redundant blocks, e.g. `.foo, .bar { color: red; } .bar { width: 50%; }` -> `.bar { color: red; } .bar { width: 50%; }` if `.foo` is absent from your markup.
11
11
12
12
More on this project's backstory & discussions: v0.1.0 alpha: [/r/javascript](https://old.reddit.com/r/javascript/comments/b3mcu8/dropcss_010_a_minimal_and_thorough_unused_css/), [Hacker News](https://news.ycombinator.com/item?id=19469080) and v1.0.0 release: [/r/javascript](https://old.reddit.com/r/javascript/comments/bb7im2/dropcss_v100_an_exceptionally_fast_thorough_and/).
13
13
@@ -230,6 +230,84 @@ server.listen(8080);
230
230
})();
231
231
```
232
232
233
+
---
234
+
### Accumulating a Whitelist
235
+
236
+
Perhaps you want to take one giant CSS file and purge it against multiple HTML sources, thus retaining any selectors that appear in any HTML source. This also applies when using Puppeteer to invoke different application states to ensure that DropCSS takes every provided application state into account before cleaning the CSS. The idea is rather simple:
237
+
238
+
1. Run DropCSS against each HTML source.
239
+
2. Accumulate a whitelist from each result.
240
+
3. Run DropCSS against an empty HTML string, relying only on the accumulated whitelist.
241
+
242
+
See [/demos/accumulate.js](/demos/accumulate.js):
243
+
244
+
```js
245
+
constdropcss=require('dropcss');
246
+
247
+
// super mega-huge combined stylesheet
248
+
let css =`
249
+
em {
250
+
color: red;
251
+
}
252
+
253
+
p {
254
+
font-weight: bold;
255
+
}
256
+
257
+
.foo {
258
+
font-size: 10pt;
259
+
}
260
+
`;
261
+
262
+
// html of page (or state) A
263
+
let htmlA =`
264
+
<html>
265
+
<head></head>
266
+
<body>
267
+
<em>Hello World!</em>
268
+
</body>
269
+
</html>
270
+
`;
271
+
272
+
// html of page (or state) B
273
+
let htmlB =`
274
+
<html>
275
+
<head></head>
276
+
<body>
277
+
<p>Soft Kitties!</p>
278
+
</body>
279
+
</html>
280
+
`;
281
+
282
+
// whitelist
283
+
let whitelist =newSet();
284
+
285
+
let resA =dropcss({
286
+
css,
287
+
html: htmlA,
288
+
});
289
+
290
+
// accumulate retained A selectors
291
+
resA.sels.forEach(sel=>whitelist.add(sel));
292
+
293
+
let resB =dropcss({
294
+
css,
295
+
html: htmlB,
296
+
});
297
+
298
+
// accumulate retained B selectors
299
+
resB.sels.forEach(sel=>whitelist.add(sel));
300
+
301
+
// final purge relying only on accumulated whitelist
0 commit comments