ETag 헤더 지원

대부분의 HTML 페이지가 캐시되지 않기 때문에, ETag를 사용하면 페이지 로딩 성능에 상당한 긍정적인 영향을 미칠 것 같습니다. 이렇게 하면 클라이언트가 이미 페이지를 다운로드한 경우 서버가 해당 페이지를 다시 전송할 필요가 없어집니다.

이 부분에 대해 논의가 있었나요?

틀린 말일 수도 있지만, Discourse는 이미 클라이언트 측 JS에 크게 의존하고 있으므로 클라이언트가 다운로드하는 데이터는 최소한의 양입니다. 거의 모든 것이 첫 방문 시 로드되고 이후 캐시됩니다. ETags가 이 캐싱 프로세스를 얼마나 개선할 수 있을지는 솔직히 잘 모르겠습니다.

예를 들어, 제 페이지의 첫 로드는 약 800Kb이고 두 번째 로드는 약 40Kb입니다.

2개의 좋아요

Discourse는 이미 캐싱을 위해 상당히 잘 설계되고 설정되어 있습니다.

대부분의 사이트 자산(JS, CSS)은 자산의 해시를 기반으로 매번 사이트 업데이트 시 고유한 URL이 생성되므로, 긴 캐시 시간을 가질 수 있습니다.

사이트 업로드(이미지, 아바타 등)도 고유한 URL을 사용하는 것으로 생각합니다.

확인할 수 있는 대부분의 전체 페이지는 동적이며, 공격적으로 캐싱되어서는 안 됩니다. 새 게시물이나 수정된 게시물이 있는지 매 페이지 로드 시 확인하는 ETag 캐싱 방식을 사용하는 것도 가능할 것입니다. 팀이 왜 이렇게 결정하지 않았는지는 확실하지 않습니다.

3개의 좋아요

더 명확히 설명해야 할 것 같네요. 에셋은 잘 캐싱되고 있습니다. 제가 말씀드리는 것은 HTML 문서(첫 번째 요청)에 관한 것입니다.

당신이 볼 수 있는 대부분의 전체 페이지는 동적이며, 공격적으로 캐싱해서는 안 됩니다. 새로운 게시물이 없거나 수정된 게시물이 없는지 매 페이지 로드 시 확인하는 ETag 캐싱 방식을 사용하는 것도 가능할 것입니다. 팀이 왜 이렇게 하지 않기로 결정했는지 모르겠습니다.

네, 제가 말씀드린 것은 본질적으로 이것입니다. 하지만 ETag는 그렇게 수동적으로 생성되는 것이 아니라고 생각합니다. 서빙되는 원시 HTML을 기반으로 생성될 수 있으며, 클라이언트에게 "이것은 이전에 본 것과 정확히 같은 것이니 그대로 사용하세요"라고 알릴 수 있습니다.

문제는 내 이해로는 이미 클라이언트 측의 JS에서 그렇게 작동하고 있다는 것입니다. 그래서 HTML이 오가면서 처리되는 일은 없어요.

1개의 좋아요

HTML은 서버에서 JSON을 로드하며, 해당 JSON 요청은 ETag를 사용할 수 있습니다. 현재는 사용하지 않고 있지만, 팀이 그렇게 결정한 이유에 대해서는 정확히 알지 못합니다.

1개의 좋아요

페이지에 대한 첫 번째 요청은 서버에서 XHR를 통해 JSON을 로드하기 전에 이미 렌더링된 콘텐츠를 포함하고 있습니다. 말씀하신 대로 XHR 요청도 실제로 일어나고 있죠.

Chrome 디버거의 “Document” 유형 네트워크 요청을 확인하면 이 사실을 검증할 수 있습니다. 제 경우를 기준으로, 해당 요청에는 이미 카테고리들이 렌더링되어 있어야 합니다.

문서 요청에서 렌더링된 콘텐츠의 예시는 다음과 같습니다:

