
CSS Purge - tnorthcutt
http://www.csspurge.com/
======
theaustinseven
Yes, CSS might be a big problem, but people's obsession with overriding
everything with Javascript is a much bigger problem. I think web
developers/designers need to move more towards lighter webpages that use HTML
for functionality whenever possible, which is something that might seem
obvious, but is so rarely done.

~~~
Smudge
For a while I worked on and made use of a very lightweight JS framework that
would essentially do two things:

* Intercept link clicks and form submissions and perform the exact same request asynchronously (AJAX)

* Wait for the server to respond with the parts of the page that need to be swapped-out (a JSON map of section IDs to plain HTML content) and, as expected, swap out those parts of the page.

This works REALLY well for, like, 80% of my use cases. With a little extra
flavor functionality (such as automatic loading indicators and event
listeners) I can enable like 90% of interactivity. The remaining 10% consists
of things that affect only temporary state and don't require a server round-
trip (e.g. a "select all" checkbox), and those I would handle with more
traditional jQuery DOM manipulation.

For the most part, once I had this basic system in place, I could rely on the
server to render (and re-render) all of the HTML and rarely had to write any
custom Javascript. I was essentially relying on the behavior of vanilla links
and forms. The site would even continue to function if you disabled
Javascript, because the server would see that it wasn't AJAX and just render
the whole page instead. The downside was that preserving local state (e.g.
partially completed form fields) was tricky whenever I had to make a change to
one of its parent containers.

Everything I learned about this approach eventually led me to appreciate what
React.js is doing. I've been using it and I may not like all of its API or how
heavy it feels overall, but the cycle of rendering and re-rendering different
parts of the page feels very natural and is far easier to debug than most JS-
heavy front-ends.

~~~
gkya
Why just don't let the hyperlinks do what they are supposed to do, which is
what you do at the end of the day anyways, then?

When I approach a link, I hover, see the href on the status bar, think and
decide, and click. Thereafter, I expect it to take me somewhere else, while
the browser pushes the url of the page I left into a stack, the history. This
implemented and working in my browser already, why redo it with JS? To lower
the load time? Then don't make the page multi-meg already, no?

The ugly thing is govt websites and such are adopting a similar style of web
app design, relying upon wizardy and tricks and hacks, for example, I sweat
blood when I use my uni's web pages because I'll hit a bug in the js for an
already-there popup or a button and it'll hurt my educational career.

~~~
Smudge
One thing I'm not sure I made entirely clear. Whenever my JS library
intercepts a link or button click, it will update the URL bar with whatever
the link or form would've brought you to, so that at any time if you refresh
the page it will result in the same state that the AJAX gave you. Also, the
approach is designed to gracefully degrade if JS is disabled, because the
links and forms really are just links and forms.

> why redo it with JS? To lower the load time? Then don't make the page multi-
> meg already, no?

I hear you, and often I let links do their full behavior, no JS magic
involved.

But beyond a certain amount of interactivity, the AJAX intercept approach does
add a few things beyond just load time:

* Even if your payload is very small, the HTTP round trip can make the interaction feel slow, especially if your browser has to go through the full load+render routine. Things like images and sometimes even the whole page will flicker. When all you need to do is update a very tiny portion of the page, having a thin JS layer on top of your usual link/form element can be a significant UX improvement.

* Say you have a page with a few interactive buttons/links and a form with text input. Without any AJAX, if you click a button or link (that isn't the form's submit button), it will wipe anything you had entered into the text field. Not a great experience.

~~~
gkya
> Whenever my JS library intercepts a link or button click, it will update the
> URL bar

The browser does this already.

> Even if your payload is very small, the HTTP round trip can make the
> interaction feel slow, especially if your browser has to go through the full
> load+render routine. Things like images and sometimes even the whole page
> will flicker.

