(번역) 자바스크립트 하이드레이션은 임시방편이지 해결책이 아닙니다 - by Miško Hevery

superlipbalm·2022년 6월 15일
16

FE 글 번역

목록 보기
2/3

원문: https://thenewstack.io/javascript-hydration-is-a-workaround-not-a-solution/
좋은 글을 작성해 주시고 번역을 허락해 주신 Miško Hevery께 감사드립니다.

웹 개발에서 하이드레이션(Hydration)은 서버에서 렌더링 된 HTML에 상호 작용을 추가하는 기술입니다. 이는 클라이언트 측 자바스크립트가 이벤트 핸들러를 HTML 요소에 부착해 정적 HTML 웹 페이지를 동적 웹 페이지로 변환합니다.

그러나 이벤트 핸들러를 DOM(Document Object Model)에 부착하는 것이 하이드레이션에서 가장 어렵거나 비용이 큰 부분은 아닙니다.

이 글에서는 하이드레이션이 오버헤드라고 생각하는 이유를 설명드리고자 합니다. 하이드레이션은 해결책이 아닙니다. 이 방법은 특히 모바일에서 메모리를 소비하고 시작 속도를 늦춥니다. 이 글을 통해 오버헤드를 피하면서 동일한 결과를 얻을 수 있는 방법을 설명드리겠습니다.

하이드레이션 깊게 파고들기

하이드레이션의 어려운 부분은 우리가 필요로 하는 이벤트 핸들러와 부착할 곳을 아는 것입니다.

  • WHAT: 이벤트 핸들러는 이벤트의 동작을 포함하는 클로저입니다. 사용자가 해당 이벤트를 발생시켰을 때 실행해야 할 작업입니다.
  • WHERE: 이벤트 핸들러를 부착해야 할 DOM 요소의 위치(이벤트 타입을 포함해서)

추가된 복잡성은 WHAT 이 APP_STATEFW_STATE를 담는 클로저라는 것입니다.

  • APP_STATE: 애플리케이션의 상태입니다. APP_STATE는 대부분의 사람들이 상태로 생각하는 것입니다. APP_STATE가 없다면 어러분의 애플리케이션은 사용자에게 동적으로 표시해 줄 것이 없게 됩니다.
  • FW_STATE: 프레임워크의 내부 상태입니다. FW_STATE가 없다면 프레임워크는 업데이트해야 할 DOM 노드가 어느 것인지, 언제 업데이트해야 할지 알 수 없습니다. 예를 들어 컴포넌트 트리와 렌더 함수에 대한 참조가 있습니다.

그렇다면 WHAT과 WHERE을 어떻게 복원할 수 있을까요? HTML로 렌더링 된 컴포넌트를 다운로드하고 실행함으로써 가능합니다. 이는 큰 비용이 드는 부분입니다.

즉, 하이드레이션은 브라우저에서 앱 코드를 실행해 APP_STATEFW_STATE를 복원하는 방법으로 다음을 포함합니다.

  • 컴포넌트 코드 다운로드.
  • 컴포넌트 코드 실행.
  • 이벤트 핸들러 클로저가 가질 WHAT(APP_STATE와 FW_STATE) 그리고 WHERE을 복원.
  • WHAT(이벤트 핸들러 클로저)를 WHERE(DOM 요소)에 부착.

처음 세 단계를 복원 단계라고 부르겠습니다.

복원은 프레임워크가 응용 프로그램을 재구성(rebuild)하려고 할 때를 말합니다. 재구성하려면 애플리케이션 코드를 다운로드하고 실행해야 하기 때문에 비용이 많이 듭니다.

복원에 걸리는 시간은 하이드레이션되는 페이지의 복잡성에 정비례하며, 모바일 장치에서 10초 이상 소요되기 쉽습니다. 복원은 비용이 많이 드는 부분이기 때문에 대부분의 애플리케이션은 특히 모바일에서 최적의 시작 성능을 발휘하지 못합니다.

복원 또한 오버헤드입니다. 이는 서버가 서버 사이드 렌더링(server-side rendering, SSR) 또는 정적 사이트 생성(static site generation, SSG)을 하며 이미 수집했던 정보를 재구성합니다. 클라이언트에 이 정보를 보내는 대신 삭제했기 때문에 클라이언트는 서버에 이미 있는 것을 재구성하기 위해 비용이 많이 드는 복원을 수행해야 합니다. 서버가 정보를 직렬화해 HTML과 함께 클라이언트로 전송했다면 이를 피할 수 있었을 것입니다. 직렬화된 정보는 클라이언트가 HTML의 모든 컴포넌트를 다운로드하고 실행하는 것을 막아줍니다.

