DevEX - reference for building teams, processes, and platforms
The Need for Speed - SMX Sydney 2013
1. The Need for Speed
- How to make your site REALLY fast! -
http://gdig.de/sydney2
Sydney, April 2013
Bastian Grimm, Managing Partner - Grimm Digital - @basgr
2. About me
SEO Trainings, Seminars & Strategy Consulting
WordPress Security, Consulting & Development
@basgr
Berlin-based Full-Service Performance Marketing Agency
2
5. “We encourage you to start
looking at your site's speed - not
only to improve your ranking
in search engines, but also to
improve everyone's experience
on the Internet.”
- Amit Singhal & Matt Cutts, Google Search Quality Team
6. One (simple) goal only:
Make your site as fast as you can!
Can you get, what Amazon got?
1%+ in revenue for every
100 ms in speed.
Amazon study: http://gdig.de/amzn100
10. GWT Site Performance Info
This is really not so good…!
high load times = high bounce rate = loosing in SERP 1:1‘s
https://www.google.com/webmasters/tools/
12. RUM: Real User Measurement
<script>
_gaq.push(['_setAccount','UA-XXXX-X']);
_gaq.push(['_setSiteSpeedSampleRate', 100]);
_gaq.push(['_trackPageview']);
</script>
Google Analytics > Content > Site Speed
Collects all the data, 1% default sampling rate (customizable)!
I “heard” this Rum is
also fairly good…
Analytics Documentation: http://gdig.de/1q
15. Get rid of multiple CSS & JS files
8 JS + 4 CSS req. on a single page is a bad idea!
Move CSS to the top, JS to the Often times JS does change the
footer to un-block rendering! style, so always do CSS before JS!
Best case: 1 CSS + 1 JS file.
Real world: 1-2 CSS, 1 int. + 2-3 ext. JS
16. Do CSS Sprites
Combine multiple (small) images into one
big image to save on HTTP requests.
http://spriteme.org/
18. Tip: Balance parallelizable resources
Even modern browsers don‘t
allow 6+ connections per
hostname at the same time!
Using img1/img2/imgX.domain.com allows balancing
requests to and between multiple sub-domains
The result: A massive 6+ connections at a time.
http://www.browserscope.org/
20. Minify CSS & JS files
Minifying this (small) style-
sheet results in 63% savings!
For CSS, try:
http://www.phpied.com/cssmin-js/
http://developer.yahoo.com/yui/compressor/
For JS, go with:
http://www.crockford.com/javascript/jsmin.html
https://developers.google.com/closure/compiler
Removing unnecessary whitespaces, line-
breaks and comments to reduce file-size.
And: Makes it way harder for competitors to steal your code!
21. Enable GZIP compression
Verify by checking the response
headers, for “Content-Encoding“
to be set to “gzip“
On Apache, try “mod_deflate” which is straight forward:
AddOutputFilterByType DEFLATE text/html text/plain text/xml
Output compression does massively decrease
file-sizes and therefore speeds up rendering.
One of the ugliest sites ever: http://www.gzip.org/
22. Why would I do that?
Based on jQuery Version 1.9.1 …
Normal Minified GZIP‘ed Min. + GZIP‘ed
271 KB 90 KB 78 KB 32 KB
~88% savings in file size due to combining
minifying with compression.
22
23. Tip: Use Live HTTP Headers in Firefox
To easily check request and response objects as well as
their headers, try Live HTTP Headers or Fire Cookie.
https://addons.mozilla.org/en-US/firefox/addon/live-http-headers/
24. Use a cookie-less domain
Live HTTP headers reveals that no
cookies are set for gstatic.com
For static files, cookies are not required -
disable cookie handling all together.
http://www.ravelrumba.com/blog/static-cookieless-domain/
25. Tip: How to get rid of Cookies…
Straight forward: Don’t set them…!
Apache header manipulation using “mod_headers”:
RequestHeader unset Cookie
Stop cookies being passed back to the client :
Header unset Set-Cookie
Same goes for other components (like PHP, Java and the
like) – each does provide functionality to disable Cookies.
http://httpd.apache.org/docs/2.4/mod/mod_headers.html
27. Setup caching for static resources
Expires: Set the “Expires”-header to exactly
Fri, 07 Sept 2013 03:18:06 GMT one year ahead of the request date
Last-Modified: Set the “Last-Modified”-header to
Fri, 07 Sept 2012 03:18:06 GMT the date the file was last modified
Cache-Control: Set the “Cache-Control: max-age”-
max-age=3153600 header to “3153600” (1 year, again)
It’s important to specify one of Expires or Cache-Control max-age,
and one of Last-Modified or ETag, for all cacheable resources.
28. Some caching pitfalls…
<link rel="stylesheet" type="text/css"
href="/styles/83faf15055698ec77/my.css" media="screen" />
Use URL fingerprinting to force
refreshing of cached resources.
But don’t use parameters to indicate
versions – Squid et. al have issues ;)
<link rel="stylesheet" type="text/css"
href="/styles/my.css?v=83faf15055698ec77" media="screen" />
If you want to cache SSL contents,
Header append Cache-Control make sure to have the “Cache
"public, must-revalidate" control“-header to contain public.
30. Remove HTML comments
ANT can remove HTML
comments at build-time
using a ReplaceRegEx task
There is no need for HTML comments on a
live system, remove them during build-time.
Or try this one: http://code.google.com/p/htmlcompressor/
31. Move inline CSS / JS to external files
Make the HTML as small as possible. Move
out inline CSS and JS to make it cache-able.
32. Don’t scale images using width / height
The image dimensions are 220x93,
but onsite it’ll be shown as 100x42.
Small images = less file-size. Don’t scale down
images using attributes, provide small ones!
33. Tip: Make images even smaller!
Use tinyPNG to optimize
PNG files without loosing in
quality (up to 70% savings)
JPEGmini does the same for JPEG
files and will reduce your images
massively (up to 80% smaller)!
http://tinypng.org/ & http://www.jpegmini.com/
34. Try jQuery Lazy Load
<script src="jquery.js" type="text/javascript"></script>
<script src="jquery.lazyload.js" type="text/javascript"></script>
Embed jQuery + Lazy Load Plug-in
<img class="lazy" src="default.jpg" data-original="real-image.jpg"
width="640" height="480" alt="sometext" />
$("img.lazy").lazyload(); Provide default + real image,
also include dimensions.
Execute the loader…
http://www.appelsiini.net/projects/lazyload
35. Don’t use empty href- / src-attributes
IE makes a request to the directory in
which the page is located.
Safari & Chrome make a request to the
actual page itself.
Empty “href” & “src” attributes can make your
site slow – they’re requesting themselves.
36. Don’t use @import in CSS
<link rel="stylesheet" type="text/css" href="/styles/my.css" />
Always load CSS files
using link-rel HTML tags.
<style type="text/css">
@import "/styles/my.css";
@import url("/styles/my.css") screen;
</style>
Especially in external CSS, this
will make your mama cry!
Using CSS @import in external CSS makes it
impossible for browsers to download in parallel.
38. Off-load components into AJAX fragments
NO! Not this one…!
I know: You guys are SEOs… you want
ALL contents being crawl-able.
So, use with care… like for filters, etc.
AJAX = Asynchronous JavaScript And XML
Using AJAX fragments does not block page loading!
Credits: http://flic.kr/p/RGtz - AJAX Crawling: http://gdig.de/ajxcrwl
39. Some details about <script> …
<script src="script.js" [...] async="async"></script>
allows script to be downloaded in
background without blocking. Having
finished, rendering is blocked and
script will be executed.
Same - except it guarantees that
scripts execute in the order they were
specified within HTML mark-up.
<script src="script.js" [...] defer="defer"></script>
39
42. How about HeadJS?
The beauty: Only a single JS
needs to be loaded in <head>!
HeadJS does enable parallelizing JS file
downloads. Freaking awesome!
http://headjs.com/
44. Use the Slow Query Log
[mysqld] Pro tip: Make sure to use “log-
log-slow-queries = my-slow.log queries-not-using-indexes” option to
long_query_time = 5 find SELECTs without proper indices!
log-queries-not-using-indexes
# Run the Perl script: Get slow log parser to know how many
sudo ./mysql_slow_log_parser.pl times queries appear, they take to exec.
/var/log/my-slow.log > slow.out and which are the worst ones!
MySQL seems to be slow - but no idea why?
Enable “log-slow-queries” in my.cnf
Log parser download: http://gdig.de/slgparse
45. Get your queries right!
Pro tip: All “SELECT * FROM X”
Adding a proper index statements can be pre-pended with
would fix this! “EXPLAIN …” – use it!
EXPLAIN SELECT id, firstname, lastname FROM employee WHERE id=1;
+----------+------+---------------+------+---------+------+------+------------+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+----------+------+---------------+------+---------+------+------+------------+
| employee | ALL | NULL | NULL | NULL | NULL | 200 | where used |
+----------+------+---------------+------+---------+------+------+------------+
A huge amount of MySQL queries suffer from bad
coding. Make sure to setup & use indices properly!
http://dev.mysql.com/doc/refman/5.1/en/explain.html
46. Don’t do search using MySQL
Neither MATCH
AGAINST nor LIKE
queries are fast!
SELECT * FROM table WHERE
MATCH (field1, field2)
AGAINST ('query');
Searching in MySQL is a performance killer!
Consider switching to a real search server.
http://lucene.apache.org/solr/ & http://sphinxsearch.com/
47. Consider “simple” table optimizations
Do you really need “BIGINT”,
maybe “INT” is enough?
Sure, this string will ever have that
many characters – “VARCHAR(20)” Also required to keep indexes in
vs. “VARCHAR(255)”? memory by trimming the
overhead!
Consider carefully how to setup your database
tables. It makes a huge difference!
48. Prioritize statements properly
Use “INSERT DELAYED” to execute
INSERTs without blocking other stuff!
INSERT DELAYED INTO xyz
(bla, blubb) VALUES
('val1', 'val2'); You need this data REALLY fast?
“SELECT HIGH PRIORITY” helps!
SELECT HIGH_PRIORITY foo,
bar FROM XYZ;
Do you need some data faster than other?
Do you care about results of INSERT statements?
49. Make your server faster!
If you’re lazy: Use MySQLTuner to
get recommendations for
optimizing your my.cnf settings
There is a pretty good reason, MySQL comes with
different pre-configuration files - Use them!
https://github.com/rackerhacker/MySQLTuner-perl
50. Consider master- / slave-setups
read-only
write
replicate
MySQL replication is awesome – use different
servers for reading and writing data.
http://de.slideshare.net/osscube/mysql-performance-tuning-top-10-tips
52. Get reliable hosting
Reliable hosting is key – make sure to choose a
provider that fits your requirements.
A starting point: http://gdig.de/ushosts
53. If you’re on Apache…
Pro tip: “Small” stuff like
disabling .htaccess can really
improve performance!
Google does provide “mod_pagespeed” to
implement their best practices – give it a try!
https://developers.google.com/speed/pagespeed/mod
54. Or maybe: Consider replacing Apache…
“nginx” is ridiculously fast – especially when serving
static assets it’s probably the best you’ll find!
http://www.nginx.com/
55. And: Reverse-proxy incoming requests
All requests will be passed
through a proxy, no direct access
squid-cache.org to web-servers will be given.
Optimising Web Delivery
Get load off your web-server by setting up a
dedicated box in front using SQUID Cache.
http://www.squid-cache.org/
57. Use memcached sessions only!
memcached comes with a
php.ini settings custom PHP session handler -
put session data straight to
your servers RAM.
session.save_handler = memcached
session.save_path = "localhost:11211"
By default, PHP will store session information on your
servers HDDs – no good for high traffic sites!
http://php.net/manual/en/intro.memcached.php
58. Get a PHP accelerator
What you need to know:
PHP code will be complied for
each request during runtime.
By using an accelerator like APC you can cache
functions, objects and much more in memory.
Better: It does also cache compiled byte-code!
http://devzone.zend.com/1812/using-apc-with-php/
59. Try out PHP-FPM
Read the full article: http://interfacelab.com/nginx-php-fpm-apc-awesome/
FastCGI Process Manager for PHP
…is an alternative PHP FastCGI implementation with some additional
features useful for sites of any size, especially busier sites.
http://php-fpm.org/
67. Use Google’s CDN for popular libraries
Since a lot of site-owners are using
G-DCs, chances are, people have
those files cached already!
Google has the fastest CDN on the planet, make sure
you use their DCs to serve your files if possible!
https://developers.google.com/speed/libraries/
68. Off-load other stuff to a CDN
Latency is crucial – especially if you’re serving a global audience,
offloading statics to a CDN will give additional performance.
CDN Overview: http://gdig.de/cdns