React 태그의 최신글

프론트엔드

Next.js 마이그레이션: 서버 컴포넌트(SSC)와 클라이언트 컴포넌트(CSC) 선택하기

React 프로젝트를 리팩토링 하면서 Next.js로 마이그레이션을 하게 되었고, 처음으로 서버 사이드 컴포넌트(Server-side Component, SSC) 를 사용할 기회를 갖게 되었다. 기존 React에서는 React Query를 활용하여 서버의 부담을 줄이며 데이터를 관리해왔는데, Next.js에서도 기존처럼 React Query를 사용할 수 있을지 고민하게 되었다. SSC와 CSC의 차이 Next.js의 서버 컴포넌트(SSC) 와 클라이언트 컴포넌트(CSC) 는 동작 방식이 다르다. SSC(Server-side Component): 서버에서 데이터를 가져와 미리 렌더링하여 클라이언트에 전달함 → SEO 최적화 CSC(Client-side Component): 클라이언트에서 데이터를 가져오고, 동적으로 업데이트함 → 실시간 변화 가능 이전처럼 React Query를 사용하여 데이터를 가져오려 했지만, 만약 모든 데이터를 클라이언트에서 가져온다면 Next.js의 서버 렌더링 기능을 제대로 활용하지 못하게 된다. Next.js를 사용하면서 서버의 역할을 최대한 활용해야 한다는 점에서 React Query만을 사용할 수는 없었다. 서버 부담 문제와 캐싱 처음에는 페이지를 이동할 때마다 서버가 데이터를 불러오면 부담이 커질 것이라고 생각했다. 하지만 Next.js에서는 서버에서 데이터를 가져올 때 캐싱을 통해 성능을 최적화할 수 있는 방법이 있었다. 위와 같이 revalidate: 60을 설정하면 60초 동안 같은 요청을 반복하지 않고 캐싱된 데이터를 반환한다. 덕분에 SEO를 챙기면서도 서버의 부담을 줄일 수 있다. 어떤 데이터는 SSC, 어떤 데이터는 CSC로? 처음에는 서버와 직접적인 연관이 있는 것은 SSC로, 정적인 것은 CSC로 사용해야 한다고 생각했는데, 사실은 그 반대였다. ✔️ 서버 컴포넌트(SSC)를 사용해야 하는 경우 SEO가 중요한 데이터 (검색 엔진 노출 필요) 초기 렌더링이 빠른 것이 중요한 데이터 변경이 자주 일어나지 않는 데이터 페이지 구조를 구성하는 주요 데이터 ✅ 예시 블로그 글 목록 (게시글 리스트) 블로그 글 내용 (제목, 본문) 사용자 프로필 정보 (변경이 잦지 않은 경우) 카테고리 목록 ✔️ 클라이언트 컴포넌트(CSC)를 사용해야 하는 경우 실시간으로 변화하는 데이터 사용자와의 인터랙션이 필요한 데이터 페이지 내에서 상태 변화가 필요한 데이터 ✅ 예시 좋아요 개수, 댓글 검색 기능 (검색어 입력 시마다 데이터 변경) 무한 스크롤 (React Query의 useInfiniteQuery 활용) 사용자 설정 변경 결론: SSC와 CSC의 최적 조합 초기 데이터를 서버에서 받아와 렌더링해야 하는 경우 → SSC 사용 자주 변경되거나 사용자 인터랙션이 필요한 경우 → CSC + React Query 사용 서버 부담을 줄이기 위해 revalidate 로 캐싱 활용 Next.js 마이그레이션을 하면서 서버 컴포넌트와 클라이언트 컴포넌트를 적절히 나누는 것이 성능 최적화에 매우 중요하다는 것을 깨달았다. SEO가 필요한 데이터는 서버에서 미리 받아오고, 실시간 업데이트가 필요한 데이터는 클라이언트에서 관리하는 것이 핵심이다. 이를 잘 활용하면 서버 부담을 줄이면서도 빠른 렌더링을 유지할 수 있다.

2025년 03월 19일 08:12

프론트엔드

스파게티 코드 갱생시키기 프로젝트

