Computer >> 컴퓨터 >  >> 소프트웨어 >> 브라우저

React 캐시, 시간 분할 및 동기식 API 가져오기에 대해 자세히 알아보세요.

React 캐시, 시간 분할 및 동기식 API 가져오기에 대해 자세히 알아보세요.

마빈 프라셰

음, 올해는 React의 해인 것 같습니다. 아마도 16.7-alpha.0에 포함된 새로운 킬러 기능인 Hooks에 대해 들어보셨을 것입니다. Time Slicing이나 Suspense와 같은 훌륭하고 멋진 다른 기능에 대해서도 들어보셨을 것입니다.

이 기사는 그렇지 않습니다 새로운 기능 중 일부를 사용하는 방법을 설명하는 것이 아니라 해당 기능이 어떻게 구축되었는지 증명하는 것을 목표로 합니다. 우리가 무엇을 하고 있는지 이해하기 위해서입니다.

제가 그 기능을 발견한 방식으로도 작성되었습니다. 아마도 생각했던 방식이 아닐 수도 있지만, 저는 이렇게 포인트를 얻었습니다.

읽으면서 알게 될 내용:

  • 비동기 JavaScript 및 이벤트 루프
  • React의 대수적 효과(예시 포함)
  • 섬유 및 반응 단계

내가 이 글을 쓴 이유는 무엇인가요?

제가 이 글을 쓰게 된 이유는 비동기를 사용할 수 있는 특별하고 실험적인 기능 때문이었습니다. 동기를 사용하는 작업 API:

const bulbasaur = ApiResource.read() ?… 뭐죠? 동기식 ?!

반응 캐시 라이브러리는 동기 API와 함께 비동기 작업을 사용하는 기능을 생성합니다. 이것이 React가 내부적으로 어떻게 작동하는지 배우고 싶게 만든 기능입니다. 다음은 Dan Abramov와 Andrew Clark이 이 라이브러리에 대해 발표한 프레젠테이션입니다.

그게 어떻게 가능합니까? 동기 호출을 사용하여 원격 데이터를 어떻게 얻을 수 있나요?

이 예제를 자세히 살펴보고 React-Cache가 이러한 기능을 구현하는 방법을 이해하고 작동 방법을 알아보겠습니다. 이 이야기는 섬유 구조에서 시작됩니다.

자바스크립트 작업 제어

Fiber 아키텍처를 통해 React는 작업 실행을 제어할 수 있습니다. React가 겪었던 여러 문제를 해결하기 위해 만들어졌습니다. 내 관심을 끌었던 두 가지는 다음과 같습니다:

  • 데이터 가져오기보다 사용자 입력과 같은 특정 이벤트보다 우선순위 지정
  • 메인 스레드 가용성을 유지하고 긴 렌더링 프로세스 중에 이를 차단하지 않도록 React 계산을 비동기식으로 분할

React뿐만 아니라 JavaScript 애플리케이션 내부에서 상태 변경을 유발하는 모든 것은 비동기 작업으로 인해 발생합니다. 여기에는 setTimeout이 포함됩니다. , fetch , 이벤트 리스너.

비동기 작업은 여러 JavaScript 핵심 개념을 통해 관리됩니다.

  • 작업(마이크로, 매크로, 렌더링 등…)
  • 이벤트 루프
  • 콜스택

이러한 개념에 익숙하지 않다면 Jake Archibald의 다음 동영상을 시청해 보시기 바랍니다.

Fiber 덕분에 사용자 입력이 해결됩니다. 가져오기 호출과 같은 다른 비동기 작업 전에

어떻게 이런 일이 가능할까요?

글쎄, 위의 Archibald의 이야기는 이벤트 루프가 작동하는 방식에 대해 배우는 나의 길의 첫 번째 포석이었습니다. 그는 예를 들어 Promise API를 통해 생성된 마이크로 작업이 이전에 실행되고 플러시된다고 말합니다. 다음 매크로 작업입니다. 이 프로세스는 setTimeout과 같은 콜백 기반 메서드를 사용합니다. .

