generated from muhandojeon/study-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Create 상범.md * Create 상범.md
- Loading branch information
Showing
2 changed files
with
153 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
# 챕터 12 리액트 디자인 패턴 | ||
|
||
## 고차 컴포넌트 (HOC) | ||
- 다른 컴포넌트를 인자로 받아 새로운 컴포넌트를 반환하는 컴포넌트 | ||
|
||
### 장점 | ||
- 재사용하고자 하는 로직을 한 곳에 모아 관리 가능 => DRY 유지, 관심사 분리 가능 | ||
|
||
### 단점 | ||
- prop 이름 충돌 가능성 => 어떤 고차 컴포넌트가 어떤 prop 제공하는지 파악하기 어려워 디버깅이 어려울 수 있음 | ||
|
||
> 이것만 단점으로 꼽는다고?! 복잡성과 트리 깊이 문제가 단점이라 생각 | ||
## 렌더링 Props 패턴 | ||
- JSX 요소를 반환하는 함수 값을 가지는 컴포넌트 prop | ||
|
||
```js | ||
function Input(props) { | ||
const [value, setValue] = useState(''); | ||
return ( | ||
<> | ||
<input type="text" value={value} onChange={(e) => setValue(e.target.value)} /> | ||
{props.render(value)} | ||
</> | ||
); | ||
} | ||
|
||
export default function App() { | ||
return ( | ||
<div className="App"> | ||
<h1>Temperature Converter</h1> | ||
<Input | ||
render={(value) => ( | ||
<> | ||
<Kelvin value={value} /> | ||
<Fahrenheit value={value} /> | ||
</> | ||
)} | ||
/> | ||
</div> | ||
); | ||
} | ||
``` | ||
|
||
> 상태 끌어 올리기 예제가 아주 적절했음, 컴포넌트 자식으로 함수 전달하는 예제도 굿 | ||
|
||
### 장점 | ||
- 여러 컴포넌트 사이에서 로직과 데이터 쉽게 공유 가능 | ||
- 재사용성 높이기 | ||
- 애플리케이션 로직과 렌더링 컴포넌트 분리 가능 | ||
|
||
### 단점 | ||
- 받은 데이터를 변경할 필요가 없는 렌더링에 치중한 컴포넌트에만 사용 가능 | ||
|
||
> 개인적으론 코드 가독성 떨어진다 생각, 가끔 유용하게 쓰일 떄 있을 것 같음 | ||
|
||
## hook의 장단점 | ||
|
||
### 더 적은 코드 라인 수 | ||
- hook을 사용하면 코드를 라이프사이클 별로 나누지 않고 관심사 및 기능별로 그룹화 가능 | ||
- 코드 길이도 줄일 수 있음 | ||
|
||
### 복잡한 컴포넌트 단순화 | ||
- 클래스 컴포넌트는 관리 어려움, 핫 리로딩과 함께 사용하기 힘듦, 코드 경량화 어려움 | ||
- 함수 컴포넌트는 hook이 쉽게 도와줌 | ||
|
||
### 상태 관련 로직 재사용 | ||
- 자바스크립트 클래스는 여러 단게에 걸친 상속 때문에 전체적인 복잡성을 높임 | ||
- hook은 클래스 작성 안하고 기능 사용 가능 | ||
|
||
### UI에서 분리된 로직 공유 | ||
- 클래스 컴포넌트는 UI와 무관한 로직을 추출하고 공유할 방법이 없었음 => 그래서 고차 컴포넌트, 렌더링 props같은 복잡한 방법 동원함 | ||
- hook 등장 이후 자바스크립트 함수로 추출할 수 있게 되고 문제 해결 | ||
|
||
## 로더블 컴포넌트 | ||
loadable-components 라이브러리는 SSR 환경에서 Suspense를 대체할 수 있는 좋은 방법 | ||
> react 18부터 SSR환경에서도 Suspense 사용할 수 있다고 적혀있는데 굉장히 제한적임 | ||
> Suspense 자체에 데이터 페칭 매커니즘이 없어서 tanstack-query에 의존하지 않으면 사용 못함 ㅋㅋ | ||
> SSR 환경에서 suspense 사용? => next.js 아니면 못함 ㅅㄱ | ||
## PRPL 패턴 | ||
- push: 중요 리소스 푸쉬해서 서버 왕복 횟수 최소화, 로딩 시간 단축 | ||
- render: 최대한 빠르게 렌더링 (TTI 줄여 초기 사용자 경험 개선하기) e.g SPA 에서 초기에 필요한 js 번들만 로드하기 | ||
- pre-cache: 초기 화면 렌더링 끝난 후, 사용자가 방문할 가능성 높은 경로와 리소스를 사전에 캐시하기 e.g service worker 사용 | ||
- lazy-load: 초기 화면에 필요하지 않은 리소스(이미지, 비동기 JS 모듈 등)를 나중에 로드 e.g Intersection Observer API를 사용해 사용자 화면에 나타나는 시점에 이미지 로드, React.lazy와 Suspense로 필요한 컴포넌트를 동적으로 로드 | ||
|
||
|
||
## 리스트 가상화 | ||
한번에 수천개의 목록 요소를 렌더링하여 초기 렌더링 속도 저하 또는 스코롤 성능 저하를 유발하는 대신 가상화는 사용자에게 보이는 항목만 렌더링 시킴 | ||
|
||
> 실제로 무한 스크롤로 이루어진 페이지에서 이미지와 데이터가 DOM에 계속 쌓이다보면 점점 느려지는 경우가 있음 | ||
> 무신사는 virtuoso, 오늘의집은 예전에는 react-virtualized 쓰다가 최근에 virtuoso로 갈아탄듯함 [오늘의집 무한스크롤 개발기](https://www.bucketplace.com/post/2024-09-11-virtualizedlist-%EB%AC%B4%ED%95%9C%EC%8A%A4%ED%81%AC%EB%A1%A4-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81-%EA%B0%9C%EB%B0%9C-%EC%9D%B4%EC%95%BC%EA%B8%B0/) | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# 챕터 13 렌더링 패턴 | ||
|
||
## 핵심 웹 지표 | ||
- TTFB: 클라이언트가 페이지 콘텐츠의 첫번째 바이트를 받는데 걸리는 시간 | ||
- FCP: 페이지 이동 후 브라우저가 콘텐츠의 첫 부분을 렌더링하는데 걸리는 시간 | ||
- LCP: 페이지의 주요 콘텐츠를 로드하고 렌더링하는데 걸리는 시간 | ||
- TTI: 페이지 로드 시작부터 사용자 입력에 빠르게 응답할 수 있을 때 까지 걸리는 시간 | ||
- CLS: 레이아웃 변경 방지 위한 시각적 안정성 측정 | ||
- FID: 사용자가 페이지와 상호작용한 시점부터 이벤트 핸들러가 실행될 수 있는 시점까지의 시간 | ||
|
||
## 클라이언트 사이드 렌더링(CSR) | ||
- 모든 UI가 클라이언트에서 생성됨, 전체 웹 어플리케이션이 처음 요청 시에 모두 로드 됨 | ||
- SPA 구축할 수 있게 함 | ||
|
||
### 단점 | ||
- 초기 큰 자바스크립트 번들을 만들도록 해서 페이지의 FCP, TTI 증가 시킴 | ||
|
||
## 서버 사이드 렌더링(SSR) | ||
- HTML을 서버에서 렌더링하고 클라이언트에서 다시 하이드레이션 함 | ||
|
||
## 정적 렌더링(Static Rendering) | ||
- 전체 페이지의 HTML을 빌드 시점에 미리 생성함 | ||
|
||
## 점진적 정적 생성(ISR) | ||
- 정적 렌더링 + stale-while-revalidate 전략을 사용한 캐시 재검증 | ||
|
||
## 스트리밍 SSR | ||
|
||
> SSR 할 때 데이터 패칭 때문에 TTFB가 오래 걸림 | ||
> => 리액트는 서버에서 renderToString 메서드 사용하는데 동기 메서드라 메인 스레드 점유 하니까 데이터 패칭할때까지는 화면에 아무것도 보여줄 수가 없네; | ||
> => 이를 위해 비동기 처리 메서드 등장 (renderToPipableStream) | ||
> | ||
> next.js app router 사용하면 streaming ssr이 기본 적용! | ||
> | ||
> 데이터 패칭하는 컴포넌트를 Suspense로 감싸면 그 영역 바깥이 먼저 pre-rendering 되고 데이터 패칭과 렌더링을 번갈아가면서 청크 단위로 html에 내려보내줌 | ||
streaming ssr 공부할 때 좋았던 레퍼런스 | ||
> [SSR의 기쁨과 슬픔: 렌더링의 변화의 흐름을 통해 알아보는 SSR과 Streaming SSR | 인프콘2023](https://www.youtube.com/watch?v=hPyyFu3lrEg&t=2080s) | ||
> [[Dev Dive_ Frontend Day] 스트리밍 SSR 딥 다이브](https://www.youtube.com/watch?v=9xl9X2pfHeI&t=1835s) | ||
## 엣지 렌더링 | ||
|
||
> edge function은 최소한의 런타임 환경에서 동작하기 때문에 라이브러리 거의 못씀. e.g) axios, 라이브러리 내에서 사용한 web api가 edge function에서 지원하지않는 api라면 사용 불가 | ||
> 왜? serverless function(e.g lambda)의 한계점인 콜드 스타트를 해결하기 위해 아예 지원하는 api를 줄여버림 | ||
> 여담으로 콜드 스타트를 완화하기 위한 방법들이 많긴 함. 하지만 여전히 엣지 렌더링은 좋음 | ||
### 내가 생각하는 장점 | ||
- 사용자와 가까운 곳에서 코드 실행 | ||
- 실 서버까지 왕복 안함 | ||
- 일정하고 짧은 반응 시간 가능 | ||
|
||
### 내가 생각하는 단점 | ||
- 공짜겠음? ㅋㅋ | ||
|
||
## 하이브리드 렌더링 | ||
- next.js app router 환경에서 페이지마다 ISR, SSR, CSR 등 하이브리드 렌더링이 가능 | ||
|
||
|