요청이 무의미한 이유는 Discourse가 HTML을 가져오지 않는 JavaScript 앱이며, 모든 "페이지"가 실행 가능한 JavaScript 코드를 통해 실시간으로 생성되기 때문입니다.

1개의 좋아요

당신의 요청은 Discourse가 HTML을 가져오지 않는 JavaScript 앱이기 때문에 무의미합니다.

여기서 당신의 경험과 전문성을 충분히 존중합니다. 하지만 저는 콘텐츠가 재사용 가능한 경우 루트 응답에 ETag를 사용하는 JavaScript 렌더링 웹 애플리케이션을 수십 개 운영해 본 경험이 있습니다.

모든 “페이지”는 실시간으로 실행 가능한 JavaScript 코드를 통해 생성됩니다.

위에서 게시한 스크린샷은 클라이언트 측 코드가 실행되기 전에 반환되는 HTML입니다. 따라서 백엔드(추측컨대 Rails)에서 이 라우트를 서빙하는 것이 분명히 존재합니다.

제가 살펴본 모든 Discourse 커뮤니티(이 커뮤니티를 제외하고)는 처음에 크롤러를 위해 모든 콘텐츠가 렌더링된 JavaScript 없는 버전의 사이트를 반환합니다.

제가 완전히 틀린 것 같다면 사과드립니다. 하지만 저는 “무의미한” 말을 하고 있다고 생각하지 않습니다. 그저 틀린 것일 뿐입니다.

1개의 좋아요

크롤러 사용자 에이전트에 대해서만 해당되므로, 이 관찰은 유용하지 않습니다.

크롤러 사용자 에이전트만 해당

이렇게 실행할 때 제가 확인하는 내용은 다음과 같습니다:

curl -H "User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36" https://community.midi.city/

이것은 크롤러 사용자 에이전트가 아니지만, 위의 페이로드가 반환되고 있습니다.


어쨌든, ETag에 대한 제 요청에 대한 답은 "아니오"인 것 같습니다. 피드백에 감사드리며, 언젠가 재고려되길 바랍니다.

맞습니다. 철학적 이유와 기술적 이유 모두를 고려할 때, 명확하고 단호한 답은 '아니오’입니다.

(에셋은 별개의 문제이지만, GUID를 사용하여 고유한 파일명을 부여하는 방식이 훨씬 우수한 접근법이기 때문에, ETag는 일반적으로 거의 쓸모없게 되었습니다.)

API도 마찬가지인가요? 작은 요청의 경우엔 가치가 없다고 이해할 수 있지만, 토픽 뷰는 최대 20KB까지 올라갈 수 있어서 누적되면 부담이 됩니다. 하지만 새 게시글이 있는 경우를 제외하면, 토픽을 반복적으로 보는 사람이 많지는 않죠..

그게 핵심입니다. 완전히 동일한 콘텐츠를 반복해서 볼 때, 오프라인 상태라면 서버에 접근하지 않고 브라우저 캐시에서 모든 콘텐츠를 이미 렌더링하고 있습니다.

온라인 상태에서도 로드되도록 업그레이드하려면 *캐시 무효화(cache invalidation)*가 필요하므로, 당연히 어려운 문제입니다.

2개의 좋아요

오, 작동한다고 해서 다행입니다. cache-control: no-cache, no-store 헤더는 API 응답이 브라우저 캐시에 절대 저장되지 않는다는 뜻이라고 생각했거든요.

그렇지 않아요. 글쎄요, 좀 복잡한 문제입니다. 여러 캐시가 관여하고 있거든요 :sweat_smile:

모두가 알고 사랑하게 되는 전통적인 브라우저 캐시에는 들어가지 않아요. 하지만 브라우저에는 JS를 통해 Cache Web API가 노출되어 있으며, 이는 이전에 읽은 콘텐츠의 오프라인 탐색을 제공하기 위해 응답을 캐시하는 데 사용됩니다.

5개의 좋아요