그래서 제가 "사용자 입력과 데이터 가져오기" 비교를 기억하신다면 팀이 fetch을 어떻게 만들었나요? 이후 결심 onChange 결심?

이러한 개념 중 어느 것도 동일한 사양인 WhatWG/HTML5/Ecma-262에 맞지 않으며 브라우저나 JS 엔진과 같은 다른 위치에서 제공됩니다.

내 말은, Promise 문제를 어떻게 해결해야 한다는 거죠? setTimeout 이후 ?

이것은 나에게 정말 미친 소리처럼 들렸고 그것이 어떻게 작동할 수 있는지에 대한 아이디어를 얻는 것이 정말 어려웠습니다. 사실은 더 높은 수준에서 발생한다는 것입니다.

나중에 React Rally에서 Brandon Dail의 놀라운 강연을 보았습니다. 이는 React Fiber 아키텍처 덕분에 출시된 새로운 Time Slicing 및 Suspense 기능을 보여줍니다:

Dail에 따르면 파이버는 스택의 각 항목을 파이버라고 부르는 일반적인 JavaScript 호출 스택과 같습니다. . 프레임에 의존하는 호출 스택과 다릅니다. 함수(+ 메타데이터)를 나타냅니다. 오히려 파이버는 구성요소(+ 메타데이터)를 나타냅니다. . 광섬유를 모든 것을 알고 있는 구성 요소 주위의 거대한 상자로 살펴보겠습니다.

이 두 개념에는 중요한 차이점이 있습니다.

우선, 콜스택은 기본 부분 구동 위에 구축된 기능입니다. 자바스크립트 코드 . 모든 JavaScript 함수 호출을 스택하고 자체적으로 실행하는 것을 목표로 합니다. 함수를 호출할 때마다 스택에 추가됩니다. 콜스택이 없으면 명확하고 자세한 오류 스택 추적을 얻을 수 없습니다. 그리고 콜스택은 자바스크립트 코드에서 접근할 수 없기 때문에 제어하기가 정말 어렵고 불가능하기까지 합니다.

반면, 파이버 스택과 같은 파이버는 동일한 개념을 나타내지만 자바스크립트 코드로 구축됩니다. 가장 작은 단위는 기능이 아니라 구성요소입니다. 실제로 JavaScript 세계에서 실행됩니다.

파이버 아키텍처가 JavaScript로 완전히 구축되었다는 사실은 우리가 이를 사용하고, 액세스하고, 수정할 수 있다는 것을 의미합니다. 표준 JavaScript를 사용하여 작업할 수 있습니다.

나를 잘못된 방향으로 몰고 간 것은 React가 JavaScript가 작동하는 내부 방식을 차단하기 위해 해결 방법을 사용하고 있다고 생각했기 때문입니다. 그렇지 않습니다 . Fiber는 React 구성 요소에 대한 정보를 소유하고 해당 수명 주기와 상호 작용할 수 있는 단순한 JavaScript 개체입니다. React 내부 기능에만 작동할 수 있습니다.

아이디어는 아님 fetch과 같이 JavaScript의 작동 방식을 재정의하려면 콜백 작업 전에 마이크로태스크 해결을 실행해야 합니다. 어떤 React 메소드를 호출해야 하는지, 말아야 하는지가 더 중요합니다. 다른 수명 주기 메서드 호출을 중단하는 것과 같은 특정 상황에서.

잠깐만요! Fiber가 React 앱의 모든 것을 절대적으로 제어할 수 있다고 말씀하시나요? 하지만 컴포넌트가 React에게 어떤 작업도 중지하라고 어떻게 알릴 수 있을까요?

대수적 효과, 예, 하지만 JavaScript로 부탁드립니다