🔴 개관 저는 프로그래밍을 할 때 단순히 돌아가기만 하면 된다는 접근보다, 가독성과 코드의 효율성을 더욱 중요하게 여깁니다. 처음 React Native로 프로젝트를 진행했을 때, React와 달리 데이터를 저장하고 사용하기 위해 복잡한 코드를 작성해야 했던 경험이 있습니다. 당시에는 효율성보다는 기능 구현에 초점을 맞췄기 때문에 코드가 비효율적이었습니다. 초보자라면 누구나 겪을 문제라고 생각합니다. 그러나 이번에 React Native로 두 번째 프로젝트를 진행하며, 비효율적인 AsyncStorage의 저장 및 조회 코드를 모듈화하여 재사용성과 유지보수성을 높이겠다고 계획했습니다. 🔴 첫 번째 React Native 프로젝트: 완전한 스파게티 코드 오랜만에 캡스톤에서 진행했던 프로젝트의 코드를 꺼내보았습니다. React Native를 처음 사용해보는거라서 아주 스파게티 코드입니다. 지금 생각하면 아주 끔찍한 코드입니다. 서버에서 오는 응답에 따른 두번의 Alert 코드와 그 Alert을 감싸고있는 AsyncStorage 함수의 모습입니다.... 초반에는 기능 구현에만 집중했기 때문에 비효율적인 코드가 발생하였습니다. 저는 여기서 Alert나 AsyncStorage에 대한 모듈화가 필요하다고 생각하였지만 기간이 빡빡하기도 하였고, 저의 실력 문제;;로 진행하지는 못하였습니다. 🔴 두번째 React Native 프로젝트: 코드 모듈화 사실 첫번째 어플리케이션을 리팩토링하자! 하는 마음이 지금도 남아있지만.... AI 서버와 백엔드 서버가 다 내려갔기 때문에 리팩토링, 유지보수 한다고 해도 돌아간다는 보장이 없습니다. 모듈화의 기회는 두번째 프로젝트에서 달성할 수 있었습니다. 저는 제일 문제된다고 생각한 것이 AsyncStorage 함수와 Alert 함수라고 생각했습니다. 그래서 프로젝트에 Utils 폴더를 만들어 전역적으로 이 함수들을 관리하기로 결심했습니다. Alert 컴포넌트 코드를 먼저 보여드리겠습니다. 확인 버튼이 있는 알림창과 확인, 취소 버튼이 있는 알림창 컴포넌트를 만들었습니다. 두 파일로 나눠서 만들까 하다가 Utils/component 폴더 내부에 또 Alert 폴더를 만들기 싫어서 한 파일만 임포트하면 두 Alert 컴포넌트 접근 가능해서 위의 이유로 한 파일에 합쳐 작성했습니다. 아래 코드는 위 컴포넌트 사용 예시입니다. 치매 진단지를 서버로 제출하는 함수인데, 서버에서 오는 응답 코드에 따라 다른 Alert 컴포넌트를 띄우거나 탭을 이동하는 코드입니다. 물론! 저 함수에 title, message, onPress 세 개의 파라미터가 들어가기 때문에 모듈화를 시켜 사용한다고 해도 여전히 코드가 어지럽고 길긴 합니다. ~~하지만 제 실력으로는 최선이었습니다.~~ 하지만 모듈화를 안하고 사용했다면? 진짜 아찔합니다. 다음으로는 절 힘들게했던 AsyncStorage 함수입니다. React와는 다르게 ReactNative에서는 async가 필요해서 코드가 굉장히 복잡해졌습니다. 여기서 흠은 console을 띄웠다는 점인데요.. 다음은 에러가 나온다고 하면 Alert창을 띄우거나.. 다시 시도하거나 하는 방식을 해봐야겠습니다. Storage 싱글톤 객체를 만들어서 내부에 네가지 메서드를 넣었습니다. 한창 정보처리기사 공부할때 디자인패턴이 나오길래 신나했던 기억이 납니다.. 주로 사용했던 메서드는 setItem과 getItem 입니다. 위에는 아까 봤던 Alert 컴포넌트와 Storage 의 setItem 메서드가 결합된 코드입니다. 엄청 깨끗해지고 가독성도 좋아졌습니다. (맞나..?) 🔴 결론 저는 캡스톤에서 처음으로 React Native를 사용해봤습니다. 기간이 부족했기 떄문에 몸통박치기 수준이 아니고 몸통 갈아넣기 정도로 일단 써보자 마인드였는데요 만약에 프론트가 저 혼자가 아니고 여러명이서 진행했다면 프론트끼리 머리채잡고 싸웠을수도 있습니다. 이런 스파게티 코드는 물론 개발 진행에 있어서 굉장히 불가피하다고 생각합니다. 하지만 계속해서 코드를 리팩토링하고 유지보수한다면 전보다는 실력이 10%정도.. 아님 1%라도 성장하는 것 같습니다. 요즘 저는 리팩토링을 진행했다고는 하지만 지금보면 발싸개같은 코드를 다시 보면서.. React 디자인패턴 공부에 박차를 가해야겠다는 생각이 듭니다.... 저의 시행착오가 여러분들에게 도움이 되셨으면 좋겠습니다.

2024년 10월 23일 08:15