[문득 떠오른 건데] 밥먹고 졸릴때 리팩토링 요소를 탐색하면 잠이 깰까? - 2편
2023 Series
1편에서는 무슨 일이 있었을까?
일찍 학교에 와서 아침을 먹으며 여러 생각을 했다.
맛있는 샐러드와 주먹밥을 먹으며 "동적 컴포넌트를 만들면 잠이 깰까?"라는 의문이 떠올랐다.
그래서 동적 컴포넌트와 정적 컴포넌트의 차이에 대해 생각해 보았고, 리액트에서도
동적인 사이트와 정적인 사이트가 있다는 것을 알게 되었다.
내가 이것에 대해 깊이 생각하게 된 이유는, 졸릴 때 만들어 보는 동적 컴포넌트와 정적 컴포넌트가
어떤 차이가 있는지 궁금했기 때문이었다. 또한, 나는 이것을 직접 만들어 보고 싶은 욕구가 생겼다.
그래서 지금 바로 결심하고 실행해보기로 했다. 이 글을 쓰면서도 그렇게 다짐했다.
앞으로는 동적 컴포넌트와 정적 컴포넌트를 만들어 보면서, 그 결과를 확인해보려고 한다.
이번에는 나의 또 다른 성장의 기회가 될 것 같았다.
아직 1편을 못봤다면??
그렇다면 이번 편에서는 어떤 일이 벌어질까?
이번 편에서는 이전에 만들어 두었던 코드를 보고 리팩토링 할 요소들을 모아 말 그대로
리팩토링을 할 예정이다
아마 이걸 진행하면 실제로 지금 진행 중인 프로젝트에서도 도움이 되지 않을까 싶다
하지만 예상치 못한 문제로 인해 리팩토링은 진행되지 못하는데...
지난 편에서는 "2. 밥을 먹고 동적 컴포넌트 만들어보기"까지 진행했으니 이번 편에서는 3번부터 이어가도록 하겠다
3. 밥을 먹고 커피를 마셔보기(리팩토링 요소 탐색)
커피를 마시면서 생각을 해 보았다. next.js 가 버전이 상승함에 따라 프로젝트 생성 시 만들어지던 디렉터리가
app 디렉터리에서 pages 디렉터리로 변화된 부분이 있었다
그렇게 바뀌면서 각 컴포넌트 별 CSR(클라이언트 사이드 렌더링)에서 페이지 별 SSR(서버 사이드 렌더링)으로 바뀐 점이 눈에 들어왔다
이왕 이렇게 마무리하기 전에 동적인 컴포넌트에는 CSR 적용을 해두는 것이 좋지 않을까?라는 생각을 했다
그렇다면 왜 동적인 컴포넌트에는 SSR이 좋지 않을까?
이 부분에 대해 알아보기 전에 서버 사이드 렌더링과 클라이언트 사이드 렌더링에 대해 알아보아야 하는 부분이 있다
SSR, CSR, ISR의 차이점
- SSR (서버 사이드 렌더링): 서버 사이드 렌더링은 페이지를 서버에서 렌더링 하여 완성된 HTML 파일을 클라이언트에게 전달하는 방식이다. 이 방식은 초기 로딩 속도가 빠르고 SEO (검색 엔진 최적화)에 유리한 편이다. 그러나 사용자와 상호작용이 많은 경우 서버에 부하가 발생할 수 있다.
- CSR (클라이언트 사이드 렌더링): 클라이언트 사이드 렌더링은 서버에서 데이터만 전달받아 클라이언트에서 HTML 파일을 렌더링 하는 방식이다. 이 방식은 서버 부하를 줄일 수 있으며, 상호작용이 많은 웹사이트에 적합하다. 그러나 초기 로딩 속도가 SSR보다 느리며, SEO에 불리할 수 있다.
- ISR (증분 정적 재생성): ISR은 Next.js와 같은 프레임워크에서 제공되는 기능으로, 정적 페이지를 생성하면서 데이터가 변경될 때 일부 페이지만 재생성하는 방식이다. 이 방식은 정적 페이지와 동적 페이지의 장점을 모두 갖추어 속도와 SEO에 유리하며, 서버 부하도 줄일 수 있다.
정적 페이지와 동적 페이지가 섞여 있는 경우, 서버 사이드 렌더링과 클라이언트 사이드 렌더링을 적절히 조합해 사용할 수 있다.
예를 들어, 정적 페이지는 SSR로 렌더링 하고, 동적 페이지는 CSR로 렌더링 하여 최적의 성능을 달성할 수 있다.
적절한 렌더링 방식을 고르지 못하면?
- 성능 저하: 잘못된 렌더링 방식을 사용하면 페이지 로딩 속도가 느려질 수 있으며, 사용자 경험을 저하시킬 수 있다.
- SEO 문제: 검색 엔진이 페이지를 제대로 크롤링하지 못해 검색 결과 순위에 영향을 미칠 수 있다.
- 서버 부하: 서버에 과도한 부하가 발생하여 웹사이트의 안정성이 떨어질 수 있다.
그래서 주로 프로젝트에서 리팩토링 소재로 많이 선택하고는 하는 그러한 주제들이고,
나는 이것을 이 간단한 프로젝트에 적용시켜보고자 한다(우와! 이렇게 빠른 리팩토링이라니!)
추가적으로 코드를 보며 발견한 주관적인 문제점들로는 아래와 같은 항목들이 있었다
리팩토링 요소들 전체 모아 보기
1. 화면 렌더링 관련 렌더링 찾기
2. 네이밍 관련 개선점 찾기
3. 코드 로직 관련 개선점 찾기
4. 함수 모듈화하기
5. 이미지 최적화
6. 파일 및 폴더 구조 개선
7. TypeScript 타입 지정하기
8. 디자인 개선
이 항목들을 우선순위에 맞게 나열해 보자면 아래와 같이 정렬된다
- 파일 및 폴더 구조 개선: 프로젝트의 전반적인 구조를 먼저 개선하여 리팩토링을 쉽게 진행할 수 있는 기반을 마련
- TypeScript 타입 지정하기: 코드의 안정성과 가독성을 높이기 위해 타입 정의를 추가
- 모든 코드에 타입이 지정되어 있는 상태가 아니기에 말 그대로 모든 코드에 타입을 붙여 볼 생각이다
- 함수 모듈화하기: 코드의 재사용성과 가독성을 높이기 위해 함수를 작은 모듈로 분리
- 이번 글에서는 작성해 둔 모든 함수들을 분리해 볼 생각이다. 추후에 변화가 필요하다면 변경할 것이다
- 코드 로직 관련 개선점 찾기: 코드의 복잡성을 줄이고, 성능을 개선하기 위해 로직을 개선
- 여러 디자인 패턴들이 있다. 필요에 의해 이 디자인 패턴을 적용해보고자 한다
- 화면 렌더링 관련 렌더링 찾기: 불필요한 렌더링을 최소화하고, 성능을 개선하기 위해 렌더링 최적화를 진행
- 이미지 최적화: 웹 애플리케이션의 성능을 향상하기 위해 이미지를 최적화
- Next.js에는 이미지와 관련된 강력한 기능이 있다. 이를 모든 이미지에 적용시켜보려고 한다
- 네이밍 관련 개선점 찾기: 코드의 가독성을 높이기 위해 변수, 함수, 컴포넌트 등의 이름을 명확하고 직관적으로 변경
- 특히 지금 프로젝트에서는 이름을 막 지은 그러한 느낌이 있다 클린코드의 한 방법 중에 네이밍이 있다고 하는데, 그 부분에 대해 개선해 보도록 하겠다
- 디자인 개선 : 모든 일이 끝나면 사이트를 예쁘게 다듬어보자!
4. 리팩토링 작업하기(0. 템플릿 탐색, 적용하기)
잠깐! 들어가기 전에 가장 중요한 작업 하나가 있다
바로 브랜치를 나누어서 작업을 하는 것이다
그렇다면 왜 브랜치를 사용해서 관리해야 하는 걸까?
브랜치를 사용하면 코드를 안전하게 관리할 수 있고, 협업을 용이하게 할 수 있다
- 병렬 작업
- 브랜치를 사용하면 여러 개발자들이 동시에 작업할 수 있습니다. 각 브랜치에서는 독립적으로 코드를 수정하고, 나중에 main 브랜치에 병합할 수 있다
- 이로 인해 개발 프로세스가 원활하게 진행된다
- 기능별 개발
- 브랜치를 통해 각 기능별로 독립적인 작업 공간을 생성할 수 있다
- 이렇게 하면 여러 기능을 동시에 개발하면서도 코드 충돌을 최소화할 수 있다
- 안전한 코드 관리
- 브랜치를 사용하면 실험적인 변경사항이나 개발 중인 기능을 main 브랜치와 분리하여 작업할 수 있다
- 이렇게 하면 안정적인 버전의 코드를 유지할 수 있으며, 실수로 버그가 포함된 코드를 배포하는 일을 줄일 수 있다
- 코드 리뷰
- 브랜치를 사용하면 다른 팀원들에게 코드 리뷰를 요청할 수 있다
- 이를 통해 코드의 품질을 높이고, 일관성을 유지하며, 버그를 찾아내고 수정할 수 있다
- 버전 관리
- 브랜치를 사용하면 프로젝트의 여러 버전을 관리할 수 있다
- 예를 들어, 이전 버전의 코드를 유지하면서 새로운 기능을 추가하는 데 사용할 수 있다
그러한 이유들로 인해 main 브랜치에서 개발을 할 develop 브랜치를 만들어 작업을 시작하고 버전이 완성될 때만 merge 할 예정이다
그 후 이슈를 생성하고 각 이슈 별 브랜치를 develop에서 분화하여 특정 규칙에 맞게 적용시키는 것을 해 볼 예정이다
내가 사용할 Branch Naming Convention은 다음 글에서 나온 대로 진행하도록 하겠다
브랜치를 분화했으니 이제 해야 할 것이 무엇이 있느냐, 바로 이슈를 만드는 것이다
이슈 템플릿 또한 미리 만들어 둔 것을 사용하도록 하겠다
그럼 이제 이 이슈 템플릿을 적용시켜 보도록 하겠다
Repository Setting -> Features -> Set up templates 클릭
Add template -> Custom template 클릭
위에 올려두었던 링크에서 내용 옮겨놓고 저장하면 이런 식으로 된다
리팩토링 작업하기(1. 파일 및 폴더 구조 개선)
현재 /src 디렉터리의 폴더구조를 뽑아내기 위해 다음과 같은 Extensions를 사용했다
개선하기 전 폴더구조
src
┣ images
┃ ┗ Logo.png
┣ pages
┃ ┣ api
┃ ┃ ┣ hello.ts
┃ ┃ ┗ search.ts
┃ ┣ components
┃ ┃ ┣ Header.tsx
┃ ┃ ┣ Search.tsx
┃ ┃ ┗ ShortWriting.tsx
┃ ┣ data
┃ ┃ ┗ searchData.ts
┃ ┣ _app.tsx
┃ ┣ _document.tsx
┃ ┗ index.tsx
┗ styles
┃ ┣ Header.module.css
┃ ┣ Home.module.css
┃ ┣ ShortWriting.module.css
┃ ┗ globals.css
개선 이후의 폴더구조
src
┣ assets
┃ ┗ images
┃ ┃ ┗ Logo.png
┣ components
┃ ┣ Header
┃ ┃ ┣ Header.module.css
┃ ┃ ┗ Header.tsx
┃ ┣ Search
┃ ┃ ┣ Search.module.css
┃ ┃ ┗ Search.tsx
┃ ┗ ShortWriting
┃ ┃ ┣ ShortWriting.module.css
┃ ┃ ┗ ShortWriting.tsx
┣ pages
┃ ┣ HomePage
┃ ┃ ┣ HomePage.module.css
┃ ┃ ┗ index.tsx
┃ ┣ SearchPage
┃ ┃ ┣ SearchPage.module.css
┃ ┃ ┗ index.tsx
┃ ┣ _app.tsx
┃ ┣ _document.tsx
┣ services
┃ ┣ api
┃ ┃ ┗ search.ts
┃ ┗ searchData.ts
┗ styles
┃ ┗ globals.css
무엇이 바뀌었을까?
- 각 페이지에 대한 컴포넌트가 별도의 폴더로 분리되어 관리가 용이해졌다.
- 각 페이지에 대한 스타일 파일도 별도의 폴더로 분리되어 관리가 용이해졌다.
- 공통 컴포넌트와 페이지 컴포넌트의 구분이 명확해졌다.
- 서비스와 API 관련 파일이 'services' 폴더에 모아져 있어 관리가 쉬워졌다.
- 기존 Search.tsx는 컴포넌트가 아닌 페이지이므로 SearchPage.tsx로 이름을 변경하고 내부의 기존 Search Logic들을 컴포넌트로 분리했다.
폴더 구조를 변경하다가 생긴 일들
- Next.js의 페이지 이동의 특징은 pages 내의 어떤 경로이던 파일 이름만 적어도 작동된다.
- <Link href={`/Search`}>검색 페이지로 이동 </Link>
- <Link href={`/SearchPage/Search`}>검색 페이지로 이동 </Link>
- <Link href={`SearchPage/SearchPage2/Search`}>검색 페이지로 이동 </Link>
- 1번, 2번, 3번의 폴더구조를 가지고 있다고 할 때 1번으로 코드를 작성해도 페이지 이동이 이루어졌다
- 즉, pages 내의 폴더 구조를 변경하더라도 href 내에는 파일 이름만 들어가 있으면 된다고 생각하면 된다
그래서 리팩토링 결과물은 어디 있죠?
리팩토링을 하기 이전에 프로젝트 초기 세팅에 대해 어느 정도 기반을 마련해두려고 했는데
생각보다 많은 시간을 잡아먹어 지연되고 있다. 특히 오류가 생겨 이를 해결하는데
+ 작업할 때 현재 브랜치가 무엇인 지 주의해 주세요
실제로 작업을 할 때 develop 브랜치가 아닌 main 브랜치에 작업을 하고 커밋을 누르자
의도치 않게 마법처럼 작업내역이 날아갔다. 심지어 로컬 디렉터리도 날아갔다...
결국 지금은 깃허브에서 다시 클론을 받아 작업을 다시 해야 하는 상황이다
결국 오류 해결에 진이 빠져버린 나는 글의 흐름을 위해 다음으로 넘겨볼까 한다
이번에는 잠 깨셨나요??
그렇죠. 특히 오류가 생겼을 때 오던 잠도 모두 달아나 버렸답니다.
평화롭게 작업을 하고 지식을 탐색하다가 내적 "어?"를 외치는 순간 내 안에 있던 졸림이 모두 사라졌다.
오류가 생기는 게 좋은 일은 아니지만 그래도 잠이 깼다는 건 좋은 일 같다.
물론 팀 프로젝트였다면 자던 팀원도 깨웠을 것이다.
최근 회고에 대한 대대적인 피드백을 통해 기존에 작성해 오던 정기적인 글에는 많은 의미가 없다는 것을 깨달았다
이후의 글은 기술적으로, 개발 기술에 대해서 깊게 알아보는 글들을 위주로 방향성을 잡아나갈 것이다
드디어 달성한 200번째 글!
오늘은 드디어 블로그의 200번째 글이 작성되는 날이다.
본격적으로 시작한 22년 10월 2일부터 지금까지 상당히 많은 일들이 있던 것 같다.
꾸준함과 올바른 방향성이 나를 좋은 곳으로 데려다준다는 믿음을 가지며, 이만 글을 마치도록 하겠다
TMI+ 아래에는 200번째 포스팅 기념으로 제대로 블로그를 시작한 날의 포스팅을 공유해 보았다.
To be Continue...
다음 글에서는 어떤 주제로 확장이 될까? 그건 지금의 나도 모른다.
갑자기 생각나서 무언가 새로운 컴포넌트를 개발할 수도 있고, 무언가 디자인을 해서 애니메이션을 만들 수도 있고,
아니면 알고리즘을 연습할 무언가를 만들지도 모른다.
하지만 계속 파고들 것이라는 사실은 변함이 없고, 그러한 과정들을 거친다면
간단한 기능을 할 수 있는 사이트가 만들어지지 않을까 기대해보고 있다.
Deep Dive는 계속될 것입니다