Quest For Better Performance

Hi,

I’m Always interested for a better performance.

So far I did:

  • DB indexes

  • DB Schema caching

  • file caching for certain application parts

  • installed PHP APC extension

Client side effects:

  • One minimized CSS file.

I log the execution time for every request. The average is about 0.20s. With APC enables it’s around 0.18s. I suspected much more from the APC, but probably the most performance is as allways the DB queries.

I want to improve this more, but I can’t easily see the time per trace event. I’m using the YiiDebugToolbarRoute and it shows me the time between events like:

20:37:23.857964

20:37:23.874440

20:37:23.902791

etc.

But I have to calculate the elapsed time between items myself. 1 Is there a plugin or way to see this at once? Like:

0.002s

0.014s

0.003s

etc.

Second question: For the cache class I use: CFileCache. I also tried the CApcCache, but it seems to make no different at all (maybe a few milliseconds). It this expected too?

3th Sometimes I see an execution time of about 8 or 9 seconds, let say once in 300 requests. What could cause this and how can I track it down?

4th, any tips I can improve even more? Or is 0.18s not bad at all?

No one cares for a better performance ? ;)

In the meantime, I can see it’s not the DB queries that use most time. But all the plugins I’m using and of course the Yii framework itself. Like my mobiledetect, just a few milisec, but storing it in a session saves me some time.

So far, the most simple pages only use 0.03 sec now, I think it’s good enough so far. Loading all the images, css and js is using much more time compared to only the execution time.

Still, if someone has more information about this topic, feel free to reply.

You could run items like yslow for firefox and use speed test websites like Pingdom or Google speed test. These are good for seeing a waterfall of items / request on your pages.

look at your page sizes too. apparently the average is about 1.5mb as of 2014 i try to stay around 275 - 500kb if possible on low content pages with a couple of images.

This is important because most people will access sites via mobile with limited bandwidth. I read some study by amazon and they found that people will wait 1.5 -2 seconds (sales increased $1 billion after reducing it from 3-3.5 seconds over a year span to 1.5-2 seconds) for a page to load on a computer and up to 5 seconds on a cell phone before leaving the page and trying a different one.

You could look at minifying (removing unnecessary info attached to them) all of your images using online tools or implement a library that does it automatically upon upload of images. If you use programs like photoshop you don’t use file save as use save for web instead it will compress the image for you. Just be careful to get a happy medium because it could make the image look like crap. Also make sure you are using the right images types in the right places ( what is the difference in images and which ones to use).

If you just have a few you could do it manually using sites like Tiny Png.

You also stated you minified your css did you do your js as well? if not you should look into that.

You could also use CDN if you have enough images / files to make sense to do it (they are super simple to set up w/yii).

If you go through those sites at the top you can get a pretty good idea of what would need to happen. I was playing around with them on a site i was doing and I managed to get a 100/100 and it actually made a difference. I figured out how to do most of the items the sites look for if you have any questions on some of them just ask here. But a 100/100 doesn’t mean its best for your site as well i just wanted to see if it was possible.

but using apc and schema cacheing is a good start. Make sure you use far fetched expiry headers so your not reloading static items on every page request too.

just some food for thought…and i hope it helps

Thank you very much for your reply. A lot of things I use already, but also new stuff, thank you for that! I’m gonne look into that. I was using Google Speed test, but got about 60/100. So 100/100 is not impossible at all as a read you’ve manage to do this.

I have no expire tag at all, so that’s definitely one I have to realize. I see Google Speed mention this also a lot for my website.

Also the mobile is a very good point. That’s why I quit a responsive design and decided to build a complete specialized mobile version, with the help of MobileDetect and Yii themes.

So far, one question for you, by CDN you mean Content delivery network?

Yes, CDN is a content delivery network.

You can publish your assets to cookieless domains too by using a subdomain (mines called static.mysite.com).

Basically it just calls my application through the subdomain without cookies so they are not being sent with every request.

