본문 바로가기

영어 공부 + 글귀 번역

React 동시성 모드란 무엇인가?

원글: https://medium.com/swlh/what-is-react-concurrent-mode-46989b5f15da

 

What is React Concurrent Mode?

For the past three years, the React core team has been working on a major feature that is going to significantly affect both user…

medium.com

지난 3년, React core team은 개발 프로세스, 사용자 경험 두가지 모두 상당한 영향을 미치는 동시성 모드를 작업해 왔다. 여전히 작업이 진행중이고 많은 부분들이 공식적이지 않지만, 가까운 미래에 무엇이 우리들을 기다리고 있는지 살펴보겠습니다.

 

"동시성"이란 무엇인가?

알다시피, Javascript는 싱글 쓰래드 언어이며, 실행하는 각 작업은 쓰래드가 다음 작업이 완료될때까지 차단합니다.

하지만, 그것은 우리가 같은 시간에 하나 이상의 프로세스를 만들지 못하는것을 의미하진 않습니다.

복잡하지만 실제 생활로 설명드리자면

 

당신은 한잔의 티와 잼을바른 토스트없이 아침을 시작할수 없는 사람입니다.

앞서 말한대로 진행하면, 차를 만들어야만 토스트를 준비할수 있다는것을 의미합니다.

 

하지만 그것은 비효율적이며 차가 식을수도 있습니다.

 

그러므로 신선하고 따뜻한 차와 토스트를 가질수 있게 효율적으로 하려면,

대신 작업을 작은 단위로 분리시켜야 합니다. 또한 각 작업을 맞춰 재정렬 해야합니다.

( 물따르고 => 물대우고 => 빵자그로 => 빵 데우고 => 잼바르고 => 티에 물붓기 )

 

ㅗㅜㅑ! 우리는 "같은 시간에" 2가지 작업을 진행할수 있었습니다.

 

동시성이란? 프로그램을 독립적으로 실행되게 만들수 있는 조각으로 분할하여 구성화하는 방법입니다.
이것은 싱글 쓰래드의 한계를 넘는 방법이며, 어플리케이션을 더 효율적으로 만들어줍니다.

 

이제 정의를 알았으니, React와 어떤 연관이 있는지 살펴보겠습니다.

 

사용자 경험을 완성하는 모든것

브라우저의 UI 쓰래드는 모든 css의 변화, 사용자 입력, Javascript의 변화를 화면에 적용합니다.

최신 기기에서, 최고의 사용자 경험을 제공하기위해 초당 60프레임의 렌더링을 할것으로 예상합니다.

그것을 이루기 위해선, 각 렌더 사이클 코드는 16.67ms 이하에서 실행되야 하며, 실제론 약 10ms 정도로 훨신 적습니다. ( 브라우저는 UI작업도 해야하므로 )

 

React는 Javascript이므로 같은 한계에 묶여있으며 React가 조정 단계를 시작하면, 끝날때까지 중지시킬수 없습니다.

이동안 브라우저의 메인 UI 쓰래드는 사용자 입력 전달과 같은 어떠한 다른 작업을 실행할수 없습니다.

따라서 React 조정 알고리즘이 엄청 효율적이라 할지라도, 웹 어플리케이션과 dom tree가 커지면 버벅거림을 이끄는 프레임 드랍 혹은 어플리케이션의 미응답이 일반적 문제라는것을 쉽게 이해할수 있습니다.

 

( input에 숫자를 입력하면 랜덤하게 색깔 pixcel box를 생성하는 예제 페이지가 있는데 입력할때마다 엄청 버벅거림 )

 

빡치죠? 1만개의 dom node를 런데링하는것은 약관 과장된거 같습니다. 하지만 문제를 신속하게 설명하는 방법입니다.

 

대부분의 개발자들이 memoization, debounce와 같은 더 나은 경험을 만들어주는 기술을 사용하지만, 메인 문제를 잠시 지연시키는 것입니다. ( 렌더링은 도로를 막는 트럭입니다. )

 

