Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Rails의 클라이언트 측 캐싱:조건부 GET 요청

러시아어 인형 캐싱 외에도 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_whenstale?

조건부 GET에 대한 요청 헤더의 Etag를 사용하려면 로컬 캐시의 개체를 "신선함"으로 명시적으로 표시해야 합니다. 예를 들어 제품을 보여주는 페이지의 경우 제품과 보기 템플릿이 변경되지 않는 한 캐시를 최신 상태로 유지할 수 있습니다. 이 작업을 수행하기 위해 두 가지 작업을 수행합니다.

  1. 전체 응답 본문을 사용하면 캐시된 응답이 유효한지 확인하기 위해 전체 본문을 렌더링해야 하므로 Etag를 구성하는 값을 명시적으로 설정합니다. /리>
  2. 요청 헤더의 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의 캐싱에 대한 더 많은 기사가 준비되어 있습니다. 그러나 다음에 (캐싱 관련 또는 기타) 무엇에 대해 작성하고 싶은지 주저하지 말고 알려주세요!