3P by GN⁺ 1일전 | ★ favorite | 댓글 1개
  • Hardcover 팀은 Next.js 기반 구조의 성능 저하, 높은 비용, 개발 속도 저하 문제로 인해 Ruby on Rails + Inertia.js로 마이그레이션함
  • SEO가 가능한 SSR 지원, 직접 DB 연결, React 유지라는 요건을 만족하기 위해 Inertia.js를 선택
  • Vercel 및 Cloud Run에서의 예상치 못한 요금 폭증Next.js의 캐싱 불확실성이 결정적인 전환 계기였음
  • Inertia.js는 Rails 백엔드와 React 프론트엔드를 연결하는 이상적인 방식으로, SSR과 캐시 관리가 쉬워짐
  • 전환 이후 Google Pagespeed와 SEO 점수가 향상되며 사이트 방문 시간과 검색 노출이 증가

전환 배경

  • 초기에는 SEO와 SSR 지원이 가능한 Next.js를 선택하여 GraphQL API 기반의 아키텍처로 구축함
  • 대부분의 데이터는 브라우저에서 클라이언트 측으로 요청하되, 정적 데이터는 서버에서 캐싱
  • 시간이 지날수록 캐싱 부재로 API 요청 증가, 성능 저하 및 개발 환경 속도 저하 발생

Next.js에서 발생한 문제들

  • App Router 전환 후에도 속도 향상 미미, Apollo POST 요청은 캐싱되지 않아 예상한 효과 없음
  • Vercel 가격 정책 변경으로 월 요금이 $30 → $354로 급증함
  • Cloud Run도 초기엔 저렴했지만, $524까지 증가
  • Next.js 캐싱 구조 파악이 어려워, 효율적 관리 불가
  • 개발 속도는 현저히 느려져 신규 인원 온보딩에 어려움 초래

Rails + Inertia.js 선택 이유

  • SSR을 유지하면서 직접 DB에서 데이터 가져오기 원함
  • React를 계속 사용하고 싶었고, Remix, react-rails, react_on_rails도 검토했지만 최종적으로 inertia-rails 채택
  • Inertia.js는 프론트엔드 라우팅 없이 Rails 라우팅 사용 가능, SSR도 수월함
  • 컨트롤러에서 inertia: '페이지명'으로 렌더링 처리하고, 캐싱은 Rails.cache.fetch로 구현
  • React 컴포넌트에서 usePage()로 props 수신

SSR 및 빌드 구조

  • SSR을 위해 application.tsx에서 hydrateRoot / createRoot 분기 처리
  • Vite를 독립 서버로 운영하며 개발 중 핫리로드 지원
  • Docker와 Kamal을 통한 Rails + Vite 배포 자동화, staging과 production 구분
  • 배포 시 make deploy 명령어로 실행, asset host는 CloudFlare로 캐시 최적화

전환 효과

  • 2025년 3월 18일 마이그레이션 배포 후 Google 검색 노출 증가, 페이지 속도 향상
  • Total Blocking Time이 대폭 개선되며, Pagespeed 점수 상승
  • 방문자 평균 체류 시간 3분 → 6분으로 상승 추세
  • 트래픽은 유지되면서 회원 가입 수는 안정적으로 유지

향후 과제 및 개선점

  • 공통 레이아웃 재사용 어려움, 각 페이지 완전 재렌더링 문제 존재
  • SSR 디버깅 어려움, 환경 세팅이 복잡
  • Inertia.js와 Rails 조합에 대한 문서 부족, Discord 커뮤니티를 통해 해결
  • Suspense 대신 Inertia 방식에 적응 필요
  • 현재는 Hasura를 계속 사용 중으로, Inertia의 form, flash 등 일부 기능은 미활용

결론 및 기대

  • React + Rails를 자연스럽게 통합한 구조로 개발 생산성과 유지보수성 향상
  • Inertia.js의 선택으로 속도, SSR, 타입 안정성을 동시에 확보함
  • 앞으로 오픈소스화 및 기여자 확보를 계획 중
