빌드 시점 콘텐츠 인덱스로 실행 시점 탐색 비용 줄이기

문제

문서 중심 웹사이트에서는 사용자가 페이지를 열 때마다 여러 작업이 필요할 수 있다.

  • 문서 파일 목록 읽기
  • 각 문서에서 제목, 태그, 링크 찾기
  • 백링크나 검색용 목록 만들기
  • 필요한 문서만 골라 화면에 표시하기

문서 수가 적을 때는 문제가 크지 않다. 하지만 이 작업을 요청마다 반복하면 첫 방문자가 특히 긴 대기 시간을 겪을 수 있다.

이 문제는 서버가 느려서만 발생하지 않는다. 이미 배포된 문서를 다시 읽고, 다시 해석하고, 다시 정리하는 불필요한 작업이 쌓이기 때문에 발생한다.

핵심 아이디어

문서 내용이 배포 뒤에 바뀌지 않는다면, 매 요청마다 문서를 분석할 이유가 없다.

대신 배포 전에 문서를 한 번 분석하고, 그 결과를 작은 인덱스 파일로 저장한다. 사용자가 웹사이트를 방문하면 서버는 원본 Markdown 파일 전체가 아니라 미리 만들어 둔 인덱스를 읽는다.

이를 빌드 시점 인덱싱이라고 한다.

여기서 빌드 시점은 배포 전에 웹사이트 결과물을 만드는 과정이고, 실행 시점은 사용자의 요청을 실제로 처리하는 순간이다.

인덱스란 무엇인가

인덱스는 원본 데이터에서 자주 필요한 정보만 따로 정리한 목록이다.

도서관의 색인 카드를 생각하면 이해하기 쉽다. 책을 찾을 때마다 도서관의 모든 책을 읽는 대신, 제목·저자·주제만 적힌 카드 목록을 먼저 본다. 웹사이트의 콘텐츠 인덱스도 같은 역할을 한다.

문서 사이트에서는 다음 정보를 인덱스에 담을 수 있다.

  • 문서 제목과 주소
  • 태그와 작성일
  • 검색에 사용할 텍스트
  • 다른 문서에서 이 문서를 가리키는 백링크
  • 문서 종류

백링크에 적용하기

백링크는 어떤 문서가 다른 문서에서 언급되었는지 보여준다.

실행 시점에 백링크를 계산하려면 모든 문서를 읽고, 각 문서 안의 링크를 찾아야 한다. 문서가 많아질수록 비용도 커진다.

빌드 시점에는 모든 문서를 한 번 읽어 다음과 같은 형태의 목록을 만들 수 있다.

{
  "note/csrf": [
    {
      "sourceTitle": "XSS",
      "sourceSlug": "xss"
    }
  ]
}

이후 csrf 문서를 열면 전체 문서를 다시 검사하지 않고 note/csrf 항목만 찾으면 된다.

기존: 문서를 열 때마다 모든 문서에서 링크를 찾음
개선: 미리 만든 인덱스에서 필요한 항목만 찾음

인덱스가 실제로 쓰이는 과정

인덱스를 만든다고 서버가 완전히 사라지는 것은 아니다. 비싼 문서 분석을 배포 전으로 옮기고, 요청 시점에는 작은 조회만 남기는 것이다.

백링크가 필요한 페이지는 실행 시점에 서버에서 렌더링될 수 있다. 이때 서버는 원본 문서 전체를 읽는 대신, 빌드 결과물에 포함된 인덱스에서 note/csrf 같은 키를 찾는다.

배포 전
문서 전체 읽기
→ 링크 찾기
→ 백링크 인덱스 만들기
→ 배포 결과물에 포함

사용자 요청 시
문서 주소 받기
→ 인덱스에서 해당 주소 찾기
→ 백링크 목록 전달

검색용 목록도 같은 원리로 만들 수 있다. 내 사이트의 Cabinet 같은 기능은 문서 목록을 미리 만들고, 사용자가 열 때는 이미 생성된 목록을 받도록 구성할 수 있다.

배포 전
문서 전체 읽기
→ 검색용 목록 만들기
→ 정적 응답 생성

사용자 요청 시
→ 미리 생성된 응답 전달

정적 응답은 서버가 매번 계산해서 보내는 대신, 배포 결과물이나 CDN에 미리 놓아 둔 응답이다.

정규화가 필요한 이유

같은 문서를 가리키는 링크도 여러 방식으로 작성될 수 있다.

[[note:csrf]]
[[../note/csrf]]
[[zt/literature/csrf]]

사람에게는 모두 같은 문서처럼 보이지만, 프로그램은 문자열이 다르면 다른 값으로 취급할 수 있다.

그래서 인덱스를 만들기 전에 링크 표현을 하나의 주소 형식으로 바꾸는 과정이 필요하다. 이를 정규화라고 한다.

정규화 규칙은 문서를 화면에 렌더링하는 규칙과 같아야 한다. 두 규칙이 다르면 링크는 열리지만 백링크에서는 누락되는 문제가 생긴다.

장점

빌드 시점 인덱싱은 계산을 더 일찍 하는 전략이다.

  • 첫 요청의 서버 작업이 줄어든다.
  • 같은 데이터를 반복 계산하지 않는다.
  • 정적 응답을 CDN에 저장하기 쉬워진다.
  • 응답 시간이 더 일정해진다.

특히 문서가 많아질수록, 실행 시점에 모든 문서를 훑지 않는 것만으로도 체감 성능 차이가 커질 수 있다.

언제 적합한가

빌드 시점 인덱싱은 콘텐츠가 배포와 함께 갱신되는 사이트에 특히 적합하다.

  • 개인 블로그
  • 문서 사이트
  • 정적 위키
  • 배포할 때만 콘텐츠가 바뀌는 포트폴리오

반대로 사용자가 수시로 글을 수정하거나 데이터가 실시간으로 바뀌는 서비스라면, 인덱스 갱신 전략을 별도로 설계해야 한다.

주의할 점

인덱스는 원본 문서에서 파생된 데이터다. 문서가 바뀌었는데 인덱스를 다시 만들지 않으면 오래된 결과가 보일 수 있다.

그래서 콘텐츠 동기화와 배포 빌드 과정에 인덱스 생성을 연결하는 것이 중요하다.

문서 변경
→ 인덱스 생성
→ 빌드
→ 배포

이 흐름이 자동화되어 있으면 원본 문서와 인덱스의 불일치를 줄일 수 있다.

정리

빌드 시점 인덱싱은 사용자가 기다리는 실행 시점에 문서를 분석하지 않고, 배포 전에 필요한 정보를 정리해 두는 전략이다.

문서가 자주 바뀌지 않는 웹사이트라면 단순한 구조로 첫 요청 성능과 탐색 경험을 함께 개선할 수 있다.

연결

참고

Backlinks 1