- 메인 스레드에서 길고 부하가 큰 작업을 실행할때
- 큰 작업을 이벤트 루프의 여러 틱에 걸쳐 주기적으로 분할하는 것
- 그 중간중간 다른 작업을 실행할 수 있도록
- 가장 자주 접했던 방법 setTimeout을 반복 하는 것
- setTimeout으로 실행한 콜백은 매크로태스크 큐에 쌓이고 이벤트 루프 돌면서 실행할 수 있기 때문에 분할되는데
- setTimeout 안에서 재귀로 호출하게 되면 일정 주기로 작게 분할된 작업을 실행하도록 할 수 있다
- async/await + Promise로 분할
- 큰 작업 중간에 단순하게 Promise로 대기하는 로직을 추가한다
await new Promise(resolve => setTimeout(resolve, 0))
- Promise의 resolve는 마이크로태스크 큐에 쌓이기 때문에 다음 이벤트 루프에서 실행된다
다음 이벤트 루프 사이클로 넘겨라
하는 의미
await
를 만나면 작업하던 것을 멈추고 이벤트 루프에게 권한을 넘긴다
setTimtout(resolve, 0)
을 다음에 실행할 매크로태스크 큐 넣어두고
- Promise의 콜백을 마이크로태스크에서 꺼내 실행하고 다음 매크로태스크에 들어가며 resolve까지 실행되는 순서
- setTimeout과 Promise 각각의 큐
- 매크로태스크 vs 마이크로태스크
- 이벤트 루프 돌면서 콜스택이 비어있을때 마이크로태스크 모두 실행되고 그 다음 매크로태스크가 실행된다
- 그렇다면 먼저 실행되어야하는 것이 있다면
Promise.then
을 사용하고 그 다음 순위로 실행될 작업에 setTimeout
을 해주면 된다
- 분할하다보니 requestAnimationFrame가 떠오르는데
브라우저의 화면 갱신 주기와 동기화하여 작업을 예약하도록 설계되었습니다
콜백은 항상 다음 화면이 렌더링 되기 직전에 실행
- 렌더링 애니메이션 프레임 단위로 실행되는 requestAnimationFrame는 화면 끊김 없이 UI 작업이 진행되어야하는 경우
- setTimeout은 순서는 중요하지 않으며 무거운 비동기 작업을 분할하여 실행해야하는 경우
- 그렇다면 화면 끊김 없이 무거운 비동기 동작을 필요로한다면…
- requestAnimationFrame만으로는 문제가 발생한다
그러나 화면 갱신 주기에 맞춰 무거운 작업을 실행하면 렌더링 성능이 저하될 수도 있습니다.
- 화면 갱신 주기와 동일하게 항상 실행되고 있으니 오히려 무거운 작업을 실행했을때 렌더링이 되지 않은 상태로 대기하는 것
- requestAnimationFrame와 setTimeout 을 조합해야하는데
- 어떤 형태가 되어야할까? requestAnimationFrame(setTimeout)
- 화면끊김이 우선이니 🤔
- 항상 작업 분리를 하다보면 웹 워커에 도달하게 되는데
- 리액네에는 존재하지 않다보니 금방 패스 하게 된다
- 브릿지 모듈로 네이티브를 다녀오거나
- 렌더링 퍼포먼스는 극악의 최적화를 해야한다
- 처음 리액트를 공부하기 시작했을때
- 우선 고고 를 외치면 프로젝트 만들때 사용했던 CRA
- 이게 프레임워크 인줄 알았다
- 적절하게 프로젝트 환경이 구성되어있었기에
- 리액트 = CRA = 프레임워크 라는 흐름으로 🏄
이러한 문제를 해결하기 위해 사용자는 결국 CRA 위에 자신만의 맞춤형 솔루션을 구축하게 되는데, 이는 원래 CRA가 해결하고자 했던 문제이기도 합니다.
- 프레임워크를 사용함으로써 얻을 수 이점이 있는데
- 프로젝트마다 요구하는 구성이 다르기에 각각 자신만의 프레임워크를 구축하게 되지 않을까
- 모든 곳에 완벽한 것은 없으니 계속 다양한 성격의 진화를 하게 되는듯
- ref를 전달하고 이를 전달 받기 위해 forwardRef를 사용했는데 이게 없어진다고?
표준 프로퍼티로 ref를 직접 전달
컴포넌트 아키텍처를 간소화하고 보일러플레이트 코드를 줄이고자
- 🥳 ref > forwardRef > ref…
- 보일러 플레이트를 줄인다는 것에 감동
- 그럼 리액트 19에서는 이걸 어떻게 접근할 것인가?
- ref를 다른 props와 동일하게 사용한다
- 🤔 왜인지 속상하다
- 시맨틱 앞에 더 있다니!
MAJOR.MINOR.PATCH
업그레이드 시 호환성과 안정성을 보장하기 위한 라이브러리 관리자와 사용자 간의 **계약
**
- 어떤 버전이 올라갔는지를 보고 어떤 목적의 업데이트가 이뤄진건지 추측할 수 있다는 것
{EPOCH * 1000 + MAJOR}.MINOR.PATCH
- 메이저의 단계를 분할하여 조금 충격적이 것을 에포크 버전으로 올리자는 것인데…
- 같은 의미로 쓰이던 메이저 버전을 조금 더 세분화 하는 느낌이라
- 충격적인 의미를 전달하는 목적이라면
- 버전 범핑이 1, 2, 3 순서대로가 아니라 1, 2, 10, 20 이런식으로 가도 되는 것 아닌가?
- 그게 바로 에포크 인가