Optimizing Your Application
This is the central place for people to share tips and techniques for optimizing web-based applications and these suggestions are not solely limited to Symfony. The tips cover all layers of any web application, from the client's initial request to the final rendering of the page. This includes, but is not limited to, database and web server optimizations, file storage and distribution, caching, load balancing, benchmarking, frontend tweaking, and much more...
If you need to make your site perform better, this is the place for you.
"There's a lot of attention and many books devoted to optimizing performance [in the backend], so that's where most people spend time looking for improvements. In reality, for most web pages, less than 10-20% of the end user response time is spent getting the HTML document from the webserver to the browser. If you want to dramatically reduce the response times of your web pages, you have to focus on the other 80-90% of the end user experience [the frontend]."
-- Steven Souders, Chief Performance Yahoo!, in his book, High Performance Web Sites: Essential Knowledge for Frontend Engineers (O'Reilly)
Steve gives 14 tips (details can be found by buying the small, but invaluable, 150 page, book):
- Make fewer HTTP requests.
- Use a content delivery network.
- Add a far future Expires header to your components.
- Gzip your scripts and stylesheets.
- Put your stylesheets in the document HEAD using the LINK tag.
- Move scripts to the bottom of the page.
- Avoid CSS expressions.
- Reduce DNS lookups by using Keep-Alive and few domains.
- Find ways to avoid redirects.
- Make sure your scripts are included only once.
- Reconfigure or remove ETags.
- Make sure your Ajax requests follow the performance guidelines, especially having a far future Expires header.
You can download YSlow, a Firefox add-on, that scores a site on a scale of A to F on how well a page satisfies the rules listed above.
Caching is very important to improving the performance of your website, is multi-faceted, and can appear in many unexpected places. Thus, an entire section is devoted to this topic.
- Memcached - Free and open source. Used on many popular sites. Also see PHP's implementation of this. Propel 2.0 plans to support this and it looks like Doctrine will as well.
- The Definitive Guide to Symfony, Chapter 12: Caching.
- The Definitive Guide to Symfony, Chapter 18: Performance.
- Jobeet! Tutorial Day 22: Performance and Cache
- Increase realpath_cache_size (for example to 64K instead of the default, 16K). "realpath_cache_size determines the size of the realpath cache to be used by PHP. This value should be increased on systems where PHP opens many files, to reflect the quantity of the file operations performed."
- Increase realpath_cache_ttl (for example to 180 instead of the default, 120). "realpath_cache_ttl is the duration of time (in seconds) for which to cache realpath information for a given file or directory. For systems with rarely changing files, consider increasing the value.
- Code Caching
- APC is a free, open, and robust framework for caching and optimizing PHP intermediate code.
- eAccelerator "is a free open-source PHP accelerator, optimizer, and dynamic content cache. It increases the performance of PHP scripts by caching them in their compiled state, so that the overhead of compiling is almost completely eliminated. It also optimizes scripts to speed up their execution. eAccelerator typically reduces server load and increases the speed of your PHP code by 1-10 times."
- XCache "is a fast, stable PHP opcode cacher that has been tested and is now running on production servers under high load."
Note on opcode caching
The cached config files created by symfony can be quite large. Most opcode caching software has an option to not cache files larger than a certain size. e.g. by default APC default is 1M. Some cached config php files are larger than 1M and are therefore not cached, meaning a performance penalty on every request. To see the size of the files look for cache/<app>/<env>/config/*.php, where <app> and <env> are the application name e.g. 'backend' and env is the environment e.g. 'prod'
If the files are larger than the opcode default, increase the max size in the the config. e.g. in APC add
It has been said over and over by experienced web developers that, in the backend, the primary bottleneck is the database. This bottleneck supersedes any framework, language, web server, platform, or whatever. If you're site is slow, the database is the first place you should look.
Indexes can rapidly increase the speed of your queries (and they're easy to do). [More info]
Reads vs. writes. [More info]
Propel is the ORM distributed with Symfony 1.0. The community is yearning for Propel 2.0 but in the meantime, the beta release of Propel 1.3 is available and is purportedly significantly faster than the version bundled with Symfony 1.0). Have a look at the Propel 1.3 plugin. Note, Propel 1.3 is already included in symfony 1.2 and above and therefore does not require the sfPropel13Plugin plugin.
- Set comments to off in propel.ini
- Use Propel's hydrate method instead of holding entire record sets in memory
- output_handler = ob_gzhandler compress your php output for browsers that support it. Most useful for modem users.
Last known, YouTube and Wikipedia were using Lighttpd for fetching images.
Nginx is small and high-performance web server, used by WordPress.com and FastMail.fm.
- Perlbal - Free and open source. Used in production on several popular sites. Runs quite well in front of a pool of Apache servers.
File Storage and Distribution
- MogileFS - Free and open source. Used in production on several popular sites. Negates the need for RAID. MogileFS is an anagram for "OMG Files". Used in conjunction with Perlbal.sfMogileFSPlugin (beta)
- Building Scalable Web Sites: Building, Scaling, and Optimizing the Next Generation of Web Applications, by Cal Henderson, Flickr.com
- High Performance Web Sites, by Steve Souders, Yahoo!
- Use appropriate sorting routines (some are more memory-efficient than others) [more info]