You are here: Home / What do you need? / Help and documentation / Plone Info / Tips on how to make a Plone site faster

Tips on how to make a Plone site faster

by Darrell Kingsley last modified Mar 13, 2014 01:04 PM
by Rafael Oliveira - Point to common and easy ways to make a Plone site faster.

Purpose

This document's purpose is to point to common and easy ways to make a Plone site faster. It's not meant to be exhaustive nor include detailed instructions.

The "hard" part of making a Plone site faster is not mentioned here: use a proxy/cache in front of the Zope instance. This is a complex topic, which involves other pieces of software outside the Plone/Zope world, and is covered in other places.

Profiling and benchmarking

First you'll need to setup some tools for profiling and benchmarking. You need some way to tell whether your attempts to improve performance are working or not, and you need to know what is really consuming time.

ab

ab is an Apache tool that makes a number of HTTP requests to your site and measures the time consumed and the number of requests per second the web server can handle. The basic usage syntax:

ab -c 5 -n 100 http://127.0.0.1:8080/somesite

It means ab will make 100 requests, 5 at a time (i.e concurrently).

FireBug

Firebug is an add-on for Firefox, very useful for web development. It has a "Network" panel, which shows the size and the time to load of each resource requested when opening a page. It also shows the HTTP request and response headers (which is very useful when debugging caching issues).

ZopeProfiler and PTProfiler

Usage of ZopeProfiler and PTProfiler is well covered by this article by Mikko Ohtamaa.

There's also this blog entry by Bertrand Mathieu containing instructions on how to patch ZopeProfiler to avoid errors which occurs on recent versions of Zope and Plone. Without this patch it won't work at all.

The author also mentions Gprof2dot and xdot.py, two tools that allows visualizing the data produced by ZopeProfiler as a pretty formatted graph.

Install collective.remove.kss

Install collective.remove.kss add-on to remove KSS, which does all the Ajax stuff inside Plone. Beware this will remove some functionalities (check the add-on page for a list). Ajax operations are expensive, so it is often worthy to remove them.

Install archetypes.schematuning

Straight from archetypes.schematuning entry on PyPI:

This package speeds up Archetypes Schemas and is a patch for Products.Archetypes. It uses plone.memoize to cache Archetypes Schemas instead of factoring and modifying them every time its accessed.

Make images in skin layers cacheable by the browser

For each image residing inside a skin layer folder, add a correspondent .metadata file (i.e myimage.png.metadata) containing:

[default]
cache=HTTPCache

Use the CSS and JS registries

Do not add links to CSS and JS files directly on your page templates. Use the CSS and JS registries instead. These tools merge the resources, reducing the number of HTTP requests. And it handles caching as well.

Minimize number of requests and "404 not found" errors

Related to the previous topic, you should care to minimize the number of HTTP requests, because it's expensive in Zope. CSS and JS registries can be used to do just that.

From Profiling Plone and tuning add on product performance (by Mikko Ohtamaa):

Make sure that you don't get any HTTP Not Found 404 pages, since they are very expensive in Zope. You can log not found pages if you clear "NotFound" in error_log / "Ignored exception types".

You can use the Firebug's Network panel to find 404 errors and to see which resources are requested by the browser when opening a URL on your site.

Move processing from templates to view classes

From Profiling Plone and tuning add on product performance (by Mikko Ohtamaa):

Move template expression (python:, string: and traversing expressions) to BrowserView methods, since template expressions are run under RestrictedPython sandbox which comes with heavy execution penalty.

You can use PTProfiler to see which expressions are more time consuming.

Use plone.memoize

From Profiling Plone and tuning add on product performance (by Mikko Ohtamaa):

Check plone.memoize product which contain function decorators for caching the function value during subsequent function runs. This is easy way to solve the problem if a heavy function or view is called several times per request.

Use Zeo

It's often said that use a Zeo server is always a good idea, even if you have only one Zeo client. Read the chapter Scalability and ZEO of the Zope Book for more details.

Change Zope instance options and use multiple Zeo clients

This is the hardest part. There are plenty of articles and mailing lists messages discussing the optimal values for the following options.

In your buildout.cfg you can try to fiddle with these options for theplone.recipe.zope2instance recipe:

  • debug-mode: Set to off to improve speed.
  • zserver-threads: The default is 4.
  • zeo-client-cache-size: Example: 100MB.

You can consider using multiple Zeo clients and a load-balancer between those clients. You can even use multiple servers, containing one or more Zeo clients. The optimal value forzserver-threads value depends on the number of Zeo clients and Zeo clients per server -- besides the number of concurrent users you're planning to have etc.

For more details check Scalability and ZEO (chapter of the Zope Book). See On Zope, multiple cores, and the GIL for an example of issues to consider when doing this kind of optimization.