Perceived Performance


When it comes to performance, the most frustrating thing can be that measuring performance in the backend doesn't necessarily translate to the user experiencing any of that gain. What we really care about, more than anything, is the user experiencing a faster, more responsive plone site.  A lot of this is pulled from the YSlow/Google PageSpeed tips but below is a good appetizer of things that really help Plone setups, as well as other delicious tips.

 

Caching

Read all about it. And no, I'm not talking about page caches or any of that internal mumbo jumbo. I'm talking about doing as much as you can to make sure that browser never ever requests that page again, unless it absolutely has too. The user experience here is directly translated to smoothness of transition between pages. 

 

Serve static content from a static web server: Having apache or nginx or some other static web server serve up all your js, css, and images will take a LOT of pressure off of Plone to deliver content. Static servers will...

 

An example of what to put in httpd.conf to serve images locally (which just so happens to gracefully degrade): 

   # serve anything from the folder "...htdocs/my_images" locally

   RewriteCond %{REQUEST_URI}  .*my_images.*

   RewriteRule ^/(.*)portal_skins/my_images/(.*)  /my_images/$2 [L]

 
The interesting thing here that happens as well is that it forces you to explicitly set origination of images. This is super important mainly because you do not want to trigger acquisition on display muck. Not only is it more expensive, but if you have set up a cache in front like varnish and you rely on acquisition, varnish is storing that image or whatever every time its accessed at a different url. So if all of your pages have '<img src="loading.gif"/>', then every call to this template from a different url will create a new entry in the browser cache, the page cache, the space time continuem, etc...
 

Redo your Web Interfaces: There a gagillions of studies out there showing that users really have no clue how long it takes for an interface to load, they just know how long it takes to get what they need to done.  For example, look at amazon: their page load time is attrocious, but I bet you in 30 seconds I can find and purchase the entire season of Gilmore Girls. Learn from that! REALLY sit down and ask yourself if your interface makes it easy for your users to get their task done fast. If you do this right, not only will it seem faster, but your users will scream with joy that you made their life easier, even if technically not a single page loads faster.

 

Load As Much As Possible Up Front: Do you have multiple pages to your form requiring submits between each section? Shame on you! Don't divide things out - generate once and use javascript to show and hide certain sections. It's cheaper to generate all at once because the performance hit for page generation in a sanely coded app is in the base template itself! global_defines.pt, for example, is a big pooper here.

 

Use Ajax: Yeah I said it. Get some. It's awesome. If you don't need 508 compliance, just go nuts. Even if you do, graceful javascript degradation techniques are easy to find and follow (hint: do all your dev with javascript disabled FIRST, then convert over). When you use ajax, you're users get a more seamless experience, you are generally talking to python scripts which are fast, and you can bypass a shit-ton of security overhead if you so choose. You don't have to be extreme and get all facebook on it, but really think about where it makes sense.

 

Put Javascript at the Bottom: I know some people won't like this, but it really helps. It's easy to customize the main_template.pt and most all that JS to the bottom, right before the closing body tag. It also forces you to code with good, event driven javascript code. i.e. Are you putting still onclicks in your html like it's 1999? This will help you break that habit once and for all. 

 

Embrace CSS Sprites: If you have lots of icons, this will help you a lot. Instead of servicing 18 requests for 18 images, combine them into one. Once the browser has already fetched that image, it won't get it again so not only will you have less requests, but with proper compression you are likely to be sending way less kb's over the wire in the end. Good candidates for sprites are any icons, especially for archetypes, tags and logos, personal bar items, etc...

 

Deffered Content Loading: Another thing that Amazon does that is brilliant and hackey is derferred content loading. Check it out by viewing and item and quickly scrolling to the bottom. You'll see that it doesn't load content below the page fold until it actually scrolls into view. Brilliant. Hackey. It's Brill-ackey, its easy to implement, and it will save rendering of unnecessary, potentially expensive elements. TODO: Example here.

 

Compress, Gzip and Deflate Everything: In the default httpd install there is a line that says " # Don't compress images, java scripts and style sheets". Ignore that. Comment it out. If it breaks stuff work backwords from there. I'm not sure about other servers, what the defaults are.

 

* Technically it can get two requests at once per host, but that really only emphasizes the point. Also, I believe chrome doesn't abide by this 2 requests rule but I can't remember where I read that.