Caching of stylesheets

Discussion corner for Developers of Serendipity.
Post Reply
Cenic
Regular
Posts: 20
Joined: Wed Jul 16, 2008 11:09 am

Caching of stylesheets

Post by Cenic »

Hi,

following a discussion concerning traffic usage in the german corner of the forum I looked into the way serendipity delivers CSS stylesheets. Currently the stylesheet has an Expires header which allows the browser to cache the stylesheet for 1 hour. After that period the browser will request the stylesheet again and the backend will transmit the whole stylesheet again.

I tried to find a way that the stylesheet could be delivered with an ETag header that would allow the server to answer successive requests with an 304 Not Modified saving bandwidth and time to parse the stylesheet again.

The change is almost working and I could supply a patch. Obviously the 304 response should not have a response body to really save the bandwidth. Looking at serendipity.css.php it seemed obvious: the file contents of the stylesheet is copied to a variable $out, serendipity_plugin_api::hook_event() is called for $css_hook and then $out is printed.

But is seems some plugins (I can confirm nl2br and karma) do not use the hook to append their styles to the supplied variable but instead simply print it. That obviously makes it impossible to intercept the output and suppress it when sending the 304. Is that the correct way to generate CSS output by plugins or has it simply been overlooked? Am I missing something obvious?

Regards,
Stefan
If Java had true garbage collection, most programs would delete themselves upon execution. (Robert Sewell)
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Re: Caching of stylesheets

Post by garvinhicking »

Hi!

I think it might be required to patch serendipity.css.php for that, right? That should make it possible to use ob_start() and ob_get_contents() to properly capture also the output made by plugins using echo...?

Regards,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
Cenic
Regular
Posts: 20
Joined: Wed Jul 16, 2008 11:09 am

Re: Caching of stylesheets

Post by Cenic »

Hi Garvin,

yes, this involves changing serendipity.css.php. I will look into using ob_get_content() for it.

Although I would say that the way the hook mechanism is used in serendipity.css.php suggests that plugins should alao add their styles to the parameter instead of messing directly with the output. This would also allow changing the styles from within a plugin (like minifying it).

Thanks,
Stefan
If Java had true garbage collection, most programs would delete themselves upon execution. (Robert Sewell)
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Re: Caching of stylesheets

Post by garvinhicking »

Hi!

If you maybe have the time to patch the current plugins that use the 'css' hook and only use echo instead of using the eventData, that would also be great? :-))

Regards,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
Manko10
Regular
Posts: 50
Joined: Sun Dec 26, 2010 4:58 pm

Re: Caching of stylesheets

Post by Manko10 »

I wouldn't use ETag if it is not absolutely necessary. This caching mechanism is more or less defective by design, produces unnecessary HTTP requests and doesn't work well with load balancing.
Normally you should go well with an Expires header set to a date fare in the future (for style sheets at least on or two weeks, 1 hour is definitely ways too low) and a Last-Modified header.
Cenic
Regular
Posts: 20
Joined: Wed Jul 16, 2008 11:09 am

Re: Caching of stylesheets

Post by Cenic »

Hi,

in this case I believe ETag would be the better and simpler way to do it.

ETag is defective the way Apache has implemented it by default. Out of the Box Apache uses the inode of the file to calculate the ETag. This of course leads almost always to different ETags when the same file is served by different hosts.

I started to think about using Last-Modified. I wanted to take the maximum date of all included style sheets. But since plugins can add output to the style sheet there is no easy way to find out if either a new plugin or a changed configuration has caused a change that needs to be reflected in the header. For ETag on the other hand I would simply take the whole output including the plugin styles and calculate MD5 of it. Same MD5 hash means same CSS. In this case serendipity.css.php could simply send the 304 Not Modified and not send any content. Any change to a plugin or configuration parameter that leads to a different style sheet leads to a different hash and you can send the changed styles right away.

This doesn't influence the caching due to an Expires header at all. It simply avoids another GET with a full style sheet after the time has expired. If one hour is to long or too short is another discussion. I believe it has been set to a lower value because otherwise people start to complain that the site looks broken after they install a plugin (because the browser uses an old copy for too long missing the plugin CSS).

Regards,
Stefan
If Java had true garbage collection, most programs would delete themselves upon execution. (Robert Sewell)
Manko10
Regular
Posts: 50
Joined: Sun Dec 26, 2010 4:58 pm

Re: Caching of stylesheets

Post by Manko10 »

If you change your configuration or installed plugins on a daily basis, you should use ETag, indeed. But normally style sheets shouldn't change too often, therefore ETag headers generate a huge overhead due to lots of useless HTTP requests. With a far future Expires, the browser doesn't issue any requests at all. And if a style sheet changes, just add a different token (e.g. the MD5 sum) to the the URL and the browser will immediately catch the new version.
Post Reply