모듈성
대규모 애플리케이션을 구축하는 꿀팁은 대규모 애플리케이션으로 구축하지 않는 것
모듈성
애플리케이션을 작고 독립된(독립적으로 개발 및 테스트할 수 있는) 모듈 또는 컴포넌트로 나누는 것
모듈성은 코드의 재사용성을 높힘
모듈화된 앱을 구축하는 최고의 방법은 작고, 모든 것을 포함하고 있고 독립적으로 테스트 및 디버깅할 수 있는 기능 조각에서 시작됨
모듈을 사용하면 조직화되고, 재사용할 수 있고, 유지보수성이 높은 코드베이스를 갖게 됨
컴포넌트화를 통해 모듈성을 확보하면 앱 유지보수 및 확장가능하게 만들고 개발자 경험을 향상시킴
컴포넌트의 명확한 구조와 재사용성을 제공하기 떄문
재사용 가능한 컴포넌트 식별
버튼, 메뉴, 카드 같이 반복적으로 반복되는 요소들
헤더, 컨텐츠 영역, 푸터 같은 페이지의 섹션들
기능의 논리적 덩어리
앱을 작은 컴포넌트로 나누기
컴포넌트화의 핵심은 앱을 보다 작고, 관리 가능한 컴포넌트들로 자르는 것
작은 컴포넌트들은 보다 유연하고 여러 컨텍스트에서 재사용할 수 있다.
모든것을 컴포넌트로 만들고 싶을 수 있지만 균형이 중요
너무 잘게 나누면 그 코드베이스를 탐색하기 어려움
컴포넌트를 나눌 때는 여러 요소들을 고려해야 한다.
재사용성
특정 UI 요소 혹은 기능을 앱의 여러 부분에서 반복한다면 좋은 후보
단순성과 가독성
컴포넌트를 작은 하위 컴포넌트로 나누고 각각의 책임에 집중하도록 하면 코드를 보다 쉽게 읽고 이해할 수 있게됨
개선된 테스트 가능성
컴포넌트가 더 작고 집중된 책임을 갖으면 보다 효율적으로 테스트 작성이 가능해짐
적은 내부 상태, 적은 사이드 이펙트를 가지므로 테스트에서 격리하기 쉽고 각 컴포넌트가 의도한 대로 작동함을 보장
성능 고려 사항
컴포넌트를 나눔으로써 렌더링을 최적화하거나 불필요한 조작을 줄일 수 있음
종종 작은 컴포넌트가 보다 적은 수의 리렌더링을 하며 컴포넌트와 계산을 메모제이션함
이는 떄때로 앱의 전반적인 성능을 개선할 수 있음
디자인 시스템을 구현하라
재사용 가능한 컴포넌트, 가이드라인, 에셋의 집합
팀이 응집된 제품을 구축하는데 도움을 준다.
디자인 시스템을 구축하면 리액트 앱의 컴포넌트 설계와 개발을 표준화하는데 도움이 된다.
이를 활용하여 구체적인 로직과 기능에만 집중 가능
지연 로딩
필요할 때 만 리소스를 로딩함으로써 앱의 초기 로딩을 크게 최소화하고 사용자 경험 및 리소스 효율을 개선
더 나아가 앱 전체를 독립적으로 로딩될 수 있는 작은 덩어리로 나눈다.
동적 임포트:
lazy()
lazy
는 default exports 를 사용할 때에만 효과가 있다.즉시 필요하지 않은 큰 컴포넌트에만 사용해야 한다.
코드에 약간의 복잡성이 추가되고, SSR 관련 이슈를 야기할 수 있기에
상호작용에 대한 지연로딩: 인터렉션이 발생할 때 컴포넌트를 동적으로 로딩
Intersection Observer API 사용한 지연 로딩: 페이지의 특정 영역에 들어올 때 코드를 로딩
코드 분할
앱 코드 전체를 보다 작은 관리 가능한 덩어리로 나눔으로써 성능 최적화하는 기법
모듈화된 혹은 컴포넌트화된 앱 구조를 갖추는 것은 효율적인 코드 분할을 위한 토대를 닦는 것
컴포넌트가 독립적이고 필요한 모든 것을 가지고 있도록 설계되면 이들을 필요할 때 로딩할 수 있는 구분된 덩어리로 분리하기 더욱 쉬워짐
코드 분할의 목표는 전체 앱을 미리 로딩하지 않고, 사용자에게 필요한 순간에 필요한 코드만 로딩하는 것
코드 분할하려면 가장 먼저 크리티컬 패스
를 식별해야 한다.
크리티컬 패스는 앱이 사용자에게 표시되기 전 반드시 로딩되어야 하는 리소스의 순서를 의미
어떤 리소스를 보다 발전된 코드 분할 기법을 사용해 지연로딩 할 수 있는지 결정할 수 있음
코드 분할 패턴
라우트에 따라 분할: 사용자의 탐색에 따라 페이지 모듈을 로딩
컴포넌트에 따라 분할: 그래프나 테이블 같은 큰 컴포넌트를 지연 로딩
온디맨드 로딩: 사용자가 버튼, 드롭다운 등을 클릭할 때 코드를 로딩
온디맨드
-> 사용자가 필요할 때 즉시 제공되는 방식
엔트리 포인트 분할
초기 자바스크립트 파일을 작은 덩어로리로 자른다.
이 덩어리들은 필요할 때만 로딩되며 페이지의 초기 로딩시간을 줄여줌
벤더 분할
코드에서 서드파티 의존성을 분리할 때 사용하는 기법
서드파티 라이브러리, 프레임워크를 사용하면 해당 라이브러리 코드들은 앱 번들에 포함됨
번들의 크기는 커지고 로딩 속도는 느려지며, 라이브러리가 업데이트 되었을 때 캐시 무효화 이슈를 야기할 수 있음
벤더 분할을 사용하면, 서드파티 의존성과 관련된 코드를 별도의 덩어리로 잘라내 독립적으로 캐싱 가능
우리 코드를 업데이트 했을 때, 최종 사용자는 전체 라이브러리를 다시 다운로드하지 않아도 된다는 의미
라이브러리는 이미 캐싱되어있기 때문
캐싱을 최적화하고 불필요한 데이터 다운로드를 줄임으로써 더 빠른 로딩과 더 나은 UX 제공
동적 분할
JS 코드를 필요할 때 필요한 만큼 로딩할 때 사용하는 기법
코드 각 부분이 특정 상황에서만 필요한 대규모 앱에 유용
동적 분할은 미리 정해진 엔트리 포인트에만 의존하지 않는다는 점에서 엔트리 포인트 분할과 다름
리엑트의 lazy/suspense, 동적 import 기능 도구나 패턴들을 사용해 코드를 분할한다.
컴포넌트 수준 분할
각 컴포넌트를 필요할 때만 지연 로딩
네트워크 대역폭을 보다 효율적으로 사용할 수 있지만 경우에 따라 로딩해야하기 때문에 지연을 증가시키기도함
라우트 기반 분할
라우트에 기반해 각각의 번들로 나눔
초기 코드량을 줄이는데 도움되지만, 네트워크 대역폭 사용관점에서는 컴포넌트 수준보다는 효율적이지 않음
Last updated