Skip to content

Conversation

@DEV4N4
Copy link

@DEV4N4 DEV4N4 commented Sep 2, 2025

과제 체크포인트

배포 링크

기본과제 : https://dev4n4.github.io/front_6th_chapter4-1/vanilla/
심화과제 : https://dev4n4.github.io/front_6th_chapter4-1/react/

기본과제 (Vanilla SSR & SSG)

Express SSR 서버

  • Express 미들웨어 기반 서버 구현
  • 개발/프로덕션 환경 분기 처리
  • HTML 템플릿 치환 (<!--app-html-->, <!--app-head-->)

서버 사이드 렌더링

  • 서버에서 동작하는 Router 구현
  • 서버 데이터 프리페칭 (상품 목록, 상품 상세)
  • 서버 상태관리 초기화

클라이언트 Hydration

  • window.__INITIAL_DATA__ 스크립트 주입
  • 클라이언트 상태 복원
  • 서버-클라이언트 데이터 일치

Static Site Generation

  • 동적 라우트 SSG (상품 상세 페이지들)
  • 빌드 타임 페이지 생성
  • 파일 시스템 기반 배포

심화과제 (React SSR & SSG)

React SSR

  • renderToString 서버 렌더링
  • TypeScript SSR 모듈 빌드
  • Universal React Router (서버/클라이언트 분기)
  • React 상태관리 서버 초기화

React Hydration

  • Hydration 불일치 방지
  • 클라이언트 상태 복원

Static Site Generation

  • 동적 라우트 SSG (상품 상세 페이지들)
  • 빌드 타임 페이지 생성
  • 파일 시스템 기반 배포

구현 과정 돌아보기

가장 어려웠던 부분과 해결 과정

디버깅하는게 제일 어려웠다......
에러 하나 고치면 다른거 터지고 그거 고치면 또 다른거 터지고
그리고 테스트가 깨진 결과를 보고 원인을 찾아내는게 어려웠다.

그리고 기본과제에서는 query가 상태로 저장되지 않게 하려고 router에서 관리하지 않게 작업을 했는데
심화에서는 router 자체를 동시성 문제가 없도록 작업하다보니 query를 상태로 저장하게 되었다.
기본을 먼저 하고 심화를 했는데 개발을 하다보니 일관성이 좀 없어진 것 같다.
심화에서 어떻게 될지 예측하지 못해서(막연히 기본이랑 비슷할거라고 생각했어서..) 어려움을 겪었던 것 같다.

그리고 심화에서는 Router가 필요한 순수함수들을 기존 interface 그대로 쓰기 위해서 router를 주입하는 훅으로 만들었는데 이 과정도 어려웠다.
원래는 props drilling을 하듯이 해결했었는데 전체적으로 코드의 변경이 너무 자잘하게 많아져서 고통받았었다.
지금은 조금 깔끔해진 것 같다.

구현하면서 새롭게 알게 된 개념

express를 제대로 공부하고 사용해본 것도 처음이고 SSG에 대해서 처음 알게되고 접하게 되었다.

SSR은 요청 시마다 렌더링, SSG는 빌드 타임에 미리 생성!

Hydration 과정에서 서버 HTML과 클라이언트 Virtual DOM이 일치해야 한다는 것도 처음 알게 되었다.
예전에 Next를 쓰면서 SSR 페이지를 개발할 때 개발자도구 네트워크 탭에서 서버에서 내려주는 HTML이 정확한지 확인할 생각도 못하고(뭣도모르고) 걍 개발했었는데 이번에 배워가지구 확인하면서 했다.

성능 최적화 관점에서의 인사이트

SSR을 쓰면 접속했을 때 서버에서 데이터를 구성해서 랜더링을 하기 때문에 화면이 뜨기까지 조금 느렸는데
미리 빌드하는 SSG를 이용하니까 화면이 빠르게 바로바로 뜨는 것 같았다.

학습 갈무리

Q1. 현재 구현한 SSR/SSG 아키텍처에서 확장성을 고려할 때 어떤 부분을 개선하시겠습니까?

지금은 페이지 단위로 SSG를 하는데 더 잘게 쪼개서 컴포넌트 단위로도 미리 만들 수 있지 않을까 하는 생각이 들었다.

Q2. Express 서버 대신 다른 런타임(Cloudflare Workers, Vercel Edge Functions 등)을 사용한다면 어떤 점을 수정해야 할까요?

