17

I'm working on a Laravel 5.1 project, using a lot of ajax calls returning html blocks.

To optimize the speed of the website i want to implement private and public response caching. this works fine using following code:

        return response()
        ->json($result)
        ->header('Cache-Control', 'public, max-age=300');

Yet using it this way wont hold in account objects that are updated within the 300 seconds.

Are there possibilities that allow me to clear the response cache of a request, if and only if the returning objects have been updated ?

4
  • To know that they have been updated you would have to send the actual request. Unless you create some sort of trigger when a value is updated that tells the cache that it shouldn't be used any longer Commented Mar 21, 2016 at 17:51
  • Yup, i could use E-tags, with an md5 hash of the updated state. yet i want to keep this as a last resort, and search for an elegant way in the mean time. Commented Mar 21, 2016 at 20:38
  • I usually handle that in the server-side using something like Redis. You can put an observer on the model and then loop through any keys that have your block and delete them so a new cached version will be created on the next page load. (are they specific to user, or page, or both? Commented Apr 22, 2021 at 20:56
  • you may be able to leverage localcache blogs.tensult.com/2020/01/27/… Commented May 26, 2021 at 14:44

2 Answers 2

1

Maybe you can try server side caching with something like this below. sorry this is crude

function sometest(User $user)
{

    /** . . .conditions to check if some data has changed . . . **/


    $jsonResponse = Cache::remember(Auth::id() . "_sometest", 300, function () use ($user)
    {
        $result = $user->all(); //get result here

        return $result;
    });

    return response()->json($jsonResponse);
}

You can read about here Cache

you can also try

Sign up to request clarification or add additional context in comments.

Comments

0

As other said, client browser need a request to know that the data has been updated. Here's some solutions I would look into in your case:

Server-side cache (data still need to be network transferred):

  • depending on your environment, I would set up an Nginx + FastCGI cache using a "stale and update" policy. So the cache is always served (fast), and the cache is always refreshed. So only a few requests (one, or more depending on time to refresh cache) after code update are served with outdated data. This cache is URL-based, so if your content is cookie/session-based it can become tricky.

  • as @ZachRobichaud said, you can use the Laravel cache and set up a low cache retention time. Let's say 10s, which means the request will be outdated for 10s max after your content update. I'm not aware of a "stale and update" way on laravel, but it can be done with queues.

Client-side cache (no data transfer needed):

as I said, the client needs to know the data has been updated to invalidate the cache.

  • Usually for assets, we do "cache bursting" by adding GET parameters to the file URL. Like 'asset?version=1234with version changing for each deployment. As header cache is URL (and header) based, URL change will force network loading of files. Not tested with text/HTML content-type response, but worth a try if you can update URLs with a parameter you can change in.env` as example. Can be done dynamically if you have a CD/CI or thins you can trigger on deploy. In this case, you can "infinite" cache those as the "refresh" will be done by changing the URL parameter.

  • You can take a look at stale-while-revalidate Cache-Control header value that seems to work the same: always serve cache, and refresh cache if expired (also look at other parameters, can give you ideas). Careful about compatibility on this (no IE or Safari).

The Laravel Cache may be the fastest to implement and test, and see if the results suit you. It depends on the payload size also, if it's huge, browser cache is indeed better. If bandwidth is not the issue, it's mostly server response time: in this case, Laravel Cache would do the trick.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.