간단한 브라우저 캐싱을 이용하기 위해 전체 사용자 이미지 파일 구조를 변경하는 것이 가치가 있습니까?


9

모바일 사이트 중 하나에서 사용자의 프로필 이미지를 사용자 폴더에 '1.jpg'로 저장하고 업로드 한 추가 사진을 위해 점차적으로 거기에서 이동합니다. 즉, 프로필 사진을 변경할 때마다 파일 이름이 동일하게 유지됩니다.

사용자의 프로필을보고 다시 볼 때마다 동일한 오래된 그림이 반복해서 다운로드되지 않도록 이미지 캐싱을 활용하고 싶었지만 동시에 사용자의 브라우저를 원합니다. 변경된 경우 새 파일을 다운로드하십시오.

내가 읽은 것에서 실제로이 작업을 수행하는 유일한 방법은 실제로 임의의 파일 이름을 사용하고 DB의 모든 파일 이름을 추적하여 만료되지 않는 캐시를 설정할 수 있도록하는 것입니다. 변경된 파일은 새로운 파일 이름을 갖기 때문에 다시 뽑 힙니다. 그러나 지금까지 내가 구성 한 방식의 장점은 데이터베이스를 완전히 건너 뛰고 파일의 위치를 ​​예측할 수 있기 때문에 파일에 직접 액세스 할 수 있다는 것입니다.

그래서 내 질문은 내 업로드 파일의 전체 파일 구조를 변경하고 DB 요소를 추가하여 새로운 업로드시 영구 캐싱 및 자동 다시 다운로드의 이점을 얻는 것이 가치가 있습니까?

이것은 큰 사업이지만, 가치가 있다고 생각되면이 급격한 변화로 나아가는 데 아무런 문제가 없습니다. 나는 이것이 "큰 소년들"이 그것을하는 방법인지 확인하고 싶기 때문에 파일 구조를 다시 변경할 필요가 없다.

감사.

답변:


7

일반적으로 사용되는 솔루션 중 하나는 이미지 URL을 다음과 같이 만드는 것입니다.

http://www.example.com/path/to/images/1.jpg?v=123456

여기에 /path/to/images/1.jpg이미지의 실제 URL 경로 ?v=123456가 있지만 URL 끝에 추적되는 더미 쿼리 일뿐입니다. 쿼리 문자열은 이미지가 변경 될 때마다 변경하고 변경되지 않는 한 동일하게 유지하는 한 버전 번호, 타임 스탬프, 이미지 내용의 해시 등 어떤 것이 든 될 수 있습니다.

트릭은 URL이 실제로 정적 파일을 가리 키기 때문에 이러한 URL을 제공하도록 요청 될 때 웹 서버가 쿼리 문자열을 무시한다는 것입니다. 그러나 사용자의 브라우저와 그 사이의 프록시에 따라 쿼리 문자열이 다른 URL은 완전히 다르므로 쿼리 문자열을 변경하면 브라우저가 파일을 다시로드해야합니다.

따라서, 당신은 보낼 수있는 웹 서버 구성 할 수 있습니다 ExpiresCache-Control쿼리 문자열을 변경하여 다시로드를 강제 할 수있는 지식의 안전 무기한 캐싱을 허용하는 HTTP 헤더를. mod_expires 와 함께 Apache를 사용하는 경우이를 수행하는 한 가지 방법은 다음 .htaccess과 같이 이미지 디렉토리에 파일 을 넣는 것입니다 .

ExpiresActive On
ExpiresDefault "access plus 1 year"

이 기술은 많은 유명 웹 사이트에서 사용됩니다. 예를 들어이 페이지의 HTML 소스를 보면 다음과 같은 URL에서 해당 스타일 시트가로드 된 것을 알 수 있습니다.

http://cdn.sstatic.net/stackoverflow/all.css?v=7cd8ea9d6f1e

여기서는 ?v=7cd8ea9d6f1e위에서 설명한 것처럼 더미 쿼리 문자열입니다. 변경 한 후에도 여전히 동일한 파일을 리턴하는지 확인할 수 있습니다.


또한 흥미롭지 만 파일을 마지막으로 수정 한 시간과 브라우저를 처음 본 시점을 어떻게 추적하여 사용자 브라우저에 파일을 다시 가져와야하는지 (예 : 쿼리 값 변경) 결정하는 방법은 무엇입니까?
ProgrammerGirl

1
파일을 본 시점을 추적 할 필요가 없습니다. 파일이 마지막으로 변경된시기 (또는 다른 적절한 특성)를 추적하여 쿼리 문자열에 포함하십시오. 이렇게하면 파일이 변경 될 때마다 URL도 변경됩니다.
Ilmari Karonen

매우 흥미 롭습니다. 따라서 파일의 "마지막으로 수정 된"속성을 가져 와서 쿼리 값을 올바르게 만들 수 있습니까?
ProgrammerGirl

1
그렇습니다.
Ilmari Karonen

1
내가 아는 중요한 단점은 없습니다. 검색 엔진 색인에 이미지의 복제본이 생길 수 있지만 적어도 Google과 같은 주요 검색 엔진은 그러한 트릭을 다루는 데 상당히 현명합니다. 어쨌든 rel = "canonical"HTTP 헤더를 전송 하고 만료 시간을 적절 하게 유지함으로써 (예 : 1 년이 아닌 1 개월 또는 1 주 )이 문제를 완화 할 수 있습니다 .
Ilmari Karonen

6

캐시하는 방법은 여러 가지가 있습니다.

조건부 GET