서버리스 환경은 Express 서버와 달리 매번 새로 뜨는 서버라고 생각할 수 있는데, 이로 인해 서버리스 환경에서는 메모리를 계속 사용할 수 없다. 그래서 최적화가 좀 어려울 것 같고 요청이 들어올 때마다 매번 초기화 작업을 해줘야 하므로 초기화를 경량화 하는 게 중요할 것 같다.
예를 들어서 prefetch 함수를 좀 더 작게 만든다거나?? 하는 식으로..

Q3. 현재 구현에서 성능 병목이 될 수 있는 지점은 어디이고, 어떻게 개선하시겠습니까?

라우터를 매번 새로 create 하는 것이 조금 걸렸다.
다 사용한 라우터를 메모리에서 해제하는 방법이 있으면 좋을 것 같다.

Q4. 1000개 이상의 상품 페이지를 SSG로 생성할 때 고려해야 할 사항은 무엇입니까?

어엉ㅇ...ㅠㅜㅜㅜ
설마 1000개 페이지가 한번에 다 필요하지는 않을거같고... top 100개 페이지만 미리 만들고 나머지는 실시간으로 SSR로 내려도 괜찮지 않을까? 이게 비용면에서 합리적인 선택일 것 같다.

Q5. Hydration 과정에서 사용자가 느낄 수 있는 UX 이슈는 무엇이고, 어떻게 개선할 수 있을까요?

layout shift가 발생할 수 있을 것 같다. 서버나 클라이언트나 동일한 데이터로 동일하게 UI를 그려야만 개선할 수 있을 것 같다.

Q6. 이번 과제에서 학습한 내용을 실제 프로덕션 환경에 적용할 때 추가로 고려해야 할 사항은?

SSG 할 수 있는 페이지들을 체크해뒀다가 미리미리 빌드해서 서버의 성능을 아낄 수 있지 않을까 싶다.

Q7. Next.js 같은 프레임워크 대신 직접 구현한 SSR/SSG의 장단점은 무엇인가요?

일단 학습에 도움이 되었고 (평소에 별 생각없이 여겼던 것을 딥다이브해보는 좋은 기회가 되었다..)
이렇게 직접 구현을 해서 쓴다면 모든 걸 제공하는 프레임워크만큼 무겁지는 않을 것 같다. 필요한 것만 구현하면 돼서 가볍게 돌려볼 수 있을 것 같다.
반대로 프레임워크가 제공해주는 안정성을 확보하지는 못할 것 같다.

Q8. Next.js 를 이용하여 SSG 방식으로 배포하려면 어떻게 해야 좋을까요?

SSG로 빌드한 내용은 서버가 필요없으므로 정적 호스팅 환경(gh-pages나 S3 같은 곳) 만으로도 충분히 배포할 수 있을거라 생각한다.

코드 품질 향상

자랑하고 싶은 구현

export const useProductUseCase = () => {
  const router = useRouterContext();

  return {
    loadProductsAndCategories: () => loadProductsAndCategories(router),
    loadProducts: (resetList = true) => loadProducts(resetList, router.query),
    loadMoreProducts: () => loadMoreProducts(router),
    searchProducts: (search: string) => searchProducts(search, router),
    setCategory: (categoryData: StringRecord) => setCategory(categoryData, router),
    setSort: (sort: string) => setSort(sort, router),
    setLimit: (limit: number) => setLimit(limit, router),
    loadNextProducts: () => loadNextProducts(router),
  } as const;
};

구현을 하다보니 원래 구조에서 router가 추가적인 인자로 하나씩 추가되게 되었는데
원래는 이걸 props drilling처럼 해결을 하다가 위 형태로 리팩토링 하였다.
그래서 router가 인자로 하나씩 추가되었더라도 함수를 실행하는 데에는 변함이 없도록 하여 코드의 변화가 적도록 한 게 좋았다.

개선하고 싶은 부분

prefetch 데이터 함수가 home 화면에 필요한 데이터랑 상세 화면에 필요한 데이터를 모두 담당하고 있는 것을 좀 개선하면 좋을 것 같다

리팩토링 계획

작업을 하다보니 모든 파일을 ts로 작성하지는 못했는데 리팩토링을 하게 된다면 일단 이를 전부 ts로 바꿔서 타입 안정성을 강화하고 싶다.

학습 연계

다음 학습 목표

어떤 변수가 싱글톤으로 사용되는 게 서버 환경에서 어떤 의미인지 알게 되었는데 이런게 쓰이는 라이브러리들이 뭐가 있는지랑 이렇게 쓰는 게 많은지? 궁금하다.

실무 적용 계획

SSG를 쓸 수 있는 페이지를 찾아내서 적용해보려고 할 것 같다.

리뷰 받고 싶은 내용

Router를 매번 새롭게 생성하려고 Context를 사용했는데 더 좋은 방법이 있을까요?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant