Search site

Add to Google

Send a comment back

If you are not a registered user, your comment will be moderated and may be deleted subsequently by the author if it is deemed to contain inappropriate materials. All embedded URLs will automatically be turned into anchors, so there is no need to wrap them in HTML tags

by:Guest User
Your Name:
Your URL/Blog
(to link back to your site):
Ajax calls are so slow on Rails 2.3, but only in production back

Ajax-icon

It has been a long time since I write, and it has been a long time since there was anything worthwhile to write, but today I encountered such a bizarre situation that I thought must be worth chronicleing. I am one of those ancient dinosaurs who has seen a lot and has fixed a lot, so usually a technical problem does not take me too long to find the answer to. This is why this strange phenomenon today must be written down, before I forget how I arrived at the resolution.

I have been working on this little Rails project for the last few months, and managed to get it to a stage where I felt ready to deploy to the real server. In development, I have been using WEBrick running on my laptop, and the performance has been pretty fantastic. The site has been very responsive and page and AJAX rendering have both been exemplary. So I expected it to fly once deployed on the production server. Alas, to my astonishment, certain parts took at least ten times longer to render, up to the point that I had to add a spinning image to show that it was still doing something. After about 30 seconds, both IE and Firefox managed to come back with the rendered contents, whereas Chrome simply gave up altogether and returned blank. I did all the possible investigations, like profiling the calls in Firebug, like streamlining the calls, by Googling for various but logical phrases such as "ajax call slow", or "partial rendering slow" etc. The thing about Google is it can get you pretty accurate information, but only if you know what to ask for. All to no avail. In any case, after all the initial fact findings, here are the facts:

  • the call is slow to render for all browsers, not any brand in particular (although Chrome failed to render at all due to time out)
  • the call is slow only for Ajax calls, meaning whole page refreshes are achieved at 'normal' speed
  • the call is slow only on Apache, not on WEBrick
  • according to the log file on the server side, the call finishes even faster when on Apache (which is what you'd expect), and yet, all browsers seem to languish in some no man's land for a good multiples of seconds before finally showing the contents
  • the contents are identical in each case, only the environments are different (development for WEBrick and production for Apache)
  • caching is switched on for servers in both environments
OK, armed with the above information, maybe someone will jump out and say 'ah ha, I know what the problem is!'. But for me, I was left scratching my head for the whole morning. The code is the same, the outputs in the logs look similar enough to discount any difference which may be credited to the performance discrepancy. We are talking about a factor of ten here!

I followed a number of trails, but all led to nowhere. After a number of hours, I decided to focus on the browsers, which all seem to exhibit similar behaviour: they all seem to choke while swallowing the payload. But why only in production? The same payload, albeit rather large, were rendered with ease in development. So, I got Firebug to dump out for me the request and response headers between the browser and the server, and here they are:

WEBrick request:

Host    localhost:3000
User-Agent    Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12 (.NET CLR 3.5.30729)
Accept    text/javascript, text/html, application/xml, text/xml, */*
Accept-Language    en-us,en;q=0.5
Accept-Encoding    gzip,deflate
Accept-Charset    ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive    115
Connection    keep-alive
X-Requested-With    XMLHttpRequest
X-Prototype-Version    1.6.0.3
Content-Type    application/x-www-form-urlencoded; charset=UTF-8
Referer    http://localhost:3000/forms/1/edit
Content-Length    71
Cookie    *********************; path=/; HttpOnly


WEBrick response:

Etag    "575561dea8cefa6c05062352e0531b74"
Connection    Keep-Alive
Content-Type    text/html; charset=utf-8
Date    Fri, 03 Dec 2010 14:20:50 GMT
Server    WEBrick/1.3.1 (Ruby/1.8.7/2010-01-10)
X-Runtime    48
Content-Length    121020
Cache-Control    private, max-age=0, must-revalidate
Set-Cookie   ********************; path=/; HttpOnly


Apache request:

Host    www.ok2life.com
User-Agent    Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12 (.NET CLR 3.5.30729)
Accept    text/javascript, text/html, application/xml, text/xml, */*
Accept-Language    en-us,en;q=0.5
Accept-Encoding    gzip,deflate
Accept-Charset    ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive    115
Connection    keep-alive
X-Requested-With    XMLHttpRequest
X-Prototype-Version    1.6.0.3
Content-Type    application/x-www-form-urlencoded; charset=UTF-8
Referer    http://www.ok2life.com/forms/1/edit
Content-Length    67
Cookie    *******************


Apache response:

Date    Fri, 03 Dec 2010 14:22:59 GMT
Server    Apache
Etag    "8ad228384f45c2f104da1442e5999941"
X-Runtime    134
Content-Length    20876
Set-Cookie    **********************; path=/; HttpOnly
Cache-Control    private, max-age=0, must-revalidate
Vary    Accept-Encoding
Content-Encoding    gzip
Keep-Alive    timeout=15, max=98
Connection    Keep-Alive
Content-Type    text/html; charset=utf-8



And there the difference jumps out at me (in red). The requests are simliar in that they contain the same header attributes. However, the response from Apache contains an extra header, namely Content-Encoding. It essentially indicates that Apache compresses the response before sending it back to the browser. This accounts for the fact that the response is only 20Kb long, compared to the WEBrick response, which comes in at 120Kb. A massive 1:6 compression ratio! After all, the browser request clearly indicates that it supports compressed responses in the Accept-Encoding header. And credit to both IE and Firefox, which manage to uncompress the returned data and render them, after stuttering a bit. And there lies my answer. I went into Apache's mod-enabled directory and switched off the compression of html contents:

<IfModule mod_deflate.c>
# AddOutputFilterByType DEFLATE text/html text/plain text/xml
# AddOutputFilterByType DEFLATE text/css
# AddOutputFilterByType DEFLATE application/x-javascript application/javascript application/ecmascript
AddOutputFilterByType DEFLATE application/rss+xml
</IfModule>

and hey presto, the problem disappears. Apache returns the data uncompressed and the browser is happy, rendering it faster than ever, but at the expense of bandwidth, alas.

It seems there is a discussion here, which indicates maybe Ajax contents should carry a different mime type so that they do not get compressed by the server. Also, I am not sure why browsers take so long to uncompress the data. If this had worked properly, it would have been great in saving the bandwidth in general.

Personally, I am inclined to agree with Apache, in that 'if you can not handle the content encoding, do not ask for it'. I find it surprising that all three major browsers have problems with compressed contents for Ajax calls, specially when they seem to be able to handle them fine for whole page refreshes. Maybe someone can enlighten me?

back


 by by David at 03 Dec 2010 17:31:16
Copyrights © Transcraft Trading Limited 2006.All rights reserved.