tags:

views:

56

answers:

2

I would like to have user customizable look and feel options on a website. I envision an interface for selecting background and text colors, images, fonts, etc.. I'm just not sure what the best way to store and use the information is. I plan on storing all options in a database table tied to the user.

Is there a good way to dynamically generate css for each user? Is it better to generate the css as they make changes and just store it, or to regenerate it for each page view? Are there established patterns for doing this kind of thing?

+2  A: 

Separate out the parts of the CSS that are customisable from the parts that are static. That way you can still serve most of the CSS as you normally would.

Dynamically generate the CSS that is customisable. Don't try to do any optimisation or fancy caching unless you observe there's a performance problem.

The only potential performance problem is that the browser can't cache the customisable CSS. However, you probably don't want the browser to cache it anyway as that could mean that the user's colour scheme doesn't immediately update when they edit it.

If you do have a performance problem I wouldn't worry about ETags. ETags are designed to save the browser from re-downloading a component that it already has, but the customisable portion of the CSS is likely to be very small.

In case of a performance problem, consider inlining the customisable CSS directly into the HTML page. That will save an extra HTTP request. However, don't do this unless you are sure there is a need.

ctford
"ETags are designed to save the browser from re-downloading a component" - but ETag may save server resources spend on regenerating CSS content. Usually ETag may be calculated almost instantly.
Roman
Time spent generating the CSS will be negligable. Besides, how are you going to calculate the ETag if you don't regenerate the CSS?
ctford
As I have written, possible solution is to maintain user styles (options) version, which must be incremented every time user changes some option (business logic responsibility). This version may be used as ETag and for adding as version parameter to CSS link `?v=version` to ensure new version download after changes.
Roman
Ah, I understand now. I personally doubt that the performance improvement of not having to regenerate CSS would justify the complication of implementing ETags, but it depends on the exact requirements of the questioner.
ctford
+1  A: 

First of all, use appropriate caching headers for generated CSS and also use ETag header to re-validate CSS source when client asks for it. You must implement some fast ETag calculation algorithm, for example increment version field each time users changes some setting and return its value as ETag. In this scenario you may choose not to "generate the css as they make changes and just store it" but "regenerate it for each page view", because actually CSS will be stored in user agent cache and even when user presses F5 ETag will be used to ensure that CSS on client side is still valid.

Of course, CSS must be returned by some http handler (usercss.ashx or something like this). When including link to this CSS into HTML page, make sure to add some parameter to work around cached content issues, for example `

From my own experience I'd recommend you to use handler to serve user CSS as separate resource and do not embed it into HTML page each time it is generated, because in last case you must either recalculate CSS every time page is generated or somehow cache it on the server, both cases are rather bad ideas. Besides, this CSS may be rather large, there is no reason to download it on every request.

Roman
Can you explain why having to regenerate the CSS is such a bad idea? I don't see that it would be any more resource-intensive than generating the HTML. The CSS that needs to be regenerated would be very small - it need not include all the CSS that does not depend on user-preferences.
ctford
Generally I have nothing against CSS regeneration, but if there is rather simple solution that allows us to not regenerate and pass to client that piece of data, why not too use it? I agree with you that in described scenario CSS regeneration may be good (even best) approach because it is easier to implement that my Browser cache / ETag approach. Everyone can be wrong and me too :)
Roman
I suppose it depends on the exact situation. Thanks for helping me look at the problem from a different perspective.
ctford