How it works it the subdomain static.mysite.com root is pointed to the root of my main appication mysite.com. static.mysite.com has cookies turned off. Since the request are being sent via my subdomain they are sent without cookies.

You can send assets this way by setting it in your main config file. I also call my images through the subdomain so they are sent without cookies too. I don’t use a cdn because i dont need too (I only have about 30-50 photos total) but i send some of my images via the subdomain too static.mysite.com/images/myimage.png.


'components'=>array(

 		'assetManager' => array(

        	'linkAssets' => true,

        	'baseUrl' => 'http://static.mysite.com/assets'

    	),

In your .htaccess use the following (caution rewrite is enabled at the top. if your not using it you can comment it out with # or remove it) your score should jump quite a bit. Also, if you are using version for your css and JS ie styles.css?v1.25 it will not add far fetched headers you would have to modify the code below and put some rewrites in

here is an article on it

Far fectched headers and versioning


#Use if on shared hosting and this not in the root folder.

RewriteBase /

RewriteEngine on

# if a directory or a file exists, use it directly

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

# otherwise forward it to index.php

RewriteRule . index.php

Header unset ETag

FileETag None

# ----------------------------------------------------------------------

# Expires headers (for better cache control)

# ----------------------------------------------------------------------

#

# These are pretty far-future expires headers

# They assume you control versioning with cachebusting query params like:

#   <script src="application.js?20100608">

# Additionally, consider that outdated proxies may miscache

#

#   www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/

#

# If you don`t use filenames to version, lower the css and js to something like "access plus 1 week"

#

<IfModule mod_expires.c>

ExpiresActive on

# Perhaps better to whitelist expires rules? Perhaps.

ExpiresDefault                      	"access plus 1 month"

# cache.appcache needs re-requests in FF 3.6 (thx Remy ~Introducing HTML5)

ExpiresByType text/cache-manifest "access plus 0 seconds"

# Your document html

ExpiresByType text/html "access plus 0 seconds"

# Data

ExpiresByType text/xml "access plus 0 seconds"

ExpiresByType application/xml "access plus 0 seconds"

ExpiresByType application/json "access plus 0 seconds"

# RSS feed

ExpiresByType application/rss+xml "access plus 1 hour"

# Favicon (cannot be renamed)

ExpiresByType image/x-icon "access plus 1 week"

# Media: images, video, audio

ExpiresByType image/gif "access plus 1 month"

ExpiresByType image/png "access plus 1 month"

ExpiresByType image/jpg "access plus 1 month"

ExpiresByType image/jpeg "access plus 1 month"

ExpiresByType video/ogg "access plus 1 month"

ExpiresByType audio/ogg "access plus 1 month"

ExpiresByType video/mp4 "access plus 1 month"

ExpiresByType video/webm  "access plus 1 month"

# HTC files  (css3pie)

ExpiresByType text/x-component "access plus 1 month"

# Webfonts

ExpiresByType font/truetype "access plus 1 month"

ExpiresByType font/opentype "access plus 1 month"

ExpiresByType application/x-font-woff "access plus 1 month"

ExpiresByType image/svg+xml "access plus 1 month"

ExpiresByType application/vnd.ms-fontobject "access plus 1 month"

# CSS and JavaScript

ExpiresByType text/css "access plus 1 year"

ExpiresByType application/javascript "access plus 1 year"

ExpiresByType text/javascript "access plus 1 year"

#The following line is enough for .js and .css

AddOutputFilter DEFLATE js css

#The following line also enables compression by file content type, for the following list of Content-Type:s

AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml

#The following lines are to avoid bugs with some browsers

BrowserMatch ^Mozilla/4 gzip-only-text/html

BrowserMatch ^Mozilla/4\.0[678] no-gzip

BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

</IfModule>

<IfModule mod_headers.c>

Header append Cache-Control "public"

</IfModule>

<ifModule mod_php4.c>

php_value zlib.output_compression off

</ifModule>

#enables gzip (HTML)  compression

<ifModule mod_gzip.c>

  mod_gzip_on Yes

  mod_gzip_dechunk Yes

  mod_gzip_item_include file .(html?|txt|css|js|php|pl)$

  mod_gzip_item_include handler ^cgi-script$

  mod_gzip_item_include mime ^text/.*

  mod_gzip_item_include mime ^application/x-javascript.*

  mod_gzip_item_exclude mime ^image/.*

  mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*

</ifModule>



Let me know if you tried the htaccess and what your score jumped too and your load stats before and after I’m kinda curious.

I don’t know how hard core you want to get but you could also clean your css up. if you use bootstrap good luck but here is how to profile your css so you can reduce time to paint the screen

Oprea CSS Profiler

As a side not to the Google speed test unless you use inline styling or dont have a lot of css / js you will not get a perfect score you will receive "Eliminate render-blocking JavaScript and CSS in above-the-fold content" though.

But the best thing i can say is do what’s best for your site.

As far as detecting mobile i use a simple php function (probably isn’t the best one but so far it works).

I just use a file under protected -> components -> customFunctions.php its declaired in my main config like


	'components'=>array(

 			'functions'=>array(

                	'class'=>'application.components.CustomFunctions',

            	),



one of my functions is


function isMobile() {

    	return preg_match("/(android|avantgo|blackberry|bolt|boost|cricket|docomo|fone|hiptop|mini|mobi|palm|phone|pie|tablet|up\.browser|up\.link|webos|wos)/i", $_SERVER["HTTP_USER_AGENT"]);

	}

and is called like


if (Yii::app()->functions->isMobile()==true){

    	//do something

    	}

I put all of my global functions i need for my app there and call them like above.

any other persons input would be awesome so we can know the best current way too to these things.

I found a very nice MySQL command recently that I’ve never heard of before. Apologies if it’s common knowledge but its use has sped up my databases no end.

Say you want to optimise "table1" then type:


SELECT * FROM table1 WHERE PROCEDURE ANALYSE(10, 8192);

This will give you a lisating of what MySQL thinks are the optimal datatypes and their sizes for each of your columns.

You can find more info if you Google "PROCEDURE ANALYSE" on Google.

Ive never used that personally, ill defiantly look into it. Thanks for that. also you could leverage the full capabilities of cache by using something like this in your controller to cache the whole page (server side). This will cache your whole page and your queries. So Yii has some pretty nice caching features that is just the simplest of them. I’d definitely look into them.


public function filters()

{

	return array(

	'accessControl', // perform access control for CRUD operations

	'postOnly + delete', // we only allow deletion via POST request

	array('COutputCache + view, index',

  	'duration'=>100,

  	'varyByParam'=>array('id'),

	),

	);

}

Wow, this topic is really getting me somewhere. I found a lot of resource on the topics you suggest. Quick reply:

  • the static subdomain is a simple but smart solution. I’ve seen it a lot in sites code, but never got the clue why it was used. It save a lot of cookie data.

  • The expire header is one thing I really need to apply. It’s also Google Speed nr1 suggestion when I test my site. First I will apply it only to image/jpg and when all my css en js are set up with a version param (?v=1.26) I can use it for other files as well.

  • PROCEDURE ANALYSE, cool command. I only knew the EXPLAIN command to optimize indexes and so.

At the moment I’m very busy building some features on the website. When this is done I will apply the expire mod and static subdomain. I don’t want to mess things up by rushing is and launch it on a quit time at night. So I will come back on this topic in a while.

For the record, the Google PageSpeed test score is now: 55/100 (mobile) 68/100(desktop). And biggest downside according to Google is the lack of expire headers indeed.

update: I applied an expire header of a few weeks only to jpeg images and this makes a PageSpeed score of: 62/100(mobile) and 78/100 (desktop).

Check out how to profile your code using XDebug: http://www.yiiframework.com/wiki/487/profiling-using-xdebug/.