즉, 서버가 이미 SSG 또는 SSG의 일부로 실행한 코드를 다시 실행하는 것은 하이드레이션을 순수한 오버헤드로 만드는 것입니다.

리주머빌리티(Resumability): 오버헤드 없는 하이드레이션의 대안

오버헤드를 제거하려면 프레임워크는 복원뿐만 아니라 위에서 말씀드린 네 번째 단계인 WHAT을 WHERE에 부착하는 작업도 피해야만 합니다.

이 작업에 드는 비용을 피하려면 다음 세 가지가 필요합니다.

  • WHAT, WHERE, APP_STATE 그리고 FW_STATE를 포함한 HTML의 일부로 직렬화된 모든 필수 정보
  • 이벤트 버블링에 의존해 모든 이벤트를 가로채는 전역 이벤트 핸들러. 특정 DOM 요소에 대해 모든 이벤트를 일일이 등록해야 하는 번거로움을 없애줍니다.
  • 이벤트 핸들러(WHAT)를 지연 복원할 수 있는 팩토리 함수

위 구조는 리주머블(resumable) 합니다. 서버가 이미 수행한 작업을 반복하지 않고 서버가 작업을 중단한 지점에서 작업을 재개할 수 있기 때문입니다. 사용자 이벤트에 대한 응답으로 WHAT을 지연 생성함으로써 하이드레이션에서 발생하는 모든 불필요한 작업을 피할 수 있습니다. 이 모든 것은 오버헤드가 없다는 것을 의미합니다.

메모리 사용량

DOM 요소는 요소의 수명 동안 이벤트 핸들러를 유지합니다. 하이드레이션은 모든 리스너를 즉시 생성하므로 시작할 때 메모리를 할당해야 합니다.

반면에 리주머블한 프레임워크는 이벤트가 발생되기 전까지 이벤트 핸들러를 생성하지 않습니다. 따라서 하이드레이션보다 적은 메모리를 소비합니다. 또한 이벤트 핸들러는 실행 후 해제되어 메모리를 반환합니다.

어떤 면에서 메모리를 해제하는 것은 하이드레이션의 반대입니다. 이는 프레임워크가 특정 WHAT을 지연 하이드레이션하고, 실행한 다음 디하이드레이션하는(dehydrate) 것과 같습니다. 핸들러의 첫 번째 실행과 n 번째 실행 사이에는 큰 차이가 없습니다.

성능 차이

이 아이디어를 실행에 옮기기 위해 저희는 "리주머빌리티(resumability)"를 중심으로 설계되고 빠른 시작을 달성한 프레임워크인 Qwik 을 만들었습니다. 리주머빌리티가 미치는 영향을 보여주기 위해 Cloudflare edge에서 실행되는 to-do 앱 데모를 만들었습니다. 이 페이지는 약 50ms 내에 상호 작용할 준비가 됩니다.

또한 저희는 저희 웹사이트인 builder.io를 리주머블 전략과 Qwik을 사용해 다시 만들었습니다. Qwik과 저희의 다른 솔루션인 Partytown을 사용해 저희 사이트에서 자바스크립트를 99% 줄이고 100/100의 PageSpeed 점수를 얻을 수 있었습니다.(하이드레이션을 사용한 이전 페이지를 방문해 성능 차이를 직접 비교 경험해 보실 수 있습니다.)

결론

간단히 말해, 하이드레이션은 중복 작업을 하기 때문에 오버헤드입니다. 서버는 WHERE과 WHAT(APP_STATE와 FW_STATE)을 구성하지만 정보는 클라이언트를 위해 직렬화되는 대신 삭제됩니다. 그다음 클라이언트는 애플리케이션을 재구성하기에 충분한 정보가 없는 HTML을 받습니다. 정보가 부족하면 클라이언트는 WHERE과 WHAT을 복원하기 위해 애플리케이션을 즉시 다운로드하고 실행해야 합니다.

대안이 되는 접근법은 리주머빌리티입니다. 리주머빌리티는 모든 정보(WHERE과 WHAT)를 서버에서 클라이언트로 전송하는 데 중점을 둡니다. 사용자 상호 작용만이 클라이언트가 해당 상호 작용을 처리하기 위해 코드를 다운로드하도록 합니다. 클라이언트가 서버에서 했던 작업을 반복하지 않으므로 오버헤드가 아닙니다.

🚀 한국어로 된 프런트엔드 아티클을 빠르게 받아보고 싶다면 Korean FE Article(https://kofearticle.substack.com/)을 구독해주세요!

profile
FE 개발을 하고 있어요🌱

2개의 댓글

comment-user-thumbnail
2022년 6월 18일

잘 보고 갑니당 ㅎㅎ

1개의 답글