React는 파이버 아키텍처 덕분에 구성요소를 제어하고 구성요소가 실행 중인지 알 수 있습니다. 지금 빠진 것은 React에게 특정 구성 요소에 대한 변경 사항이 있음을 알려주어 이 변경 사항을 처리하도록 하는 방법입니다.

대수적 효과가 여기에 해당됩니다. 게임에 입장하세요.

대수적 효과는 JavaScript에 존재하는 것이 아닙니다. 좀 더 높은 수준의 설명으로 무엇인지 설명하도록 노력하겠습니다.

대수적 효과는 디스패처와 비슷하게 일부 정보를 어딘가로 보낼 수 있는 개념입니다. 중단하는 특정 함수를 호출하는 것이 아이디어입니다. 상위 함수가 계산을 처리할 수 있도록 현재 실행 중인 함수를 정확한 위치에 배치합니다. 상위 계산이 완료되면 정보가 전송된 초기 위치로 프로그램을 다시 시작할 수 있습니다.

OCaml 또는 Eff와 같은 일부 언어는 이러한 기능을 기본적으로 활용합니다. 구현 세부 사항은 상위 항목에만 의존하기 때문에 이는 정말 흥미로운 추상화입니다.

JavaScript에 이런 기능이 있다면 정말 멋지지 않을까요?

React 팀은 JavaScript try/catch를 다루는 React 컨텍스트에서 유사한 접근 방식을 만들었습니다. 블록. Dail에 따르면 이는 JavaScript에서 가장 가까운 개념입니다.

무언가를 던지는 것은 어딘가에 있는 부모에게 정보를 보내는 것을 허용합니다. 정보를 파악한 첫 번째 부모는 해당 정보를 처리하고 계산할 수 있습니다.

천마디 말보다 하나의 예가 낫다

동기 API를 사용하여 이상해씨를 가져오려고 시도하는 다음 코드를 상상해 보세요. :

이 코드는 동기 API를 사용하여 데이터를 가져오는 것이 일반적이지 않기 때문에 이상할 수 있습니다. customFetch 안으로 들어가 보겠습니다. 기능 구현:

아 잠깐! 이건 절대 가져오기처럼 보이지 않습니다! 이 기능의 목적이 무엇인지 전혀 모르겠습니다...

자, 구성요소 주변에 뭔가가 있다고 상상해 보세요. , 다음과 같은 광섬유를 가정해 보겠습니다.

잠시 시간을 내어 코드를 읽어보세요.

이제 customFetch로 이동해 보겠습니다. 구현:

이전 스니펫에서 중요한 부분은 try/catch입니다. 차단합니다.

다양한 코드 조각을 통해 무슨 일이 일어나고 있는지 요약해 보겠습니다.

  • Pokemon 구성 요소가 customFetch를 호출합니다. 방법입니다.
  • customFetch 메소드가 내부 캐시를 읽으려고 시도하지만 비어 있습니다. 그래서 그것은 뭔가를 던집니다 / 어딘가 — 대수적 효과.
  • fiber 부모는 해당 정보를 포착하여 처리하고 데이터를 가져옵니다. 그런 다음 customFetch를 채웁니다. 데이터와 함께 캐시합니다.
  • Component(args)에서 다시 렌더링이 발생합니다. 그리고 이제 customFetch 캐시가 가득 찼습니다. 이제 동기 API를 사용하여 구성요소에서 데이터를 사용할 수 있습니다.

react-cache을 살펴보세요. 구현 세부정보를 확인하고 다양한 던지기 방법을 확인하세요.

이 과정에서 주의를 끌었던 내용이 있을 수 있습니다:render 두 번 호출되었습니다. 오류 발생을 위한 하나 — 일시중지 구성요소 — 및 데이터 가져오기 — 재개 구성 요소. 여러 개의 render를 트리거하는 React에서는 괜찮습니다. 순수한 함수이기 때문에 호출합니다. 그 자체로는 부작용이 없습니다.

잠깐… 뭐? render 부작용은 없나요? DOM은 어떻습니까?

