3. Harder, Better, Faster, Stronger
• Make Fewer HTTP Requests
• Use a Content Delivery
Network
• Add an Expires Header
• Gzip Components
• Put Stylesheets at the Top
• Put Scripts at the Bottom
• Avoid CSS Expressions
• Make JavaScript and CSS
External
• Reduce DNS Lookups
• Minify JavaScript
• Avoid Redirects
• Remove Duplicate Scripts
• Configure ETags
• Make AJAX Cacheable
Steven Souder’s 14 Rules
http://stevesouders.com/hpws/rules.php
5. Harder, Better, Faster, Stronger
• CSS Sprites
• http://csssprites.com/
• http://css-sprit.es/
• Mind size limits for mobile browser caching
• Combine scripts and stylesheets
• If not using Etags turn ‘em off in httpd.conf:
Header unset Etag
FileETag None
Reducing HTTP Requests
6. Harder, Better, Faster, Stronger
Server side
•Distributed: Memcached
•Opcode caching: Xcache, APC
Client side
•Cache headers
Caching
7. Harder, Better, Faster, Stronger
Javascript & CSS:
• remove extra chars, comments & whitespace
• reduce size for first page load
There are many online compressors:
• www.cssdrive.com
There are also local compressors:
• YUI compressor
• LESS/SASS tools (SimpLESS, WinLESS, etc.) will minify
resultant CSS.
Minification
8. Harder, Better, Faster, Stronger
1) Install if not installed
2) Enable in apache if not enabled already
3) Configure mod_deflate in apache:
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
application/x-javascript
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4.[0678] no-gzip
BrowserMatch bMSIEs7 !no-gzip !gzip-only-text/html
BrowserMatch bOpera !no-gzip
Header append Vary User-Agent
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml
• Or configure mod_gzip in the mod_gzip.conf
GZIP
9. Harder, Better, Faster, Stronger
# phase 1: (reqheader, uri, file, handler)
# ========================================
# NO: special broken browsers which request for gzipped content
# but then aren't able to handle it correctly
mod_gzip_item_exclude reqheader "User-agent: Mozilla/4.0[678]“
#YES: HTML & PHP
mod_gzip_item_include file .html$
mod_gzip_item_include file .php$
# NO: include files / JavaScript & CSS (due to Netscape4 bugs)
#mod_gzip_item_exclude file .js$
#mod_gzip_item_exclude file .css$
# YES: CGI scripts
mod_gzip_item_include file .pl$
mod_gzip_item_include handler ^cgi-script$
# phase 2: (mime, rspheader)
# YES: normal HTML files, normal text files, Apache directory listings
#mod_gzip_item_include mime ^text/html$
#mod_gzip_item_include mime ^text/plain$
mod_gzip_item_include mime ^httpd/unix-directory$
# YES: include files / JavaScript & MIME text
mod_gzip_item_include mime ^application/x-javascript
mod_gzip_item_include mime ^text/
# NO: images (GIF etc., will rarely ever save anything)
mod_gzip_item_exclude mime ^image/
10. Harder, Better, Faster, Stronger
Control what you cache and for how long.
1) Enable in apache:
LoadModule expires_module /path_to/modules/mod_expires.so
2) Figure out how long different content types can last until stale
3) Configure in .htaccess:
(next page)
4) Add parameters to some of your images and other static content to allow you to expire them
by image name.
i.e.
Change your reference to heroshot.jpg to heroshot.jpg?123
Now when you update that image you can change it to heroshot.jpg?124
A Browser will recognize this as a new image.
Expires Headers
11. Harder, Better, Faster, Stronger
EXAMPLE:
# Expires Headers
ExpiresActive on
ExpiresDefault "access plus 5 minutes"
ExpiresByType text/html "now"
ExpiresByType image/jpg "access plus 3 days"
ExpiresByType image/gif "access plus 30 days"
ExpiresByType image/png "access plus 30 days"
ExpiresByType image/x-icon "access plus 30 days"
ExpiresByType image/jpeg "access plus 30 days"
ExpiresByType text/css "access plus 30 days"
ExpiresByType text/javascript "access plus 30 days"
ExpiresByType text/js "access plus 30 days"
ExpiresByType application/x-javascript "access plus 30 days"
ExpiresByType application/javascript "access plus 30 days"
Expires Headers
12. Harder, Better, Faster, Stronger
• Using a CDN vs. Reduce DNS lookups
– DNS lookups are cached at the client (or their ISP) but first load time
can take time
– Parallel loading of content can occur, however, if you use a CDN
– Therefore balance is key: parallel loading of a very large javascript file
on a first time visit can be worth the extra 30+ ms for the DNS lookup
• CSS at top – allows for progressive rendering (i.e. not having
to load and THEN redraw page elements)
• JS at bottom – allows for rendering to continue before JS
blocks it, also JS will block any parallel image downloading
Misc
13. Harder, Better, Faster, Stronger
• David Engel
• davidengel.dev@gmail.com
• http://winnipegphp.com
• http://www.meetup.com/Winnipeg-PHP/
• http://www.linkedin.com/groups/PHP-
Winnipeg-3874131
Closing