Hacker News 의견
  • 서버 사이드 렌더링(SSR)은 사라진 적이 없으며, 웹은 이제야 그것이 기본이었던 이유를 기억하고 있음. 첫 번째 렌더링과 SEO는 여전히 서버에서 마크업이 올 때 더 좋음. Rails + Turbo, HTMX, Phoenix LiveView, React Server Components 같은 다양한 프레임워크가 SSR을 기본으로 삼고 있음. 대부분의 대시보드와 CRUD 앱은 클라이언트 라우터, 글로벌 상태, 200kB 하이드레이션 번들이 필요 없으며, 단지 부분적인 HTML 교체만 필요함

    • 진정한 원동력은 복잡성 비용임. 클라이언트 JS의 모든 라인은 빌드 도구, npm 감사 소음, 공급망 위험을 가져옴. 이 페이로드를 줄이면 성능과 보안이 동시에 개선됨. 물론 Figma나 Gmail 같은 앱은 여전히 무거운 클라이언트 로직의 이점을 얻음. 따라서 "기본적으로 HTML, JS는 필요한 곳에만"이라는 패턴이 나타나고 있음. 전체 SPA가 아닌 섬을 생각해야 함

    • 따라서 서버로의 회귀가 진행되고 있지만, 이는 2004년 PHP에 대한 향수가 아님. JavaScript를 적절히 조정하고 HTML이 항상 잘했던 90%의 지루한 작업을 하도록 하는 것임

  • 우리는 NextJS를 몇 가지 프로젝트에서 사용했지만 이미 이를 단계적으로 중단하고 있음. 이유는 여러 가지가 있지만, 몇 가지 주요 요인은 다음과 같음

    • 인증 스토리가 어려움. next-auth는 몇 가지 제한이 있어 iron-session을 사용하게 되었음. 예를 들어, 동적 ID 제공자 도메인을 사용할 수 없어서 전체 openid 흐름을 소유해야 했음. 이는 가능하지만 성숙한 프레임워크에서 예상치 못한 시간 소모였음

    • NextJS 서버가 우리의 주요 API 게이트웨이가 아니었기 때문에 모든 요청을 프록시해야 했음. 문서가 명확하지 않았고, 요청 시간 초과/최대 헤더 크기 등과 같은 무작위 문제를 추가했음

    • 프레임워크는 클라우드로의 전환을 매우 적극적으로 유도하며, 이는 우리의 목표와 상충되었음

    • 유지보수자들이 특히 도움이 되지 않았음. 다른 도구/프레임워크는 결함에도 불구하고 유지보수자들이 매우 접근 가능하고 도움이 되기 때문에 사용함 (Chillicream/HotChocolate에 감사)

  • 작년에 Next.js의 페이지 라우터에서 앱 라우터로 이동하면서 SEO가 개선되었다는 블로그 글을 읽은 기억이 있음. 이번에는 Vercel의 비용 증가로 인해 Next에서 React+Inertia.js로 이동하고 있음. 동일한 앱을 클라우드 제공자 대신 자체 VPS에 배포하면 문제가 해결될 것임. 그러나 복잡성을 원하는 이유는 이해하지 못함. 책 추적 앱이 정말로 GraphQL, 별도의 프론트엔드 프레임워크 및 복잡한 빌드 프로세스가 필요한지, 아니면 처음부터 VPS에 HTML 템플릿으로 단일 RoR 앱을 배포함으로써 해결될 수 있었는지 궁금함

  • 웹과 스택에 대한 기사와 토론을 볼 때마다 "실제로 어떤 문제를 해결하고 있는가"라는 질문을 던지게 됨. 답은 항상 "화면에 텍스트를 표시"임

    • 비즈니스 목표가 "화면에 텍스트를 표시"하는 것이라면, 다음 논리적 단계는 기술 스택이 얼마나 많은 시간과 비용을 절약하는지를 묻는 것임. 이 질문에 숫자로 답하는 개발자를 본 적이 없음. 이는 정말 큰 문제임
  • JS 풀 스택을 원할 때 특히 DB가 포함된 경우 사람들은 무엇을 하는지 궁금함. ORM 상황은 상당히 분열되어 있거나 순수 SQL을 작성해야 함. 그리고 여전히 백엔드를 결정해야 함. express를 사용할 것인가? Next.js는 잘 알려져 있지만 의문스러운 의제를 가지고 있음. Remix, Astro, TanStack 등. 항상 무엇을 사용할지 재조정하고 재평가해야 하기 때문에 혼란스러움

    • 개인 프로젝트에서는 Ruby on Rails로 돌아가는 경우가 많음. 항상 즐거움. 반면에, 사용 가능한 Rails 개발자가 너무 적어서(비교적 JS에 비해) 전문 프로젝트에는 적합하지 않음. JS와 종종 Java를 백엔드로 선택하는 것이 무책임함

    • 비슷한 감정을 가진 사람이 있는지 궁금함

  • 프론트엔드와 백엔드 개발자는 오랫동안 대화가 잘 되지 않았음

    • 역사적으로 백엔드 개발자로서 Html/JS/CSS를 싫어했음. Swing/Awt, WinForms, Android UX 등과는 의미 있는 다른 패러다임임. 그것만으로도 나를 좌절시키고 백엔드에 머물게 했음. 프론트엔드를 배우기 위해서는 이 세 가지를 배워야 했음. 이제야 익숙해지고 있음

    • 그러나 프론트엔드 개발자들은 "또 다른 언어"를 배워야 했음. 많은 언어들이 nvm과 비교하여 다른/성가신 빌드 시스템을 가지고 있음. 그리고 언어를 바꾼 사람이라면 누구나 알듯이, 새로운 프레임워크, 패러다임 등을 배워야 했음

    • 대신 일부는 JavaScript를 백엔드로 밀어낼 수 있다는 것을 깨달았음. 많은 단점이 있었지만, "일을 끝내는" 사람들, 특히 "서버를 더 추가하라"와 "VC 자금은 공짜다! 인프라에 태워라!"라는 세계에서는 이러한 단점이 걱정할 만한 것이 아니었음

    • 그러나 프론트엔드 개발자들, 이제는 "풀 스택 개발자"지만 실제로는 "모든 것을 JavaScript로" 개발자들은 계속해서 눈에 띄는 방식으로 창작함. 이는 현재 LinkedIn 구인 공고에 반영되어 있으며, Next.JS/Node.JS/기타 역할을 요구함. 모든 것을 지배하는 하나의 언어임

    • 몇 가지 생각이지만, 사람들이 Next.JS를 선택하는 이유와 강하게 관련이 있다고 생각함

  • 기술적인 측면에 대해서는 말할 수 없음 (Next.js에만 익숙하고 Rails는 익숙하지 않아서, 이 글이 저자의 Rails에 대한 편안함을 반영한 것인지, 더 기술적으로 적합한 아키텍처를 반영한 것인지 불분명함). 그러나 여러 소프트웨어 엔지니어가 있는 회사가 월 1,000달러 미만의 인프라 비용을 걱정하는 것이 이상하다고 생각함. 호스팅 비용을 걱정하는 것은 현명하지 않음

  • Rails가 가져온 프론트엔드 프레임워크와의 상호 운용성에 대한 진정한 1차 지원에 집중했다면 지금쯤 훨씬 더 커졌을 것임. Hotwire에 많은 노력을 기울였지만, 나는 React를 사용하고 싶고, 다른 사람들도 자신이 익숙한 것을 사용하고 싶어할 것임

  • Next.js vs. SSR에 대한 논쟁이 왜 있는지 궁금함. Next.js는 하이브리드이며 꽤 잘 수행됨. 다른 SPA 프레임워크와 대조적으로, Next.js는 빠른 첫 로드를 위한 사전 렌더링된 HTML 출력을 생성하고, 효율적인 JS 청크, 링크 위에 마우스를 올리거나 페이지 렌더링 후 모든 n+1 링크를 미리 로드하는 등의 설정 스위치를 제공하며, 브레이크포인트에 따라 효율적인 이미지 (사전) 로딩을 제공함 (순수 SSR 솔루션과 비교할 때 보통 아킬레스건임)

    • 기본 설정을 사용하는 Next.js 앱과 Rails 등의 실제 성능 지표를 비교하는 것에 관심이 있음
  • Rails를 조금 작성해봤지만, 왜 그렇게 열광하는지 잘 이해하지 못함. 완벽하게 괜찮았지만 특별한 점은 찾지 못했음

    • Python 서비스에서 심각한 확장 문제를 겪은 후, 이제는 서버를 Go나 Rust로만 작성하고 싶음. 조금 더 어렵지만 성장할 수 있는 것을 얻을 수 있음