3

I've been working on this PHP CPU and RAM monitor for a while now - http://nereus.rikkuness.net/php-cpu-monitor/

And it's all working great and does what it's supposed to do. But I use Linux so do not have much ability to test on IE. A few friends are saying that it works on everything modern but completely crashes IE.

Just wondering if anyone had any idea as to why that might be?

Code is available here - http://php-cpu-monitor.googlecode.com/files/php-cpu-monitor-1.0.tar.gz

Charles
  • 50,943
  • 13
  • 104
  • 142
Steve
  • 576
  • 2
  • 7
  • 21
  • I am using IE and it does not crash. – Rudi Visser Jan 03 '13 at 01:02
  • 4
    moreover, the fact that it crashes in ie has nothing to do with php, php is a serverside language, after you serve the file with it it has nothing to do with php. The ajax can come from wherever as far as the frontend cares. – Benjamin Gruenbaum Jan 03 '13 at 01:05
  • What version is it not crashing with? – Steve Jan 03 '13 at 01:06
  • IE 9.0 stops responding on win7. Also the timers update more often then on other browsers. I suppose your javascript had a memory leak somewhere. Something IE interprets on a different way... – Neograph734 Jan 03 '13 at 01:06
  • Benjamin Gruenbaum: Well this is true, but it's JQuery in the background so I'm assuming it's probably that that's doing the damage. – Steve Jan 03 '13 at 01:06
  • 1
    It does not crash on IE10 FWIW. – Rudi Visser Jan 03 '13 at 01:23
  • Please construct a concise example and post the relevant code in the OP. Otherwise, it's useless when the code download is no longer available. – Sparky Jan 14 '13 at 20:39
  • Yeah but like I said, I don't know where it's going wrong. I have no way of testing and debugging to find out what's breaking. – Steve Jan 14 '13 at 20:42
  • Perhaps you can use Microsoft's [IE App Comp VPC images](https://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=11575) (with VirtualBox) to do testing? There's also a tool ([ievms](https://github.com/xdissent/ievms)) that can automate the installation for you. – Jeffery To Jan 18 '13 at 07:35
  • try setInterval instead of calling replay() inside itself. – Chris Whittington Jan 18 '13 at 19:52
  • Does the problem still occurs if you set the timespan to 30 seconds? I am asking, because I wantet to use the JavaScript Profiler of the IE to see what happens. – Christian Kuetbach Jan 21 '13 at 20:59

3 Answers3

4

IE caches your AJAX call in the first load. So your interval timer is bypassed and your UI gets pounded by the constant calls to the replay() function

$("#cpu").load("cpu.php?cpu=" + cpuCall , function() {

you could add a timestamp to avoid getting the cached result:

$("#cpu").load("cpu.php?cpu=" + cpuCall + "&t=" + new Date().getTime(), function() { 

check this link for reference

jQuery's .load() not working in IE - but fine in Firefox, Chrome and Safari

Another solution might be to delay the call to replay() with setTimeout()

setTimeout(replay,cpuCall);

but this will, if i understand your code correctly, require you to change your code on the server side (and it will not resolve the IE cache issue)

Community
  • 1
  • 1
Urban Björkman
  • 2,095
  • 1
  • 13
  • 27
4

I've had some problems very similar to this one in the past, and they are usually always related to caching. And since your AJAX requests are getting cached, your PHP script is no longer sleeping for the user's given interval, which is why you are seeing the requests complete so much faster.

Background on Caching

There are really only three response headers that your web server will issue to control how your AJAX resources are cached. These apply both to HTTP as well as AJAX requests. You don't really need to understand these for your purposes, but it is always good information to know:

  1. Expires - this header tells the browser when it needs to retrieve a new version of the resource. For example, a photograph or company logo might have an Expires header set to months into the future, since we don't expect these images to change very often. On the other hand, AJAX requests to retrieve time-sensitive CPU usage data should probably have an expires value of -1 to ensure that this data is always refreshed
  2. Last Modified - this can be used by the browser to send conditional GET requests to the server. The server checks to see if the resource has been changed later than the given value, and if so returns the updated content
  3. Cache Control - this allows proxies and other caches to store copies of this resource in shared (or non-shared) pools for even quicker access to the resource.

How jQuery.load() Works

jQuery.load() works by sending a simple GET request for html resources on the server. Keep in mind that the jQuery load() function is the simplest way to fetch data, and oftentimes isn't the best method of data retrieval. It is designed to be a quick way to grab html from the server and subsequently populate the html within your selected jQuery DOM elements. Here's a snippet from the docs:

This method is the simplest way to fetch data from the server. It is roughly equivalent to $.get(url, data, success) except that it is a method rather than global function and it has an implicit callback function. When a successful response is detected (i.e. when textStatus is "success" or "notmodified"), .load() sets the HTML contents of the matched element to the returned data. This means that most uses of the method can be quite simple.

Since $.load() is primarily a simple way to insert html into jQuery elements, the jQuery library doesn't provide a mechanism to ensure that your requests are not being cached. This is reasonable, because if you are simply retrieving HTML, we can get much increased performance by caching these responses, especially if they haven't changed and are being polled frequently.

Of all the browsers I tested, it looks like IE(9) is the only one that consistently caches AJAX requests. Look at the difference between the requests made in Firefox vs. Internet Explorer:

Firefox:

AJAX Request in Firefox

Internet Explorer:

AJAX Request in IE9

Notice the suspicious <1 ms response time from IE. IE doesn't ever refresh cached content before it's expiration date, nor does it distinguish between HTTP and AJAX requests when it comes to caching. We need to try a different solution in order to ensure that we are receiving fresh data each time we make the call to your AJAX URL.

Preventing Internet Explorer from Caching AJAX Requests

There are a couple different ways we can workaround IE's caching limitations:

  1. Add a randomized token (nonce value) to the query string, like ?token=[timestamp]. By altering the request URL for each request, browsers will store different cached copies of the resource for each request, and you'll ensure that you get the latest data from the server. jQuery creates a nonce value by simple getting a timestamp like so: var nonce = ( new Date() ).getTime();
  2. Use POST instead of GET requests. Since POST requests are designed to send requests that modify resources on the server, browsers will never cache them.
  3. Send a HTTP response header that specifically forbids browsers to cache it - this would be implemented in your cpu.php. You can easily modify this by altering your $http_response_header array (see here for the documentation)
  4. Use jQuery.ajax() instead of jQuery.load(): With $.ajax() you can specify certain AJAX calls to force refresh using the cache: false option. Or even more, you can ensure that all AJAX calls are refreshed each time by configuring this in your ajaxSetup(): $.ajaxSetup ({ cache: false });. This is essentially the same solution as #1, but without the need to create a nonce value in your javascript code.

Of all the alternatives, #4 is the best preserves the type of request you are making and is the easiest to configure.

One other suggestion - using window.setInterval() to call your replay() function is an easy way to set waiting intervals between requests, and it's usually better to implement variable-length sleep cycles on the client than the server.

Kyle
  • 4,202
  • 1
  • 33
  • 41
  • 1
    Well researched and posted. Thanks for going to such great lengths to document all of this. – tobint Jan 22 '13 at 02:40
-1

I am seeing this code, the text is outside the input tag, is this intentional?

<input id="radio01" type="radio" name="speed" value="0.1" onclick="changeSeconds(this)" />0.1
<input id="radio05" type="radio" name="speed" value="0.5" onclick="changeSeconds(this)" checked="checked" />0.5
<input id="radio1" type="radio" name="speed" value="1" onclick="changeSeconds(this)" />1
<input id="radio5" type="radio" name="speed" value="5" onclick="changeSeconds(this)" />5
<input id="radio10" type="radio" name="speed" value="10" onclick="changeSeconds(this)" />10
ATOzTOA
  • 34,814
  • 22
  • 96
  • 117