43

In current project, I was asked for compressing the HTML class attribute and corresponding CSS selectors before deployment. For example, the code on production is:

<div class="foo">
  <div id="bar"></div>
</div>

.foo {/*Style goes here*/}
#bar {/*Style goes here*/}

On deployment, I want the HTML class and corresponding CSS selectors to be substituted:

<div class="a">
  <div id="b"></div>
</div>

.a {/*Style goes here*/}
#b {/*Style goes here*/}

What's the available tools there to archive this compression?

steveyang
  • 9,178
  • 8
  • 54
  • 80
  • 3
    Classes should be readable and understandable, this isn't something you'd do in real life (actually quite a bad idea) and probably a pointless assignment. Optimizing selectors, however, is a good idea. What's your question? – Wesley Murch Nov 09 '11 at 15:47
  • You need a method to transform ".foo" to ".a" and "#bar" to "#b" in your CSS and your HTML? – Galled Nov 09 '11 at 15:49
  • 19
    @Madmartigan They should be readable and understandable when developing, there is no reason why you couldn't compress them when publishing the site. There are plenty of sites that do it, have a look the source at google plus for example. – Niklas Nov 09 '11 at 15:50
  • OP is probably looking for a HTML compressor, the equivalent of google closure compiler for javascript but for HTMl. – aziz punjani Nov 09 '11 at 15:52
  • 7
    Yep, I am looking for a HTML/CSS compressor to finish this task before deployment. – steveyang Nov 09 '11 at 15:56

7 Answers7

14

If you really want to rename class names (keeping in mind what Madmartigan said) Google Closure Stylesheets does that. It's an overkill, and YUI Compressor or any other minification + gzipping tool should give you enough performance boost, but it can do it. You'll have to use other Closure tools to make appropriate changes to your .js files and html templates.

revelt
  • 2,312
  • 1
  • 25
  • 37
Litek
  • 4,888
  • 1
  • 24
  • 28
5

There is also a project called "rename-css-selectors" if you handle the code with node:

https://www.npmjs.com/package/rename-css-selectors

There are plugins for nearly every build tool (webpack, parcel, gulp, ...):

https://github.com/JPeer264/node-rcs-core#plugins

This will minify all CSS selectors in HTML, JS and CSS files (actually any file you want). I saved 20ish% of the CSS filesize at the end.

Jan Peer
  • 305
  • 3
  • 8
4

This is amazingly short-sighted.

  • Step 1: Turn on GZip or Zlib compression in web server
  • Step 2: All text gets compressed, often by 70% or more
  • Step 3: There is no step 3.
  • Step 4: PROFIT
Tyler Eaves
  • 12,879
  • 1
  • 32
  • 39
  • 6
    I strongly suggest anyone downvoting explain why it's better to save 0.1% at the cost of code readability instead of saving tons for free. If you're already compressing in the webserver, then these sort of edits do NOTHING because the compression is already simplifying common sequences. – Tyler Eaves Nov 09 '11 at 15:52
  • Gzip and Zlib has already turned on, but there are still a lot spaces to be trimed for the HTML and CSS files. – steveyang Nov 09 '11 at 15:58
  • 1
    No there's not. Modern, even not so modern compressors like zlib are very good at removing redundant information. That's their job. How big are these HTML files that this is even an issue? – Tyler Eaves Nov 09 '11 at 16:14
  • 1
    gzip does not apply to local files served via `file:`. For a 12MB reference file (yes, a real-world example I'm looking at right now) this glib non-answer to the question is not helpful. The savings in cleaning up a file with verbose names as in my file not "0.1%", they are multiple percent. (This is reasonable advice for those using HTTP 1.1+, however.) – Phrogz Jun 05 '12 at 16:05
  • IF you're slurping the file off the local disk, what does it really matter any way? You're not even talking HTTP _at all_ at that point. – Tyler Eaves Jun 05 '12 at 17:36
  • 32
    you DO NOT need code readability for production! see Google, Facebook and any other major website. all classes and IDs are compressed, to save as much bytes from the HTML and CSS. nobody should care about production readability ever. The **only** parameter is performance. – vsync Sep 04 '14 at 09:50
  • gzip is great, but you can still get significant savings with both. Here's a source that compared the difference between multiple big sites, with savings ranging from 6-16%: http://madskristensen.net/post/effects-of-gzipping-vs-minifying-html-files That's nothing to scoff at. That's for HTML, and gzip savings will vary based on the glyph distribution of different code styles. – TimE Dec 09 '15 at 00:41
  • 2
    @vsync I would add "security" to "performance" in production, too :) – gillytech May 26 '16 at 19:19
  • Use case where your suggestion is useless: standalone HTML files you plan on sending as email attachments. – phk Oct 07 '16 at 08:37
  • I'm skeptical. I would like to see some actual data that shows the difference between compression only and minifying class attributes+compression. gZip has to store another entry in its dictionary for each class it compresses, so there should be additional gains to be achieved by minifying before compressing. And I think these gains may be substantial enough to warrant the extra effort. Especially since CSS often takes up a big portion of the bytes sent over the internet for most websites I've analyzed. – hostingutilities.com Jul 13 '17 at 21:19
  • 1
    What about the dynamically created components that use these classes. We have views that have children in the hundreds, each of these having, presumably, copies of these strings. So to apply the styles to one element it could mean that we concat really long strings, as we have named the classes for readability. However, it's not necessary during production, and our question is if compressing these symbols could save a lot of memory due to not allocating strings which are ~100 characters or more, and instead having ~10 if coding their names. This is the question we have at my place. – Simon Jul 19 '17 at 12:25
  • 1
    There nothing that prevents you from doing both, and in fact, it'll be much better. Gzip tries to remove redundancy by looking for duplicate and assigning less bit (an index in a dynamic dictionary) than the duplicate would have taken. If you reduce the size of the item, it's more likely that it'll be in the dictionary already or it'll appear more often. You'll get a smaller/more efficient dictionary and a much better compression ratio – xryl669 Apr 17 '19 at 17:56
