읽어보았던
- [번역] 프런트엔드 웹 퍼포먼스: 필수 요소(1)
- 메인스레드에서 실행이 아름답게 이뤄지기 위한 방안
- 응답하지 않거나 끊기는 애니메이션을 멀리하기 위해서는 이 메인 스레드 처리가 연속적이여야함
- 이벤트 루프에서 마이크로 + 매크로 태스크를 처리하는데, 우선순위가 높은 마이크로 태스크에 비동기 처리가 들어간다면?
- 마이크로 태스크에서 비동기 처리하는 동안 렌더링을 처리해야하는 매크로 태스크는 지연되고 이 과정에서
화면은 끊긴다
ㅜㅜ - 그렇다면 이벤트 루프의 마이크로태스크를 효율적으로 이용하는 방안을 찾아봐야하는데
- (= 이벤트 루프 자체가 가볍게 훅훅 돌고 돌 수 있도록 🤡)
- 마이크로 태스크에서 비동기 처리하는 동안 렌더링을 처리해야하는 매크로 태스크는 지연되고 이 과정에서
- 그 방안 중 하나로 브라우저에 양보하기
- 실행 시간이 긴 코드를 분할하여 중간중간 매크로 태스크가 실행될 수 있도록 하는 것
requestAnimationFrame, setTimeout, setImmediate
- 일반적으로 이런 상황에서 setTimeount을 쓰고 있었는데 이는
일정 시간 지연 후 매크로 태스크 큐에 푸시
된다 - 아직 사용해보지 않은 setImmediate는
매크로 태스크 큐에 바로 푸시
하여 즉시 실행되도록 하는 것인데- 그래서 setImmediate를 RN에서는 처리해줄까? 하는 의문과 즉시 실행할거라면 이걸 왜 써야하지? 하는 의문
- 애니메니션 프레임 단위로 처리하고 싶을때 requestAnimationFrame
- 참고: jsconf 이벤트 루프 영상
- 메인스레드에서 실행이 아름답게 이뤄지기 위한 방안
- (번역) 주의 깊게 XMLHttpRequest 재시도하기
- fetch 에러 발생 시 인터셉터에서 retry
- 지금 구조에서는 횟수만 제한을 두고 refetch 하고 있는데
- 글의 내용처럼 서버 에러가 발생한 상태에서 빠르게 재요청 하는 것은 무의미한 요청이였을지도 모른다는 생각이 든다
7/24 ~ 7/31
useCurring
- 메모이제이션 + 파라미터 이슈로 계속 이어지는 테스트...
- 될 것 같은데 안되네 이거
- 벌써 한달
- 클로저를 쓰면 기억할 수 있는거 아닌가????
- 이게 문제가 아니다
- 디펜던시 변경 전까지 해당 콜백은 변함이 없어야하는데
- 하나의 콜백을 여러 사용처에서 파라미터만 다르게 사용하는 경우에
- 파라미터를 사용처마다 다르게 기억해야한다
- 이걸 클로저로 해당 상태를 기억하게 하려고 했는데...
- 무언가 문제가 따로 있다
- 리턴되는 콜백의 레퍼런스가 변경되면 또 다시 리렌더를 발생시킨다
- 이 훅을 통째로 props 전달하는 경우에는 문제가 되지 않는다
- 통째로 하나의 레퍼런스를 갖고 있기 때문에
- 하지만 커링 함수의 목적은 쪼개기 위함인데... 쪼개서 넘기는 경우에 문제가 있다
- 쪼개진 콜백이 매번 새로운 콜백을 반환하면 레퍼런스가 변경되면서 리렌더 발생시킨다
7/17 ~ 7/23
React18
- react18 변경사항을 문서로 읽기는 했지만
- 잘모르겠다!
- 영상으로 설명해주는걸 듣고 싶어서 (문득 영상 올라온거 보고)
useTransition
- 렌더링 요청이 여러번 호출된 경우 이를 처리하기 위해 다른 작업이 블로킹하고 오직 렌더링 연산만 처리 한다 (= 블로킹 렌더링)
- 이때 여러번 요청된 상태 업데이트가 화면에 바로 반영되지 않는 문제가 발생한다
- ex) 상태 업데이트 요청 > 변경된 상태에 따른 렌더링 요청 > 이게 여러번 반복되는 경우 > 밀린? 쌓인? 렌더링을 처리를 하기 위해 실제 상태 업데이트에 따른 화면 업데이트가 발생하지 못함
- 이를 해결하기 위해
useTransition
의startTransition
으로 렌더링 업데이트를 요청하는 상태 변경 함수를 감싸는 것 - 화면 업데이트 중간에 사용자의 상태 업데이트를 받는 경우 렌더링 처리를 중단하고 이를 처리한 뒤 다시 렌더링을 처리하는 것
- 애니메이션 처리를 프레임 단위로 사이사이 호출하도록 하는 것과 같은 느낌이다
Automatic Batching
- 여러 상태 업데이트를 한번에 모아모아 리렌더 발생하도록 그룹화
const callback = useCallback(() => { setState(prev => prev + 1); // 1 setState(prev => prev + 2); // 2 }, []);
- 위와 같은 상태에서 1,2번 상태 업데이트가 발생했을때 각각 리렌더를 발생시키지 않고 딱 한번의 리렌더로 처리하는 것이다
- 이미 react17에서 대응하였으나 동기 처리 지원했다고 한다
- 아래와 같은 경우 상태 업데이트 2번에 대하여 각각 리렌더가 발생하였다
const callback = useCallback(() => { setTimeout(() => { setState(prev => prev + 1); setState(prev => prev + 2); }, 0); }, []);
- 이를 react18에서 모두 automatic batching 지원하게 된 것
- 아래와 같은 경우 상태 업데이트 2번에 대하여 각각 리렌더가 발생하였다
- 여러 상태 업데이트를 한번에 모아모아 리렌더 발생하도록 그룹화
flushSync
- 이를 사용할 예시를 아직 생각해내지 못했는데
Automatic Batching
에서 상태 업데이트에 따른 리렌더 그룹화를 해제하는? - 상태 업데이트 각각 리렌더 되도록 하는 목적이 있다
const callback = useCallback(() => { flushSync(() => { setState(prev => prev + 1); // 1 }); flushSync(() => { setState(prev => prev + 2); // 2 }); }, []);
- 이렇게 되면 기본적으로 react18에서는 상태 업데이트에 따른 리렌더가 그룹화되어 1번 발생해야하지만
flushSync
로 감싸진 상태 변경을 그룹화하지 않고 각각 1, 2에 따른 리렌더가 2번 발생하게 된다
- 그럼 일부만
flushSync
를 사용하면 어떻게 되는거지? 🤔const callback = useCallback(() => { flushSync(() => { setState(prev => prev + 1); // 1 }); setState(prev => prev + 2); // 2 }, []);
- 이것도 2번 발생한다...!
- 이를 사용할 예시를 아직 생각해내지 못했는데
- 이런 커다란 것 말고 개인적으로 소소하게 마음에 드는 변화
- Notable Changes - React
Components can now render undefined
No warning about setState on unmounted components
- 특히 언마운트 시점의 상태 업데이트 경고 없애려고...
useMountedState
같은걸 사용했었는데 희소식
7/10 ~ 7/16
😯
- 이번달은 직접 시도해보는 것보다 영상이나 블로그 보는게 더 많은 것 같다
왜 React는 성공했나
- 제목이 재미있어보여서
- FE 의 중요한 한가지 DOM 을 어떻게 제어하느냐
- 다양한 브라우저의 스펙에 따라 직접 지원하는 api로 작업하기 <<< 보다 빠른 DOM 제어를 도와주는 라이브러리
- 이런 흐름으로 react가 좋은 대안이 되었다
- 본문에서 나오지만 jquery가 밀린 이유 = 속도
- DOM을 쉽게 제어할 수 있도록 라이브러리를 사용하는데
- react 대비 jquery의 속도가 너무나 느리기 때문에
-
개발자는 React 문법에 맞춰
상태(state)만 관리
하면,상태를 기준으로 DOM API는 React에서 알아서 처리하여 DOM을 렌더링
합니다. -
클래스 컴포넌트
같은 경우,최초로 생성되는 컴포넌트만 새롭게 인스턴스
를 만들고, 컴포넌트가 삭제되기 전까지 만들어진인스턴스를 통해 render 메서드를 이용하여 상태 변경을 감지(setState)
합니다. 즉, 해당 인스턴스에서 필요한 부분만을 업데이트하여context 상태를 계속 유지
할 수 있습니다. -
하지만
함수 컴포넌트(function component)
의 경우props를 인자로 받아서, JSX 문법에 맞는 React Component를 반환
해 주기 때문에함수 컴포넌트의 호출은 무조건 렌더링
을 일으킵니다. 이미 만들어진 인스턴스를 가지고 render만 호출하는 클래스 컴포넌트와는 다르게,함수 컴포넌트는 상태가 변경될 때마다 새로운 인스턴스를 생성
하기 때문입니다. 따라서 함수 컴포넌트는 호출될 때마다 늘 동일한 상태, 초기화된 상태만 가질 수 있었습니다. - 상태만 관리하면 된다
- 클래스에서 함수 컴포넌트로 넘어오고 나서 memo만 잘 사용하면 문제 없고 오히려 코드가 hooks으로 통일되어 보인다는 장점만을 생각했다
- 근데 최근(지난주 조합 찾기 처럼)에 함수 컴포넌트처럼
React Component를 반환
하는 무언가 (=useCallback에서 반환하는) 들이 무자비한 리렌더 또는 불필요한 연산을 유발하고 있었던것을 깨닫게 되었다
7/3 ~ 7/9
조합 찾기
- 메모이제이션 잘 되고 있는걸까
- useCallback = memoized version of the callback
- useMemo = memoized value
아는거 딱 하나 있는데
- 악 아는게 없나보다!!!!!!!!!!
- 아는게 없는걸 안다
- 이거 하나 아는게 다행인가
7/1 ~ 7/2
FlatList
- shopify: FlashList로 FlatList를 개선할 수 있을까
- 비슷한 것만 봐도 깜짝깜짝 놀래는 FlatList
- 이걸???