사용자 경험을 향상시키는것은 퍼포먼스 문제를 수정하는것이 전부가 아닙니다. 하지만 사용자가 더 나은 경험을 원하는지(고려하는지) 또한 생각해야 합니다.

 

당신은 성능좋은기기, 똥기기를 가지고있던간에  스피너, 스켈레톤, 플레이스홀더 에서 도망칠수 없습니다 (ㅠㅠ).

그것은 무언가가 실행되는동안 좋은 표시를 제공하지만 필요 이상으로 너무 많이 보여줄때 오히려 경험을 저하시킵니다. 만약 데이터가 기기에 충분히 빨리 로드된다면, 스피너를 처음에 보여줄 필요가 있을까요? 1초정도 더 기다렸다가 렌더링된 화면으로 이동하는것이 더 좋은 경험이지 않을까요?

 

구조 해석을 위한 렌더링

동시성이 어떻게 작업을 작은 단위로 나누고 여러 작업을 진행하는지 말해줬던것을 기억하나요?

이것이 바로 React가 하는것입니다: 렌더링 프로세스는 더 작은 작업으로 분류되고, 스케듈러는 중요도에 기반해 우선순위를 지정할수 있습니다 ( "시간-분할" 이라고도함 ).

이것으로 React 동시성이 가능합니다.

1. main 쓰래드를 막지 않는것

2. 같은 시간에 여러 작업을 하고 우선순위에 따라 전환

3. 결과를 커밋하지않고 부분 렌더링

 

렌더링 작업은 쓰래드를 길게 막습니다. 그것은 해석적이며 사용자 입력과 같이 더 높은 중요성을 가지는것이 있으면 제쳐둘수 있습니다.

 

만약 핵심적인것에 관심있으시면, React Fiber(새로운 조정 알고리즘)가 어떻게 동작하는지 이 비디오를 보는것을 추천드립니다. ( lin clark )

 

이제 동시성모드의 새로운 기능중 일부와 함께 이 이론을 사용하겠습니다.

 

그전에 메모해주세요: 말했듯이, 나오는 기능은 "React 공식 library"에 없습니다. 나중에 바뀔수도 있으므로 production에서 사용하지 않는게 좋을겁니다, 또한 이를 활성화 하려면

A. 실험적인 'react', 'react-dom' package를 사용하세요

B. 첫 렌더링을 다음과같이 바꿔주세요

const rootElement = document.getElementById("root");
ReactDOM.createRoot(rootElement).render(<App />);

 

useDeferredValue

앞에 데모를 기억해주세요( 10000개의 pixel rendering ), 모든 키를 누를때 UI가 멈출수있는곳은 어디일까요?

유저 경험을 고치려면 사용자 입력에 우선순위를 두고 많은 grid를 렌더링하는것에만 중점을 두는 방법이 필요합니다.

운좋게도 useDeferredValue를 사용할수 있습니다.

 

useDeferredValue는 prop/state 값을 감싸고 최대한의 지연된 시간을 받는 hook입니다.

이것은 React에 말하는것입니다: "이 값에 종속된 컴포넌트는 나중에 렌더링되도 괜찮다."

import { useState, useDeferredValue } from 'react';
const [value, setValue] = useState('');
const deferredValue = useDeferredValue(value, {
  timeoutMs: 5000
});

 

이것은 기능적으로 render debounce를 하지 않는것을 명심하세요! 리엑트는 여전히 "측면에" 컴포넌트를 render합니다.( virtual dom을 말하는듯 ) 그리고 배포할 시간이 준비가 되면 dom에 변경사항을 flush합니다.

 

중요: useDeferredValue를 사용하는것은 UI의 한 부분을 우선순위에 따라 표시하므로 view가 불일치할수도 있습니다.

 

 

반응형