Browsers are very smart these days, caching many things. And if the bloat is
eliminated (unnecessarily large images [make thumbnails], custom widgets [use
what's there], etc.), if you webpage is not the whole of the Emacs or FreeBSD
manual, it'll load in about a second or so at worst. The progressbar will
indicate that it's loading, so the user will know that the server is live and
he's not standing there waiting to see a HTTP 50* or 40* or a lookup error.

> Say you have a page with a few interactive buttons/links and a form with
> text input. Without any AJAX, if you click a button or link (that isn't the
> form's submit button), it will wipe anything you had entered into the text
> field. Not a great experience.

Also an inexistent experience. Most browsers do retain the contents after
navigation, both ways. I use xombrero and it does. Chrome too, I just tried
it.

If downloads of your web pages are >1sec, check your web application, web
server, proxies, asset file sizes, loading order, internet connection, status
of hosting, etc. Use default widgets on your forms and don't fiddle with their
default behaviour. Otherwise when everybody puts out their shiny new idea, the
users become timid to click anything. But I guess if all the websites were
like this thousands of front-end devs and web designers would lose their jobs,
and thus we have all these websites.

~~~
Smudge
_sigh_

I guess my overall point here was that you can build a sufficiently
interactive webapp without a bloated, client-side, MVC, virtualDOM, JS
monstrosity. And that there are widely varying degrees of complexity to these
implementations.

So, on the one hand, you have Ember, Angular, Backbone, React, etc. On the
other hand you can have what I described. A very thin, very maintainable layer
on top of what the browser is already doing.

That was the point.

Anyway, one other thing:

> Most browsers do retain the contents after navigation, both ways.

That's not what I meant. What I meant is that sometimes you need a button or
link to take you back to the exact same form, just update the page slightly.
(Add an optional field, etc. Think if you are entering an "album" and need to
add a list of "tracks"). Without any JS/AJAX, that "add track" button will
require a bit of finagling to not clear out the rest of the form that you've
already partially filled out (but aren't ready to submit). I don't know if my
example is entirely clear, but it's about enabling a certain amount of
interactivity without relying on more standard JS bloat.

~~~
onion2k
_I guess my overall point here was that you can build a sufficiently
interactive webapp without a bloated, client-side, MVC, virtualDOM, JS
monstrosity._

Given the fact that most of the bloated JS monstrosities you're talking about
are also the most popular websites around (Facebook, Google, Pinterest), I
think this assumption might be wrong.

Do you have any examples of popular, complex web apps that work the way you
suggest is better? Why is it that Facebook etc don't make things that work the
way you're talking about?

~~~
aregsarkissian
I think he means sites that are not as complex as Facebook etc think they need
to use the same framework as Facebook etc uses where they would be perfectly
fine using the pjax/turbo link style approach the op suggests

~~~
Smudge
Yes, this is what I meant. One prominent example is GitHub. As far as I know
they still take pjax/turbolinks to an extreme, in favor of a true client-side
template/view framework.

------
onion2k
Unless data can demonstrate that reducing the number of classes or IDs on a
page has a positive impact on things like returning DAUs, sign up conversions,
etc, I'd argue these might be the wrong things to optimise. If adding another
font to your site gets another 1% of users to buy something, you should add
the font. Equally thought, if removing one gets 1% more sales, you should
remove one. That's what counts, and it won't be the same for every site.

Use data, not rules.

------
nmbr213
It's funny how they say CSS should be optimized, while they use 6 different JS
files for particle animation (one for each site + header, the only difference
being canvas size, particle count and color)

------
colmvp
Why do some of these sites have font families numbering in the double digits?!

~~~
KevanM
Designers.

~~~
paublyrne
Bad designers.

------
WA
And there, I thought for a moment, my 38 KB CSS file is a mess and way too
big. I guess, this puts it into perspective.

~~~
theandrewbailey
My blog's CSS is 100k. Take out the three embedded base64 webfonts, and it's
6k.

~~~
davidwparker
My blog's 2.4kb. It's way too big (and my blog sucks on mobile). I've been
rethinking about how I can redesign my blog to be as close to
[http://bettermotherfuckingwebsite.com/](http://bettermotherfuckingwebsite.com/)
as possible.

~~~
Nadya
965 bytes for mine. I should (but didn't, will tonight) minify the CSS, which
will bring it down to 650 bytes. My site is very much in line with BMFW and
IMO it looks pretty nice. But it's also very, very basic.

There are very few things that I would style for a text-based website:

1) The h1, h2, p, strong, and a elements. Font-family, font-size, color,
a:hover, and line height attributes only.

2) Create a container (eg: max-width 44em, margin: 0-auto, width: 100%) to
wrap everything in.

From there the "heaviest" parts of the blog would be navigation and how
accessible you want a complete archive list to be or if Previous/Next links
would be suffice.

E:

800px -> 44em, see response below.

~~~
Filligree
Unless you have some specific reason to otherwise, please specify container
widths using ems instead of pixels.

That keeps things easy to read for users that want to override the font sizes.
40-60 is a good range.

~~~
Nadya
Yes! You're completely right and I've argued something similar against sites
that like to set 62.5% font size on body. Thank you for calling out my poor
example! I'll update it if it lets me.

For those who don't yet know why this is a big deal, I made a Codepen to
illustrate why:
[http://codepen.io/anon/pen/eZwxam](http://codepen.io/anon/pen/eZwxam)

Change the font size from 18px to 12px and then to 24px to simulate users with
varying default font sizes set in their browser. Note how the containers
change. While it will vary from person to person, a fixed 800px width of a
container with 12px font size is far too wide for my taste and far too narrow
for 24px. While I find 44em is better for both.

Note: I do not suggest ever changing the font size of body but it makes the
example easy to use.

------
spankalee
Shadow DOM and it's scoped styling is going to help this situation so much.

Instead of large stylesheets with tons of highly-specific selectors, and quite
a few broken and unused rules, web components will be able to use small
stylesheets with simple selectors that only apply to their local scope, and
developers will be able to reason about and maintain styles that are limited
to a single web component.

------
partiallypro
I dream of a day when you can have CSS loaded that has no dead weight. If one
page doesn't have an accordion, there's no point in it loading the accordion
CSS. Foundation slimmed down their base CSS files because it had so much dead
weight from 5 to 6; but I wish there were some way (and I have seen some
projects on GitHub) that I could load a page and it only would load the CSS
needed for that page, but would still cache the common assets.

~~~
onion2k
What problem would that solve?

~~~
partiallypro
Your server serving up tons of code that is not being used at all?

~~~
onion2k
That would assume the user is only going to view one page. If they look at
several pages then it'd be better to have sent all the CSS necessary in the
first request and have their browser cache it.

If you only send the styles necessary for the page they're looking at then you
lose all the benefits of caching. That's a far bigger problem than sending a
bunch of unused code.

------
royquilor
Hi everyone,

Thanks for the feedback and it has been insane. 3 big sites have accepted the
challenge to purge their css. Css is just a small part of the bigger picture.
Lots more topics to discuss, but i just focus on CSS.

I've dealt with a large site working with 4 developers. I have failed a
adapting a big site to be lean on their CSS, hence looking at different ways
of doing your styling.

------
cheshire137
I think they could spare a few more characters to set their body background-
color. I have a custom dark gray color set in my Firefox CSS so the new tab
page doesn't flash white when I open it at night, and the site shows that dark
gray, making their tables and text pretty hard to read.

------
oliv__
Ummm... Default or die: _15_ tools?

I thought I was just making a website here: you know HTML, CSS, and a dash of
Javascript.

...Guess not.

------
rhubarbquid
This site is pretty CPU heavy for something reminding us to respect our users'
resources...

------
phillipwills
This site crashes Firefox mobile after being open for a few minutes... Sad...

~~~
Washuu
I was thinking maybe it was just you. I tabbed back to the web site, Firefox
desktop immediately began to crash.

------
andrethegiant
I see many articles warning not to deeply nest selectors in sass. Doesn't
gzipping your resources mitigate that problem?

~~~
digestives
File size is a moot point with regards to long selectors - they are just a bad
idea. [1][2] I am a fan of BEM to keep things sane. [3]

[1] [http://csswizardry.com/2012/05/keep-your-css-selectors-
short...](http://csswizardry.com/2012/05/keep-your-css-selectors-short/) [2]
[https://benfrain.com/css-performance-revisited-selectors-
blo...](https://benfrain.com/css-performance-revisited-selectors-bloat-
expensive-styles/) [3] [http://getbem.com/](http://getbem.com/)

------
known
Brilliant analysis and presentation; Thank you;

~~~
xufi
Indeed it is. Brushing up on CSS here myself. Its amazing to see the different
sites that use more CSS like Wikipedia.

------
escape_goat
Are you really sure you need to steer this conversation towards dispute?
Because basically you're criticizing someone's experience of how they
gracefully integrated ajax _once upon a time_. Like, in the past. I don't want
people on HN to stop telling me what they did and how they handled situations,
in the past, because they keep seeing that whenever someone like Smudge does
that, someone like gkya really, really, urgently feel the need to tell them
how they did it all wrong.

~~~
gkya
> I don't want people on HN to stop telling me what they did ... because ...
> whenever ... Smudge does that, someone like gkya really, really, urgently
> feel the need to tell them how they did it all wrong.

i.e. they discuss, on a discussion forum?

> ... you're criticizing someone's experience of how they gracefully
> integrated ajax once upon a time. Like, in the past.

Yes, what's the problem with that?

He, as a developer, poses a way to do something, and I refute it as a person
on the other side of the wire, i.e. the user/hacker. Where else than _Hacker_
News is more apt for this sort of discussion?

~~~
escape_goat
My tone, previously, was not entirely useful, so firstly my apologies for
that, I could have said the same thing in a less aggrieved way.

As to your questions, well, I'd like you to consider my words in the context
of the distinction between discussion, debate, and dispute.

I believe I already adequately addressed what the "problem with that" was, but
I'll reiterate it more clearly.

Smudge was telling a story about a solution that he applied to a problem he
was facing at one time, what the benefits and drawbacks of it were, and how it
eventually led him to have respect for the value of React. He was sharing
_history_. It was _interesting_. It would be interesting to _discuss_ it if
one had questions about the technical aspects of the thing he had done in the
past, which he had shared with the audience in this forum, or rejected a
similar solution _at that time_ for reason one cared to describe.

Smudge was _not_ introducing or participating in a _debate_. He did not state
a proposal. He did not invite a counter-proposal. He did not advocate
anything. There is no debating that he did this thing. There is no debating
that he did it for the reasons that he described. There is no debating that he
came to the conclusions as a consequence of this experience that he shared
with us. The statements that you have made seem to show a pattern of
inattention to _what is actually being said_. You are _not_ debating with
anyone. Smudge did not intend to invite a debate, _and he should not have had
any reason to think differently_. Instead, your behaviour is _obnoxious, self-
involved, and anti-social_ , because it would tend to _discourage_ people who
_did not want_ to engage in debates with you from _sharing history with the
audience of the forum_.

What you were pursuing changed from _debate_ to _dispute_. Firstly, rather
than rebut points that had been made in the context in which they arose, you
_pursued disagreement_ beyond the bounds of the _actual context of the matter
under discussion_. To give an example, whether or not "browsers are very smart
these days" is not material to a discussion of how one developer implemented
ajax updates with graceful degradation once upon a time _when browsers were
not very smart_. You were _not_ debating with Smudge, most basically because
Smudge did not _want or try_ to have a debate with you. You were not debating
with Smudge because your statements were of little value in the context of
_what the topic of a debate would have been_ \--- which would be something
akin to 'decisions web developers made when faced with web developer problems
[once upon a time]' \--- and, by themselves, suggested that you were actually
_unfamiliar_ with this topic. Your words suggested a desire to turn a
_discussion_ into a _dispute_ about a topic that Smudge was _not discussing_ ,
and which was so tangentially related to _the actual topic at hand_ that I
would have found your need to dump your opinions upon this person as
argumentation offensive even had you not stretched them to the ridiculous
conclusion that front-end web development was a rent-seeking activity.

To add the final part to what I had said before: behaving like this will
discourage people from sharing their opinions and experiences. Just because
someone said something, it _does not mean_ that they or anyone else _cares_
that you have opinions about a related topic or that that person is inviting
you to criticize them. _Wait_ until the lines of an _actual debate_ have
actually formed before you attempt to engage in a debate with someone, and
_never, never_ crash someone's thread in order to insist that they must debate
you regarding a topic you yourself have brought to the table.

Extending the reply to your last statements: firstly, no, Smudge did not
propose a way to do something. You misread what he wrote. My apologies for the
bewilderment that my response must cause you if you genuinely, rather than
wilfully, misread what he wrote. However, he did not invite a debate, and your
behaviour was not appropriate. If you thought that it was, it would serve you
well to learn why it was not. Secondly, you did _not_ 'refute' what he said.
Your statements bore no relation to a refutation. "Everyone should use the
latest web browser" is no more a solution to a problem than "Everyone should
eat cake". Telling a person that they should use the 'default widgets' rather
than write a very thin javascript library because you don't like too much
javascript is confusing. What 'default widgets'? What do you mean by that...
jQuery widgets? HTML does not come with 'default widgets'. _Yes_ a lot of
websites are clogged with useless shit, and _yes_ you have a perfect right to
_not like this_. But you _can 't_ 'refute' the decisions that a web developer
makes "from the other side of the wire", and this is true of anything else or
any other similar situation. You can't 'refute' a judicial decision on the
basis of your own interpretation of written law. You have to learn about
_actual law_ first. You have to come to _his side of the wire_ first. You
could certainly refute mis-statement of _fact_ , if you knew it to be
incorrect, but you cannot refute a _decision_ without understanding the
context in which it was made.

~~~
gkya
If there's one thing that's off-topic in this whole thread for this
submission, that is this comment you posted, which is longer than the
4-comment thread that started with my initial reply to Smudge and you didn't
like. You call me obnoxious, self-involved and anti-social, offending me
personally. And you procede to tell me what I can or can not do, and guessing
my thoughts and mindset, and deciding for other people what would discourage
them from posting online. I will not respond to any other comment you may
make, as you seem to be a self-proclaimed judge of online correspondence,
which is not all that sane.

~~~
sillysaurus3
It's best to flag off-topic comments. Especially ones that make the
conversation personal.

~~~
gkya
The flag link is a sassy little thing, it sometimes shows up and sometimes
doesn't. In this case it didn't.

~~~
dang
It doesn't show up on direct replies to oneself. Same with downvote arrow. In
such cases the system automatically recuses you and you have to rely on your
fellow users to correct misbehavior, or in egregious cases email
hn@ycombinator.com so we can look into it.

------
evbogue
[http://gitmx.com/ev/reserva](http://gitmx.com/ev/reserva) is only 5.4k

~~~
dsego
h1 { color: #333; } is only 20 bytes

