Http Cache-control

PIZZU·2023년 12월 28일
0

Http Caching (웹사이트에서만 적용)

서버 간 통신에서 REST API를 많이 사용하는 요즘. 서버의 자원을 절약하기 위한 방법으로 캐싱을 사용할 수 있습니다. 캐싱을 사용하는 지점은 여러 곳일 수 있지만 HTTP 1.1 기술을 사용하여 클라이언트가 가진 ETag 로 서버 자원의 변경을 확인하고 변경이 되지 않으면 클라이언트가 캐싱한 데이터를 사용하는 방법이 있습니다. 웹 사이트와 애플리케이션의 성능은 이전에 가져온 리소스들을 재사용함으로써 현저하게 향상될 수 있습니다. 웹 캐시는 레이턴시와 네트워크 트래픽을 줄여줌으로써 리소스를 보여주는 데에 필요한 시간을 줄여줍니다. HTTP 캐싱을 활용하면 웹 사이트가 좀 더 빠르게 반응하도록 만들 수 있습니다.

HTTP 캐싱은 GET 메소드에서만 동작합니다.

아래 소스는 예제로 만들어본 것이다.

Route

Route::middleware('cache.headers:public;max_age=300;etag')->get('/test', 'Main\AdminController@test')->name('test');

//eTag를 사용하지 않으려면 middleware를 안넣으면됨

Controller

public function test(Request $request){

        /*If-Modified-Since가 있고, If-Modified-Since시간이 현재 페이지 요청한 시간 - 300초보다 크면 (즉, 5분이 지났으면) 304를 return 해주도록 하였다.*/
        
        if (request()->hasHeader('If-Modified-Since') && strtotime(request()->header('If-Modified-Since')) >= time() - 300){      
            return response('', 304);
        }

        $query = \DB::Connection('mysqlgame')->table('User')->where('UserID','<', 10)->get();
        $data = ["data" => $query];

        $response = response(view('main.sm.test', $data));
        $response->header('Cache-Control', 'public, max-age=300')
            ->header('Last-Modified', $lastModified->format(\DateTime::RFC7231));

        return $response;
    }

View

<html>
<body>
    <div class="container-fluid">
		<h2>정보</h2>
		<div class="container">
            <div class="row">
                <div class="col column koreaG"> 
                    <h1>정보</h1>
                    @foreach ($data as $row)
                        <div class="item" draggable="true">{{$row->Nickname}}</div>
                    @endforeach
                </div>
            </div>	
    </div>
</body>
</html>

위의 소스를 설명하자면 처음 페이지를 로드했을때는 처음 200으로 나오고, 그이후 설정한 5분동안은 cache-control 브라우저 캐시에 남아있기 때문에 DB에 접근하지 않고 곧바로 304를 return한다

만약, 데이터가 변경됐을경우 새로운 데이터로 함께 200을 응답주고 싶다면 lastModified를 체크하면 된다.

$lastModified = 실제로 데이터가 변경된 시간(ex db가 변경됐다던지, 캐시가 변경됐다던지)

if (request()->hasHeader('If-Modified-Since') && strtotime(request()->header('If-Modified-Since')) >= $lastModified->getTimestamp()) {  //만약 데이터가 변경되지 않았다면 return 304
        	return response('', 304);
}

처음 로드 됐을때

로드 후 5분이 지나지 않아 캐시가 남아있을때

5분이 지나고 다시 새로고침 했을때 새로운 데이터와 함께 200 return

profile
pizzu's blog

0개의 댓글