UseSpritesForDocumentGraphics

Reduce page load times by combining DocumentGraphics into one sprite

I'm not particular skilled at this but here's an example: http://svidgen.com/sprites

Implementation Ideas

One way to do this would be to modify the %ICON{}% variable to output a modified img tag and add the appropriate css to the header. Some thing like:
%ICON{person}%
Would output
<img src='/pub/System/DocumentGraphics/placeholder.gif#person' alt='person' title='person' class='documentgraphicsprite person' />   
and add the following to the header
<style type='text/css'>
        . documentgraphicsprite {
      width: 16px;
      height: 16px;
      background-image: url('/pub/System/DocumentGraphics/sprites.gif');
   }
   . documentgraphicsprite.person {
      background-position: 0px 0px;
   }
</style>

There would need to be some sort of conf settings mapping icon names to pixel-based coordinates on the background image.

Another way to do this would be to make a new plugin that did much the same thing with a different command. Perhaps %SPRITE{}%

-- DrewStevenson - 24 Dec 2009

SpritePlugin

Went ahead and sketched out a rough SpritePlugin and attached it. Relies on FamFamFamContrib. Also included a screenshot

-- DrewStevenson - 24 Dec 2009

Thanks for the idea, I just learned something new. smile

However, the page you reference lists two drawbacks ("when not to use this technique"):
  • In the rare circumstance that your users need to be able to right-click on your image to save them [or] view their properties, this technique should not be used. -- Ok, this might not be that important
  • This technique can also cause issues printing the page, as background-images (like sprites) are ignored by default in most browsers for printing purposes. -- But this sounds like a serious problem; even if we would disable sprites for the print skin, this (a) doesn't mean that nobody tries to 'print' another skin and (b) does mean that all images would have to be transferred twice in that case (on second thought, (b) might not be a showstopper either)
btw, did you by chance do some benchmarks? Aren't these images cached on the client side anyway (cf. mod_expires or the like)?

-- MarkusUeberall - 24 Dec 2009

Hi Drew,

I too thought CSS sprites would be a great idea (after profiling my wiki with YSlow! and having it suggest this technique to me). And actually, the TinyMCE editor does this already for most of its toolbar graphics.

I had this brief chat with SvenDowideit about using CSS Sprites. As with the argument for compiling all our CSS and javascript files into one big blob, I get the impression that there is lower hanging fruit to optimise the end-user experience of foswiki (but then again, try telling that to users on PCs configured to clear their cache every time they close their browsers)...

The fact is the typical foswiki page view (and especially page edit) generates a gazillion HTTP requests (well, my site does anyway) and too often mod_expires is a band-aid that fails to hide this reality from my users.

So anyway, I'm very grateful for your experiments. If I were to pick this up and run with it, I would not generate the CSS dynamically in the header. It should be possible to compile all the CSS required for the entire doc graphics suite into one file in /pub. This will save on CPU time at the server and reduce bandwidth overhead for each page view.

On the other hand, unless you use Foswiki as a glorified CMS and you care greatly about first impression page view performance, when determining optimisation and usability priorities I will usually try to go for satisfying the regular contributors first, then the regular read-only users, and then casual/random users. Or to put this another way, I have found myself asking the question: "Are my efforts going to impact the users that I care about?". With CSS sprites, it's not a clear answer.

I will tell you something that I would find worthwhile though, probably more so than CSS sprites: I am reluctant to give my mod_expires apache config an aggressive expiry date too far into the future, because most of the CSS and JS in Foswiki is not versioned and the site is likely to look broken if people are hitting old files that have since been upgraded.

JQueryPlugin solves this by appending a ?version=x.y.z to the URL of any CSS/Javascript file that those plugins fetch. If we had a similar facility for the rest of Foswiki, I think more Foswiki installations would feel comfortable with setting their expires headers to a very distant future date.

-- PaulHarvey - 24 Dec 2009

These are good concerns raised up above.

Absolutely agree that the final version should generate a css file in pub and use that although it would be good to have it regenerate it based on some change in the settings or plugin page.

With regard to right-clicking Firefox gives the option to 'view background image'.

The print view scenario is a dicier one.

As too performance gains and the intended audience: My primary use cases both involve significantly more viewers than contributors With regard to the most performance sensitive one (http://systemstatus.umn.edu) I'm actually using the BrowserBoosterPlugin along with aggressive caching via Varnish to get stellar performance out of Foswiki as an app platform but one of my sys admins noticed that there were still a lot of requests required to load any of the pages and we weren't really comfortable with the far future expire dates either.

Maybe it'll just end up being a special use-case plugin. Although it might also make an interesting config option to have ICON switch to "sprite mode"

-- DrewStevenson - 24 Dec 2009

A small but useful enhancement would be for the ICON tag to detect whether it is running in the context of the print skin/cover or not. That way it could decide the style of img tag to generate (ie, using sprites or hardlinked images). If the behavios is cleary documented, and users are encouraged to use the "print" button in a skin (which should add the print cover/skin), one of the dawbacks of the techique is removed.

Of course, this implies that the images must be shipped in the sprite and standalone form, which may be a drawback too.

-- RafaelAlvarez - 29 Dec 2009

I'm working on using Image Magick's montage tool to generate the sprite and map info automatically. Thus if ImageMagick is present you get sprites and perhaps if ImageMagick isn't present or you're in genpdf or print skin you get regular old img tags. Thoughts?

-- DrewStevenson - 11 Jan 2010

this dovetails well with my intention to change the ICON macro in 1.1 to use =tmpl='s and css as per Tasks.Item2456 and AddFamFamFamContribToCore. That way, enabling this optimization would effectively become a change in the skin path. Very Cool.

I do wonder how much this improves things, given the articles i recal reading a while ago about the size of the browser's in-memory image cache - in that its limited to a small number of files, and a relatively small size - given that it stores the images in uncompressed form.

-- SvenDowideit - 12 Jan 2010

BasicForm edit

TopicClassification BrainStorming
TopicSummary Create plugin or modify core ICON macro to use css sprites to cut down on requests per page
InterestedParties DrewStevenson
I Attachment Action Size Date Who Comment
Screen_shot_2009-12-23_at_Dec_23_6.21.20_PM.pngpng Screen_shot_2009-12-23_at_Dec_23_6.21.20_PM.png manage 139 K 24 Dec 2009 - 00:22 DrewStevenson  
SpritePlugin.tgztgz SpritePlugin.tgz manage 9 K 24 Dec 2009 - 00:13 DrewStevenson Really rough sketch of a SpritePlugin
Topic revision: r8 - 12 Jan 2010, SvenDowideit
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy