Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible to cache JSON to increase performance / load time?

I'm using a JSON file to autopopulate a drop down list. It's by no means massive (3000 lines and growing) but the time taken to refresh the page is becoming very noticeable.

The first time the page is loaded the JSON is read, depending on what option the user has selected dictates which part of the JSON is used to populate the drop down.

It's then loaded on every refresh or menu selection after. Is it possible to somehow cache the values to prevent the need for it to be reloaded time and time again?

Thanks.

EDIT: More Info: It's essentially a unit converter. The JSON holds all the details. When a users selects 'Temp' for example a call is made and the lists are populated. Once a conversion is complete you can spend all day running temp conversions and they'll be fine but everytime a user changes conversion type so now length, the page refreshes and takes a noticeable amount of time.

like image 778
null Avatar asked Jul 12 '13 10:07

null


1 Answers

Unfortunately, I don't know of a standardized global caching mechanism in PHP. This article says that Optimizer Plus, a third party accelerator, is being included in core PHP starting in version 5.5. Not sure what version you are using but you could try that.

On a different note, have you considered file storage as andrew pointed out? I think it combined with $_SESSION could really help you in this case. Let me give you an example that would work with your existing JSON data:

Server Side

Store your JSON data in a .json file on your PHP server:

{
    "data": "some data",
    "data2": "more data",
    "data3": [
        ...
     ],
     etc.
}

Note: Make sure to properly format your JSON data. Remember all strings must be enclosed in double quotes ".

In PHP, use an if statement to decide the appropriate action:

error_reporting(E_ALL);
ini_set("display_errors", "On");
session_start();

if(isset($_SESSION['dataCache'])) {
    echo json_encode($_SESSION['dataCache']);
} else {
    $file = 'data.json';
    if (!is_file($file) || !is_readable($file)) {
        die("File not accessible.");
    }
    $contents = file_get_contents($file);
    $_SESSION['dataCache'] = json_decode($contents, true);
    echo $contents;
}

So lets dig into the above coding a little more. So here's what we are doing in a nutshell:

  1. Turn on error reporting and start session support.
  2. Check to see if we've already read the file for this user.
  3. If so, pull the value from storage and echo it out and exit. If not continue below.
  4. Save off the file name and do a little error checking to ensure PHP can find, open and read the contents of the file.
  5. Read the file contents.
  6. Save the decoded json, which is not an array because of the `true` parameter passed to `json_decode`, into your `$_SESSION` variable.
  7. Echo the contents to the screen.

This will save you the time and hazzle of parsing out JSON data and/or building it manually on the server. It will be cached for the users session so that they can use it through out.

Client Side

I assume you are using ajax to fetch the information? If not correct me, but I was assuming that's where some of your JavaScript comes into play. If so you may consider this:

Store the returned data in sessionStorage on the user's browser when it's returned from the server:

$.ajax({
    ...
    success: function (res) {
        localStorage.setItem("dataCache", JSON.stringify(res));
    },
    ...
});

Or if you use promise objects:

$.ajax({
    ...
}).done(function (res) {
    localStorage.setItem("dataCache", JSON.stringify(res));
});

When you need to read it you can do a simple test:

var data;
// This returns null if the item is not in local storage.
// Since JavaScript is truthy falsy, it will be evaluated as false.

if(localStorage.getItem("dataCache")) {
    data = JSON.parse(localStorage.getItem("dataCache"));
} else {
    // Make ajax call, fetch object and store in localStorage in the success or done callbacks as described above
}

Notes:

localStorage is a new feature in HTML5, so it's not fully supported on all browsers yet. Most of the major ones do however, even as far back as IE8 (I think). However, there is no standardized size limit on how much these browsers are required to hold per site.

It's important to take that into consideration. I can guarantee you probably will not be able to store the entire 30,000 line string in localStorage. However, you could use this as a start. Combined with the server side solution, you should see a performance increase.

Hope this helps.

like image 145
War10ck Avatar answered Sep 27 '22 19:09

War10ck