반응 단계

오랫동안 React를 사용했다면 여러 번 다시 렌더링하는 것은 좋은 습관이 아니라는 말을 들어보셨을 것입니다. Fiber 아키텍처 이전에는 렌더링 함수를 호출할 때마다 React가 내부 계산을 수행한 다음 그에 따라 DOM을 수정했습니다. 예를 들어 setState를 통해 render 함수를 호출할 때 이런 일이 발생했습니다. . 프로세스가 인라인되었습니다:

setStaterender → 가상 노드 비교 → DOM 노드 업데이트

섬유를 다루는 과정은 약간 다릅니다. 고성능 DOM 수정을 가능하게 하는 대기열 및 배치 개념을 도입했습니다.

아이디어는 아주 간단합니다. 우리는 화면이 초당 최대 60프레임을 실행할 수 있다고 가정합니다. 이 가정과 사용 가능한 JavaScript 함수를 사용하면 ~16.7ms마다 일부 계산과 DOM 수정을 수행하는 것이 가능합니다. Fiber를 사용하면 React는 여러 수정 사항을 대기열에 추가하고 초당 약 60회 커밋할 수 있습니다.

이러한 종류의 수정을 통해 React는 고유한 장점과 특징을 지닌 세 단계로 나눌 수 있었습니다:

React 캐시, 시간 분할 및 동기식 API 가져오기에 대해 자세히 알아보세요. _[React에 관한 Dan Abramov 단계](https://twitter.com/dan_abramov/status/981712092611989509/photo/1?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwter m%5E981712092611989509&ref_url=https%3A%2F%2Fmedium.com%2Fmedia%2Fbda1c34a16e9f8a8e3eb244716a1da72%3FpostId%3D2a57dc9c2e6d" rel="noopener" target="공백" title=")

  • 렌더링 단계는 순수하고 결정적입니다. 부작용이 없으며 구성되는 다양한 기능을 여러 번 호출할 수 있습니다. 렌더링 단계가 중단될 수 있습니다render이 아닙니다. 일시 정지 모드에 있는 기능이지만 전체 단계
  • 커밋 전 문구는 읽기 모드에서 스크롤바 위치와 같은 실제 DOM 상태에 대한 액세스를 제공하는 것을 목표로 합니다.
  • 커밋 단계는 실제로 DOM을 수정하며 중단되지 않습니다. . 해당 단계에서는 React를 일시 중지할 수 없습니다.

이 세 단계 세트에는 시간 분할 기능이 도입되었습니다. React는 두 구성요소 함수 호출 사이에서 렌더링 단계 동안 일시 중지하고 필요할 때 해당 단계를 재개할 수 있습니다.

섬유에서는 render 사용 가능한 최신 표현을 얻는 것만을 목표로 합니다. 내부 상태를 기반으로 구성 요소를 비교하여 React가 DOM을 변경해야 하는지 여부를 알 수 있습니다. 커밋 수정이 필요한 경우 수정 사항이 "진행 중인 작업" 대기열에 추가됩니다.

React 팀은 React Concurrent(Time Slicing + Suspense) 및 파이버 아키텍처 덕분에 성능이 크게 향상되었습니다. 그들은 이벤트 우선순위 지정 및 동시성과 같은 다양한 브라우저 문제에 대응하기 위한 해결 방법을 만들었습니다.

한발 물러서면 그들이 보여준 모습이 아닐까? 우선순위 지정은 브라우저와 프런트엔드 프레임워크에 대한 새로운 과제인 것 같습니다.

다른 팀들도 실제 기술 수준을 개선하기 위해 노력하고 있으며 미래의 API를 제안하기도 합니다. Google의 견해는 다음과 같습니다.

무료로 코딩을 배우세요. freeCodeCamp의 오픈 소스 커리큘럼은 40,000명 이상의 사람들이 개발자로 취업하는 데 도움을 주었습니다. 시작하세요