2

There's nothing wrong with minification with gzipping, even before modern browsers introduced source maps, minification was a best practice because you can still get some significant savings even when used in conjunction with gzipping. We put up with worse readability on production because the performance improvement was worth it. Now with source maps, we can have our cake and eat it too. Here's a good article demonstrating the effects of combining minification with gzip on html pages for large sites: http://madskristensen.net/post/effects-of-gzipping-vs-minifying-html-files

The difference in savings you get varies very greatly depending on the glyph distribution of the code being minified, so results will vary depending on the minification strategy and the language being minified, and even just depending on coding style. In the average case the savings are still significant.

Minification handles more than just condensing glyphs, it can also restructure the code to remove unneeded characters while achieving the same effect, something that gzipping can't do.

Now, to get back to your specific question, in your case, you want to minify class glyphs. This is harder to do for several reasons. The scoping of those glyphs are between several files, as opposed to it being possible to scope them to local parts of one file. When minifying javascript, global scope variables do not get replaced by default because they may be needed in another script, but with CSS, you don't know what classes are local and which may be defined in another file. To make matters worse, you also need to sync the class replacement to javascript as well, as it's very common to find DOM elements in code via classes. It would be impossible to sync this, as classes may be constructed dynamically in javascript, and even without that issue, it would be a huge ordeal. You can only sync the glyph replacement in javascript if you change your coding style to make sure you explicitly identify where css class strings are being used: https://code.google.com/p/closure-stylesheets/#Renaming

Luckily, glyph replacement is the thing that minification does that gzipping also does very very well, so the size savings from that particular minification strategy is much much less than the other strategies which remove glyphs entirely.

TimE
  • 2,800
  • 1
  • 27
  • 25
1

There is also gulp-selectors.

Install it:

npm install gulp gulp-selectors

Now a quick-and-dirty node script:

var gulp = require('gulp');
var gs = require('gulp-selectors');
gulp
  .src(['*.html', '*.css'])
  .pipe(gs.run({}, '{ids: "*"}'))
  .pipe(gulp.dest('.'))'

The second argument to gs.run() is in order for it to leave IDs as-is, see also its website: https://www.npmjs.com/package/gulp-selectors

phk
  • 2,002
  • 1
  • 29
  • 54
0

There is plugin https://github.com/vreshch/optimize-css-classnames-plugin Work as Webpack Loader. That might work in most of cases

0

For css there is YUI compressor. It will remove unnecessary white-space, and convert your properties to shorthand if you don't already use it. As for html I don't know any but remember that trimming white space in html is not always safe.

Litek
  • 4,888
  • 1
  • 24
  • 28
  • 1
    YUI compressor does trim CSS files but doesn't substitute the selectors, because it needs to be done both on the CSS and HTML side. – steveyang Nov 09 '11 at 16:07
  • 2
    If you alter the HTML attributes, don't forget to do the same thing to your javascript code if you use ids or classes there. Oh, and don't forget to benchmark and compare the results so you can see how much (or how little) this actually helped. – Wesley Murch Nov 09 '11 at 16:19