views:

118

answers:

3

Hi guys,

I'm writing a webapp using Zend framework and a homebrew widget system. Every widget has a controller and can choose to render one of many views if it chooses. This really helps us modularize and reconfigure and reuse the widgets anywhere on the site.

The Problem is that the views of each widget contain their own JS and CSS code, which leads to very messy HTML code when the whole page is put together. You get pockets of style and script tags everywhere. This is bad for a lot of different reasons as I'm sure you know, but it has a profound effect on our SEO as well.

Several solutions that I've been able to come up with:

  1. Separate the CSS and JS of every view of every widget into its own file - this has serious drawbacks for load times (many more resources have to be loaded separately) and it makes coding very difficult as now you have to have 3-4 files open just to edit a widget.

  2. combine the all the widget CSS into a single file (same with JS) - would also lead to a massive load when someone enters the site, mixes up the CSS and the JS for all widgets so it's harder to keep track of them, and other problems that I'm sure you can think of.

  3. Create a system that uses method 1 (separate CSS and JS for every widget), when delivering the page, stitches all CSS and JS together. This obviously needs more processing time and of course the creation of such a system, etc.

My Question is what you guys think of these solutions or if there are pre-existing solutions that you know of (or any tech that might help) solve this problem. I really appreciate all of your thoughts and comments!!

Thanks guys,

Ali

+2  A: 

With method 2, you'll be able to take advantage of browser caching. If appropriate, if the site has a "front door" entry page with nav etc. and no need of the widget library, you can pre-load the CSS and JS for the other pages after the landing page loads.

If you run your JS through something like YUICompressor and then make sure the server gzips JS and CSS files, you're really not talking about that much stuff unless you're code is really flabby. If you leverage a library that's hosted at a reliable site like Google's API repository, then you can probably keep your own code smaller. (I don't know anything about Zend, so that may or may not be relevant.)

Pointy
A: 

Not sure if this is possible in PHP, but if you are able to defer the transfer of the page until the page has been processed;

  • have each widget register its inclusion on the page using some static method
  • place a hook in the rendering pipeline that reads and concatenates all the needed resources for the included widgets
  • modify the response to include the resources
  • send the response to the client
Sean Kinsey
+1  A: 

I would definitely go for the third method. You get the flexibility of separation described in the first method, but you gain the ability to finetune the performance of your application (as pointed out by Pointy ..).

All you need is some central registry system (a class) which you use to keep track of what stylesheets need to be loaded.

Styles::add_sheet('widget_1.css');

In addition, you could add a trigger (a method) to this class so that the code which handles the caching can track if the concatenated stylesheet needs to be rebuild.

if (Styles::cache_needs_update()) {
  // rebuild (concatenate) stylesheet and save in cache
}

To go even further, one could also concatenate stylesheets by module or some other kind of grouping criterium. When there's a lot of stylesheets (or js files) these concatenated groups of stylesheets can then be cached separately.

The above code samples would become something like

Styles::add_sheet('widget_1.css','group_name');

if (Styles::cache_needs_update('group_name')) {
  // rebuild (concatenate) stylesheet for this 'group_name' and save in cache
}
zilverdistel