러시아어 인형 캐싱 외에도 Rails 앱의 성능을 향상시키는 더 많은 기술이 있습니다. 이번에는 렌더링된 페이지를 사용자의 브라우저 캐시에 저장할 수 있는 Rails의 기본 제공 조건부 GET 지원을 살펴보겠습니다.
<블록 인용>👋 그리고 캐싱 외부의 성능에 대해 더 읽고 싶으시다면 Ruby(on Rails) 성능에 대해 더 많이 썼습니다. Ruby 성능 모니터링 체크리스트를 확인하세요.
Etag 및 Last-Modified 헤더
브라우저가 Rails 앱의 페이지에 대한 HTTP GET 요청을 실행하면 라우터가 이를 컨트롤러 작업 중 하나로 연결합니다. 그런 다음 컨트롤러는 데이터베이스에서 필요한 데이터를 요청하고 뷰를 렌더링합니다. HTTP 응답(200 OK
포함) 응답 코드로)는 브라우저가 구문 분석하고 표시할 수 있도록 응답 본문의 보기에서 렌더링된 HTML과 함께 브라우저로 다시 전송됩니다.
리소스가 다시 요청되면 동일한 파이프라인을 거칩니다. 일부 상황에서는 페이지가 그 동안 변경되지 않았기 때문에 이것이 필요하지 않습니다. 이를 위해 HTTP는 ETag를 제공합니다. 및 최종 수정 헤더. 이를 사용하여 브라우저는 응답 본문을 저장하고 헤더를 사용하여 부실한 경우 무효화할 수 있습니다.
태그 , 또는 엔티티 태그 , 클라이언트 측 캐시 유효성 검사에 사용되므로 HTTP 응답에 대한 캐시 키로 생각할 수 있습니다. 모든 요청에 대해 HTTP 응답 헤더에서 브라우저로 다시 전달됩니다.
~ $ curl -I https://localhost:3000/products/1
HTTP/1.1 200 OK
...
ETag: W/"9462d76cc55aeb6249fa990e39231c7c"
Last-Modified: Wed, 25 Apr 2018 08:27:04 GMT
...
나중에 응답이 반복되면 브라우저는 캐시에서 기존 응답을 찾고 마지막 요청에서 저장된 Etag를 If-None-Match
로 사용합니다. 헤더. 이 헤더는 Rails 앱에 이미 이 버전이 캐시에 있음을 알려줍니다.
요청의 Etag가 현재 것과 일치하면 Rails는 304 Not Modified
를 보냅니다. 응답 본문이 없는 응답. 이렇게 하면 브라우저가 로컬 캐시의 캐시를 대신 사용하도록 지시합니다.
~ $ curl -i -H 'If-None-Match: W/"9462d76cc55aeb6249fa990e39231c7c"' https://localhost:3000/products/1
HTTP/1.1 304 Not Modified
...
ETag: W/"9462d76cc55aeb6249fa990e39231c7c"
Last-Modified: Wed, 25 Apr 2018 08:27:04 GMT
...
Rails의 조건부 GET 요청
로컬 Rails 애플리케이션에서 페이지를 요청하면 Rails가 각 요청에 대해 Etag를 자동으로 추가하는 것을 볼 수 있습니다. 동일한 페이지를 연속으로 두 번 요청하면 각 요청에 대한 Etag 변경 사항을 볼 수 있습니다.
Rails는 기본적으로 각 요청에 대해 Etag를 생성하지만 전체 응답 본문의 다이제스트를 사용하여 생성합니다. 이것은 <%= csrf_meta_tags %>
를 의미합니다. 레이아웃에서 csrf-token 메타 태그가 각 요청에 대해 변경됨에 따라 Etag가 꺼집니다. 각 요청의 본문을 변경하기 때문에 Etag가 무효화되고 로컬 캐시가 오래된 것으로 표시됩니다.
그 외에도 Rails는 304 Not Modified
를 반환하지 않습니다. 기본적으로 로컬 캐시는 컨트롤러에서 명시적으로 새로운 것으로 표시되지 않기 때문입니다.
fresh_when
및 stale?
조건부 GET에 대한 요청 헤더의 Etag를 사용하려면 로컬 캐시의 개체를 "신선함"으로 명시적으로 표시해야 합니다. 예를 들어 제품을 보여주는 페이지의 경우 제품과 보기 템플릿이 변경되지 않는 한 캐시를 최신 상태로 유지할 수 있습니다. 이 작업을 수행하기 위해 두 가지 작업을 수행합니다.
- 전체 응답 본문을 사용하면 캐시된 응답이 유효한지 확인하기 위해 전체 본문을 렌더링해야 하므로 Etag를 구성하는 값을 명시적으로 설정합니다. /리>
- 요청 헤더의 Etag를 이전 예측한 Etag와 비교합니다. 뷰를 렌더링하고 일치하는 경우 렌더링을 생략합니다.
Rails는 우리를 위해 모든 것을 하는 도우미와 함께 제공됩니다. fresh_when
을 사용하여 제품에 Etag 및 Last-Modified 날짜를 명시적으로 기반으로 할 수 있습니다. .
# app/views/products/show.html.erb
def show
@product = Product.find(params[:id])
fresh_when @product
end
명시적인 respond_to
가 있는 경우 차단, stale?
사용 fresh_when
대신 .
# app/views/products/show.html.erb
def show
@product = Product.find(params[:id])
if stale?(@product)
respond_to do |format|
format.html
end
end
end
이제 제품 페이지 중 하나를 요청하면 응답이 로컬로 캐시됩니다. 동일한 페이지에 대한 후속 요청에는 Etag가 포함되어 Rails에 캐시된 응답이 있음을 알리고 이를 새 Etag와 비교합니다. 일치하는 경우 Rails는 페이지 렌더링을 건너뛰고 304 Not Modified
를 반환합니다. 즉시.
참고 :페이지를 새로 고치면 항상 페이지의 캐시되지 않은 버전이 요청됩니다. 조건부 GET가 작동하는지 테스트하려면 대신 링크를 사용하거나 뒤로 버튼을 사용하여 다른 곳으로 이동하십시오.
이 기사와 AppSignal Academy 시리즈의 이전 기사가 마음에 드셨습니까? Rails의 캐싱에 대한 더 많은 기사가 준비되어 있습니다. 그러나 다음에 (캐싱 관련 또는 기타) 무엇에 대해 작성하고 싶은지 주저하지 말고 알려주세요!