Announcement

Collapse
No announcement yet.

Make web frontend Cache friendly -> MUCH faster user experience!!

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    Make web frontend Cache friendly -> MUCH faster user experience!!

    Hello,

    Just like others (search the forums/Google) I was annoyed by the seemingly slow page loading in the Zabbix web interface. So I went out to investigate.

    After having already tuned my Postgres database and installed a PHP opcode cacher (APC) page loading was still slow. I noticed however that my browser makes a lot of requests for objects (~34, css files, images, javascript files) on EVERY page load and that some of those objects are pretty big. For example jsLoader.php (a Javascript file containing the Prototype framework) is ~350kB.

    So I enabled Gzip compression in Nginx, that brought the size of most objects down tremendously (jsLoader.php was now only 90kB).
    Code:
        gzip  on;
        gzip_types  text/css application/x-javascript text/javascript application/json;
    I also wanted to take use of client side caching, so that the browser doesn't requests all the static files on the page again and again on every page load:
    Code:
            location ~* \.(jpg|jpeg|png|gif|css|js)$ {
                expires 30d;
            }
    That seemed to mostly work as expected. However, I noticed that my browser would still make GET requests for all objects from time to time, to revalidate all the objects on the page (using the If-Modified-Since header, to which the server responds with a 304 Not Modified). Thus introducing again the unnecessary overhead and roundtrips for HTTP requests for 34 objects. Even though I told it to cache all those objects...

    After some looking around, this seemed to be triggered when the graph and status pages reload automatically. It turns out that in js/main.js, the page is reloaded by doing (line 41):

    Code:
    location.reload();
    Apparently this forces the browser to not only reload the current page, but also to revalidate ALL the objects on the page (it sets Cache-Control: max-age=0). Thus making 34 GET requests again, instead of using the objects already cached. That's horribly inefficient!!
    I saw this behavior in FF and IE (Opera however seems to respect the cache or not respect the reload call, depending on how you look at it).

    To have it work 'properly' in FF and IE as well, I replaced that line by:

    Code:
    window.location.href = window.location.href;
    And, bazinga! The refresh only triggered GETs for about 4 objects instead of 34. Reload times of, for example, the trigger status page (with no triggers active and first visit time of +2 seconds) went down from ~1,50 seconds to only ~0,90 seconds!!

    IMHO, this is a big improvement. Certainly considering that my numbers are for local 100Mbps LAN! Relative improvements over Internet connections will be even bigger!

    Also when I had many automatically refreshing pages opened simultanously, I would notice pages getting stuck before or taking a really long time to reload (minutes!). I did not notice this behaviour anymore after this fix!

    The load on the webserver will also be a lot lighter, especially if you have many people looking at many pages at the same time!

    I didn't notice any negative side effects yet. The status pages or graphs themselves get updated properly, since they aren't cached in the first place. Feel free to test yourself, the 'patch' is simple

    @devs:
    I noticed the reload call being used in warning.php as well. Maybe improvements are possible there as well?
    Is there an official path I need to take to submit this as a patch or can you guys take it from here?

    Enjoying Zabbix again,
    Hopla
    Last edited by hopla; 04-05-2012, 16:35.

    #2
    nice work!

    Comment


      #3
      You should definitely put your good work at https://support.zabbix.com/ (the jira)!
      br
      Erik

      Comment


        #4
        I've reported the bug/improvement on the Jira: https://support.zabbix.com/browse/ZBX-4951

        I've also noticed that the caching often works even if you haven't explicitly enabled caching on your webserver. Most webservers send a Last-Modified header automically, based on the timestamp of the file in question, and most browser will use that for caching even without any accompanying Expires or Cache-Control headers (using their own heuristics, even if that behaviour is not according to spec).

        Setting Expires or Cache-Control headers is better however in the long run, since you're then sure that all browsers will always cache the files (and for a longer period).

        But what this means however is that everyone will probably benefit from this fix, even if they are not aware of possible server side caching improvements.

        Comment


          #5
          A fix has been made:

          https://support.zabbix.com/browse/ZBX-4951

          I don't know in what version(s) this will show up eventually though.

          Comment


            #6
            Hi,
            I noticed decent improvement in load times too. Hopefully, it won't be too long before this enhancement is publicly available.


            Regards,
            David

            Comment


              #7
              Hi,
              maybe I dont understand but...
              this is my 41 line of js/main.js
              n = Number(arguments[1]);
              if (n !== n) { // shortcut for verifying if it's NaN
              n = 0;
              }
              else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
              n = (n > 0 || -1) * Math.floor(Math.abs(n));
              }
              41line }
              if (n >= len) {
              return -1;
              }
              var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
              for (; k < len; k++) {
              if (k in t && t[k] === searchElement) {
              return k;
              }
              }
              return -1;
              Only place where i have location.reload(); is
              this.delayLeft -= 1000;
              if (this.delayLeft < 0) {
              76 line location.reload();
              }
              else {
              this.timeout = setTimeout('PageRefresh.check()', 1000);
              }
              },

              start: function() {
              if (is_null(this.delay)) {
              Ofc i change it to:
              this.delayLeft -= 1000;
              if (this.delayLeft < 0) {
              window.location.href = window.location.href;
              }
              else {
              Next restart apache and zabbix server and...
              no visual improvment, the overview is still long loading.
              My machine isent a powerful monster, so maybe this is prblem?
              xeon 3065 [email protected]
              4gb ram

              Sorry for my not "professional" approach but i dont know how to make more deeply anlyse of the problem.
              Iv try to look in apache logs but they arent tell much.
              If im missing something please advice me.

              Piotr
              Last edited by pietro54; 07-10-2012, 14:09.

              Comment


                #8
                hello,
                Maybe there is someone who can help me?

                Comment

                Working...
                X