원문 : https://kentcdodds.com/blog/remix-the-yang-to-react-s-yin
저는 2015년부터 React 애플리케이션을 개발해왔습니다. 그 이후로 React 덕분에 개발 생산성이 크게 향상했습니다. 상태를 기반으로 UI를 렌더링하는 React의 선언적 모델은 웹용 UI 구축을 구축하는 방법을 크게 단순화했습니다. 또한 이전에 Angular.js와 Backbone으로 작업했던 것보다 훨씬 앞서서 상태에 대해 생각할 수 있는 좋은 방법을 제공했습니다.
React의 슬로건은 다음과 같습니다.
사용자 인터페이스를 만들기 위한 자바스크립트 라이브러리
React는 스스로 개척한 선언형 컴포넌트 모델을 제공함으로써 이를 잘 처리합니다. 상태(콤보박스 메뉴가 열림
또는 닫힘
같은)를 관리하지 않고는 사용자 인터페이스를 구축할 수 없습니다. 이것이 React에 컴포넌트 상태 관리가 있는 이유입니다.
문제점은 웹 애플리케이션에는 로컬 컴포넌트 상태보다 더 많은 것이 있다는 것입니다. 사실, 일반적인 React 애플리케이션에 로드되는 "상태"의 대부분은 상태가 아니라 서버(예를 들어 데이터베이스와 같은 양속 계층에서 가져온 것)에서 가져온 상태의 캐시입니다. React는 항상 우리에게 상태를 관리하는 좋은 방법을 제공했지만, 우리가 관리하는 상태 대부분이 실제로 캐시이고 캐시 문제로 고통받고 있다는 사실을 숨길 수 없습니다.
Phil Karlton의 유명한 인용문에서는 다음과 같이 말합니다.
컴퓨터 과학에는 캐시 무효화와 네이밍이라는 오직 두 가지의 어려운 점이 있습니다.
여러모로 농담이긴 하지만 캐시 무효화는 확실히 어려운 문제입니다. 그리고 이를 더 쉽게 만들기 위해 지금까지 React를 중심으로 구축된 무수한 라이브러리와 도구들이 입증하듯이, React는 이 문제를 관리하기 위해 즉시 사용할 수 있는 기능을 제공하지 않았습니다. Redux(툴킷), MobX, Apollo, React Query, SWR 등 무엇을 사용하든, 이 도구들을 사용하는 이유는 React가 내부적으로 해결책을 제시하지 않는 공통된 웹 개발 이슈가 있기 때문입니다.
네트워크 캐즘(chasm) 관리
역주: 캐즘(chasm)이란 본래 지질학에서 사용되는 전문용어로 지층이 이동하면서 생긴 골이 깊고 넓어 건너기 힘든 커다란 단절을 의미합니다. 본문에서는 클라이언트와 서버가 단절되었다는 의미에서 캐즘이라는 단어를 사용했습니다.
URL : https://terms.naver.com/entry.naver?docId=17079&cid=43659&categoryId=43659
네트워크 캐즘은 무엇입니까?
네트워크 캐즘이 의미하는 바는 다음과 같습니다.
웹 개발자로서 우리는 클라이언트(브라우저)와 서버에서 실행되는 코드를 작성하게 됩니다. 우리는 네트워크를 제어할 수 없습니다. 이것이 우리가 캐싱에 대해 먼저 생각해야 하는 이유입니다. 사용자가 타코🌮 를 선택할 때 React 컴포넌트가 리렌더링 되면, 특정 타코가 사용할 수 있는 옵션에 동기식으로 접근할 수 있어야 합니다 🤤. 그래서 우리는 네트워크를 통해 HTTP 요청을 하고, React 상태(또는 일부 라이브러리)를 통해 해당 값을 메모리 내 캐시에 저장해서 리렌더링할 수 있도록 합니다.
크고 작은 앱 안에서 버그의 원인 중 일등이 뭔지 아시나요?
바로 코드입니다.
네트워크 캐즘은 엄청난 양의 코드 소스를 말합니다. 그것을 바로잡는 것은 매우 어렵지만 우리는 웹 앱을 만들고 있으므로 시도해야 합니다. 따라서 JavaScript, 최신 페치 API 및 편리한 일부 라이브러리를 사용해서 HTTP를 통해 네트워크 캐즘 위에 갈고리(grappling hook)를 쏴서 백엔드와 데이터를 주고받습니다.
역주 : grappling hook은 다음 링크를 참조하세요.
이 갈고리가 동작하는 데 필요한 코드는 모두 프런트엔드에 있습니다. 데이터 페칭의 경우 페치할 데이터를 알아야 하는데 이는 대체로 어려운 문제입니다. 데이터 페칭 코드는 데이터를 필요로 하는 코드와 같은 위치에 배치하기를 좋아하기 때문입니다(이러한 방식으로 작업을 수행하여 버그/실수/데이터 오버페치를 크게 줄입니다). 이것은 컴포넌트가 렌더링될 때까지 데이터를 페치할 수 없다는 안타까운 부작용이 있습니다.
여기에 앱 로드를 더 빠르게 하기 위해 코드 스플리팅(code-splitting)하길 원하게 되고, 그러면 컴포넌트가 렌더링될 때까지 기다려야 할 뿐만 아니라 렌더링이 시작되고 페치를 수행하기 위한 코드도 가져와야 합니다. 이것은 네트워크 워터폴로 이어집니다(그리고 우리는 모두 워터폴의 위험에 대해 알고 있습니다).
불행히도 데이터 페칭 자체로는 이 문제를 해결할 수 없습니다. 사실, 데이터 페칭을 위한 React Suspense조차도 이 문제를 해결할 수 없습니다. Suspense는 컴포넌트 내에서 데이터를 가져올 수 있다는 점에서 많은 데이터 페칭 라이브러리를 대신할 것입니다(그리고 아직 캐시되지 않은 경우 가져와야 할 데이터를 트리거해서 가져옵니다). 워터폴 효과를 피하려면, 해당 컴포넌트의 코드가 렌더링되기 전에 데이터 페치를 시작해야 합니다.
더 빠르게 페칭
제가 Remix에서 좋아하는 많은 부분을 React Router로 가져와서, React Router가 이 문제를 해결하게 되어 매우 기쁩니다. Ryan은 그의 Remixing React Router 포스트에서 이에 관해 설명합니다. 레이아웃 중첩 경로와 loaders
(데이터 가져오기) 및 actions
(데이터 뮤테이션) 기능을 사용해서, 데이터 페칭 작업은 컴포넌트로부터 분리하면서 같은 위치에 배치함으로써 갖는 이점은 그대로 얻을 수 있습니다. 이 경우 페칭 코드는 컴포넌트 안에는 없을 수도 있지만, 중첩된 레이아웃 경로의 특성으로 인해 매우 가깝습니다.
이러한 기능을 통해 "데이터 요구 사항을 알기 위해 렌더링해야 한다."에서 "URL의 데이터 요구 사항을 알고 있습니다."로 갑니다.
게다가 React Router는 이제 그 네트워크 케즘의 일부를 관리합니다. 즉, 로딩/에러 상태를 위한 코드의 양이 훨씬 줄어든다는 의미입니다. 또한 React Router가 캐시 재검증을 처리할 수 있음을 의미합니다! 아, 그리고 폼 재제출(form resubmissions)과 경쟁 상태(race conditions)도 처리할 수 있습니다(UI 개발에서 좀 더 어려운 문제들). 그리고 우수한 사용자 경험(낙관적인 UI 패턴처럼)을 구축하는 것이 그 어느 때보다 쉬워졌습니다. 이렇게 하면 네트워크 캐즘을 효과적으로 좁힐 수 있습니다.
우리가 더 잘할 수 있을까요?
React Router에 이러한 기능이 있다는 건 코드를 단순화하고 앱 속도를 높이려는 사람에게 큰 이점이 될 것입니다. React Router는 데이터 페칭을 위해 React Suspense를 사용하는 모든 사람에게 가장 좋은 친구가 될 것입니다(Meta가 가지고 있는 인프라/컴파일러/라우터가 없다면).
하지만 우리는 더 잘할 수 있습니다. 더 일찍 브라우저에서 페칭을 시작하더라도, 사용자는 여전히 화면표시를 위해 초기 JavaScript 번들이 나타나고 실행되기까지 기다려야합니다. 데이터 로딩 및 뮤테이션 관리를 도와주는 React Router를 사용하면 많은 상태(캐시) 관리 코드를 삭제할 수 있지만, 여전히 브라우저에 남아 있습니다. 그 밖에도 페치된 데이터를 필요로 하는 코드를 가져오기 전에, 먼저 페치를 수행할 코드가 필요하기 때문에 더 이상 코드 분할(code-split)을 할 수 없습니다.
모든 코드를 브라우저에서 서버로 옮길 수 있다면 좋지 않을까요? 데이터베이스와 통신하거나 개인 키를 필요로 하는 API를 호출할 때마다 서버리스 함수를 작성하는 것이 귀찮지 않나요? (예 그렇습니다). 이것들은 React 서버 컴포넌트가 우리를 위해 해준다고 약속한 유형의 것이고, 우리는 확실히 데이터 로딩을 기대할 수 있습니다. 하지만 뮤테이션에 대해서는 아무것도 하지 않기 때문에 해당 코드를 브라우저 밖으로 옮기는 것이 좋습니다(그 뿐만 아니라 출시될 때까지 기다릴 필요가 없습니다).
무대 오른쪽에 입장: Remix 💿
앱을 한 단계 더 높이려면 앱을 서버가 렌더링해야 합니다. 그리고 이를 위한 가장 좋은 방법은 Remix를 사용하는 것입니다. Remix는 당신이 그것에 대해 생각할 필요조차 없는 방식으로 당신을 위해 네트워크 캐즘을 가로지르는 브릿지를 완성합니다. 모든 데이터 페칭 및 데이터 뮤테이션 코드를 가져와서 기존의 "Remix 경로 모듈"로부터 export된 함수로 이동합니다. 그러면 해당 코드는 서버에 남아 있고 Remix가 전체 네트워크 캐즘을 처리합니다.
이제 사용자가 더 이상 JavaScript가 로드될 때까지 기다릴 필요가 없으므로 앱은 정말 날아갈 수 있습니다. 앱은 준비되어 있습니다(그리고 점진적 개선 덕분에 모든 링크와 폼들은 JavaScript가 백그라운드에서 다운로드되는 동안에도 동작합니다).
이제 서버에서 실행되는 코드를 작성할 수 있으므로 직접 데이터베이스를 호출하거나 개인 키로 API를 호출하는 것에 대해서 더 이상 걱정할 필요가 없습니다. 로더(loaders)와 액션(actions)들은 서버에서만 실행되므로 필요한 모든 작업을 수행할 수 있습니다. DX를 멋지게 개선합니다!
앱 전체
Remix는 서버의 역할을 제공합니다. 이는 필요시 앱 전체를 다룰 수 있다는 것을 의미합니다. 모든 사람이 이런 식으로 일하기를 원하는 것은 아니지만 데이터베이스 및 타사 서비스와 직접 통신할 수 있는 백엔드가 있으므로 앱 구조를 다음과 같이 만들 수 있습니다.
멋진 점은 Remix를 꼭 100%로 사용하지 않더라도 Remix를 사용하면 충분히 관리된 네트워크 캐즘의 모든 이점을 얻을 수 있다는 것입니다. 따라서 기존 백엔드에 만족한다면 계속 이것을 사용할 수 있습니다.
결론
React의 슬로건은 다음과 같습니다.
사용자 인터페이스를 만들기 위한 자바스크립트 라이브러리
그리고 그 일을 훌륭하게 수행합니다. React는 "네트워크 캐즘 관리"를 약속한 적이 없지만 모든 웹 애플리케이션은 이를 필요로 합니다. Remix가 네트워크 캐즘을 관리하면서 마침내 React의 음에 양을 갖게 되었습니다. 훌륭한 렌더링 라이브러리와 훌륭한 네트워크 캐즘 관리자를 사용하면 더 적은 수의 버그, 더 간단한 코드, 더 많은 재미로 더 빠르고 더 나은 웹 응용 프로그램을 구축할 수 있습니다.
개인적으로 이것이 제가 Remix로 웹 앱을 구축하는 것을 사랑하게된 이유입니다. 오늘 이 글을 읽고 있는 웹사이트도 Remix로 재작성한 결과입니다. 시작했을 무렵에는 이것이 어떤 멋진 일이 될지 전혀 몰랐습니다. Remix는 이 모든 것을 가능하게 했습니다. 기본적인 기능을 모두 끝냈을 때 훨씬 더 많은 일을 할 수 있는 시간과 능력이 있다는 것을 깨달았기 때문입니다((내 사이트를 재작성한 자세한 내용은 여기를 참조하세요.. Remix는 내가 가지고 있는 재미있는 아이디어에 "예"라고 말할 수 있을 것 같은 느낌을 주었고 정말 신선했습니다.
이 정보가 더 나은 웹사이트를 구축하는 데 도움이 되기를 바랍니다. 안녕히 계세요 😎
'아티클 번역' 카테고리의 다른 글
[번역] JavaScript 패키지 매니저 비교 - npm, Yarn 또는 pnpm? (0) | 2022.12.11 |
---|---|
[번역] React에 SOLID 원칙 적용하기 (0) | 2022.12.11 |
[번역] Reduce에 대한 10가지 필수 JavaScript 트릭 및 팁 (0) | 2022.12.11 |
[번역] Remixing React Router (0) | 2022.12.11 |
[번역] 누구나 자바스크립트 제너레이터 함수가 필요한 이유는 무엇인가요? (0) | 2022.12.11 |