이러한 이미지를 파일 시스템에 저장하고 웹 서버를 통해 직접 제공하는 경우 이미 조건부 get을 사용하고있을 것입니다 . 웹 서버는 파일 시스템 메타 데이터를 자동으로 사용하여 ETAG 헤더를 설정하고 브라우저 에 요청에 헤더가 포함되어 If-Modified-Since있거나 "304 Not Modified"로 자동 응답 If-Matches합니다. (모든 브라우저에서 가능합니다.)

이 경우 전체 이미지가 다시 제공되지 않으므로 대역폭을 절약 할 수 있습니다. 그러나 GET 요청은 계속 발행되므로 여전히 요청의 오버 헤드와 대기 시간이 있습니다.

웹 서버가 Cache-Control헤더 public,max-age=N값을 이미지로 설정하여 캐시 새로 고침을 희생시키면서 요청 수를 약간 줄일 수 있습니다 . 이것은 캐시가 리소스 max-age가 업데이트되었는지 확인하기 전에 최대 몇 초 동안 리소스를 유지할 수 있다고 말합니다 .

그러나 HTTP는 캐시 항목을 무효화하는 한 가지 방법 만 정의하므로 애플리케이션의 의미에 맞지 않을 수 있습니다. 프로파일 사진을 업데이트하는 URL에 POST 또는 PUT하는 경우 Location: [url of photo]헤더로 응답하면 해당 URL의 캐시 항목이 무효화됩니다.

(이것은 주석이있는 웹 페이지를 캐시 한 다음 사용자가 새 주석을 게시 한 후 브라우저가 페이지를 강제로 다시로드하도록하는 메커니즘입니다. 브라우저는 POST /commentwith 303 See Other및 a에 응답 합니다 Location: /page/with/comment. 오랜 버그 로 인해 Firefox에서 작동합니다 .)

트래픽이 많지 않으면 캐싱에 대한이 접근 방식이 좋습니다.

URL 변경

URL은 리소스의 표현이므로 캐싱을 관리하는 또 다른 방법은 리소스의 캐시 매개 변수를 변경하지 않고 "캐시 영구"지시문을 사용하여 새로운 리소스를 만드는 것입니다. 이는 "큰 소년"이 선호하는 접근 방식으로, 추가 요청 을 생성 하지 않고 많은 대역폭을 절약 할 수 있기 때문 입니다. 단점은 훨씬 더 많은 부기를 필요로한다는 것입니다.

이를위한 두 가지 일반적인 기술이 있습니다.

쿼리 문자열

웹 서버는 파일 시스템에서 파일을 제공 할 때 쿼리 문자열을 무시합니다. : 캐시는, 그러나,하지 /1.jpg?t=12345/1.jpg?t=67890서버들이이 같은 생각에도 불구하고, 두 개의 완전히 다른, 관련이없는 자원입니다.

따라서 html에서 리소스를 참조 할 때마다 파일 시스템 타임 스탬프를 쿼리 문자열로 추가하고 긴 Expires헤더를 설정하면 됩니다. 브라우저는 영원하지이 자원을 캐시 할 것입니다 어느 한 쿼리 문자열이 변경되지 않는 한 가져옵니다.

단점은 캐시를 강제로 무효화하려는 경우 항목에 대한 새 URL의 웹 서버에 지시하는 것이 어렵거나 불가능하다는 것입니다. 예를 들어, 브라우저에 참조가 포함 된 캐시 된 HTML 페이지가 /1.jpg?v=1있지만 항목 /1.jpg?v=1(파일 또는 메모리 공간이 부족할 수 있음) 을 지우려면 새 요청을 /1.jpg?v=1합니다. 그 동안 이미지가로 변경된 /1.jpg?v=2경우 올바른 응답은 다음 중 하나입니다.

  1. 파일의 이전 버전을 제공하십시오. 특정 시점에 모든 자원이 서로 일치하도록하려면이 작업을 수행하십시오. 예를 들어 오래된 html 파일이 포함 된 새 CSS 파일이 제대로 작동하지 않을 수 있으므로 CSS 파일로 수행해야합니다.
  2. 을 사용하여 파일의 새 버전으로 리디렉션하십시오 301 Moved Permanently. 모든 자원을 가능한 한 새로운 것으로 만들려면이 작업을 수행하십시오.

이 두 가지 모두 웹 서버만으로는하기가 어렵 기 때문에 이미지 요청에 대해서도 웹 응용 프로그램을 호출해야하므로 더 복잡하고 리소스 집약적 일 수 있습니다. 웹 서버는 파일을 처리하는 데 매우 빠르기 때문에 웹 응용 프로그램의 오버 헤드로 인해 대역폭과 대기 시간이 늘어날 수 있습니다.

파일명

쿼리 문자열을 추가하는 대신 파일 이름을 변경하십시오. 즉, 파일 시스템에 여러 버전의 파일을 쉽게 보관할 수 있지만 리소스 및 이름을 추적하려면 파일 메타 데이터를 저장하고 다른 데이터베이스 예약을 수행해야 할 수도 있습니다.


0

http status에 대해 읽으면 304 Not Modified304로 다운로드 요청에 응답 할 수 있어야하며,이를 통해 서버에 캐시 된 데이터를 브라우저에 다시 보내도록 요청합니다. 이 질문 /programming/2978496/make-php-page-return-304-not-modified-if-it-hasnt-been-modified를 읽고


흥미롭지 만 문제가있는 파일 스키마에 대한 "대역 지원"솔루션입니까, 아니면 내 파일 스키마가 좋으며이 캐싱 기능이 필요합니까? 또한 파일을 마지막으로 수정 한 시간과 브라우저를 처음 본 시점을 어떻게 알면 사용자의 브라우저가 파일을 다시 가져 오도록 지시해야 하는지를 결정하는 방법은 무엇입니까?
ProgrammerGirl

그것에 익숙하지 않은, Francis Avila는 그것에 대해 더 많이 알고 있다고 생각합니다
Puggan Se
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.