커리어리 알림을 통해 재미있는 게시글을 추천받았다. React를 메인 기술스택으로 사용하고 있는 입장이라 흥미롭게 읽을 수 있는 내용인 것 같아 번역을 시도해보았다. (오역,의역이 다수 포함되어있으니 잘못된 부분을 발견하여 알려주시면 감사하게 수정하도록 하겠습니다!)
많은 사람들 처럼, 오로지 내가 듣던 음악이라고는 그저 내 지역 라디오 방송국에서 틀어져있는 음악이었던 시절이 있었다. (나이가 30대가 넘은 많은 사람들에게는 익숙한 이야기이라고 해야할까 아무튼 이 이야기가 와닿지 않더라도 조금 기다리고 나와함께 해주길 바란다.) 그때에 나는 그냥 그 사실로 행복했다. 그것이 내가 필요한 전부라고 느껴졌기 때문이다.
뒤돌아 생각해보니, 나는 한 가지 사실을 깨달았다. 나는 그냥 순진하게 그저 좋기 때문에 필연적으로 유명해졌을 것이라는 사실을 믿었던 것이라는 것을. 그리고 그렇다고 생각했기 때문에 내가 알 필요가 있는 것은 당연히 내게 자연스럽게 다가올 것이라는 것을.
결국 다른 음악들이 내 삶에 영역에 자리잡기 시작하기는 했다. 나의 새 친구들과 인터넷을 통해서 나는 새로운 아티스트들과 내가 과거에 좋아했었던 것들로 부터 꽤 멀리 떨어져있는 것들에 익숙해지기 시작했다. 아니 적어도 내가 좋아한다고 생각했던 것들에서부터 말이다.
이러한 음악들은 달랐다. 일주일동안 들어도 좋아지지가 않았고, 그 뒤에는 질려버리기 일쑤였다. 나는 이러한 음악을 계속해서 영원히 들을 수 있을 것 같지 않았다.
그런데 사실은 그 정반대였다고 말해야할 것이다. 왜냐하면 그 음악들은 들으면 들을수록 나를 실제로 그것들을 좋아하게 만들었고 또 그것들에 대해서 더 잘 느낄 수 있었기 때문이다. 그곳에는 깊이가 있었다. 물론, 그런 음악들이 어느정도 크게 뒤틀려있는 일렉기타 소리를 가지고 있지도, 머리를 한대 맞은 듯한 가사들을 가지지도, 내가 그때까지 퍽 잘 즐기던 술술 잘 넘어가는 멜로디들을 가지고 있지는 않았지만 말이다. 하지만 놀랍게도 이러한 사실들은 그 음악들을 더 좋게 만들면 만들었지 나쁘게 만들지는 않았다.
그때 나는 깨닫게 되었다. '어쩌면 나는 내가 생각했던 것보다 꽤 만족하지 못하고 있는 상태가 아닐까?' 어쩌면 사실 내 진정한 축복은 무지속에 숨겨져 있던 것일지도 몰랐다.
나는 당신 또한 내가 한 이야기에 공감할 수 있을 것이라고 생각한다. 딱히 음악이란 부분에 특정하지 않더라도 말이다. 대부분 아마도 지금 당신이 정말 좋아하는 음식이나 마실 것이 아니더라도 좋아진 경험이 있던 사실을 떠올리거나 아니면 당신과 전혀 어울리지 않을 것이라고 생각했던 영화, 책, 게임, 팟캐스트, 인플루언서, 혹은 취미들을 떠올릴 수 있을 것이다. 세세한 사실들은 중요하지않다. 내가 진정 말하고자 하는 바는...
당신은 아마도 유명한 대세들(defaults)의 주변을 넘어서 어떤 꽤 괜찮은 것을 찾아낸 경험을 가지고 있을 것이라는 사실이다.
딱히 고급스러운 척하는 프론트엔드 힙스터처럼 들리지는 않겠지만 그게 내 관심사는 아니다. 간단하고 핵심만 얘기하는 걸 좋아한다면 좋다! 지금부터 이야기 하겠다. 내가 진정 하려고 했던 것은 조심스럽게 당신은 자신도 모르게 당신 스스로를 꽤 괜찮은 것들로부터 벽을 치면서 살아왔을지도 모른다는 생각을 나누는 것 이다.
편하고 익숙한 것들을 넘어서 더 좋은 것들을 찾아 나선다는 이러한 생각 전체가 우리의 삶의 어떠한 영역에도 영향을 끼칠 수 있는 것처럼, 아마도 우리의 도구들과 일하는 방식에도 적용될 수 있을 것이다.
그리고 어쩌면, 정말로 어쩌면, 당신이 진정한 만족을 찾을 수 있게 도와줄 수 있을 것이고 그렇지는 못하더라도 적어도 당신이 놓치고 있는 사실들을 모르고 지나가지 않게끔은 해줄 수 있을 것이다.
전에 어떻게 React가 프론트 프레임워크 분야에서 새로운 대세가 되었는가 에 대해서 작성한 적이 있다. 그런데, 나는 많은 사람들이 React를 일상적으로 사용하면서 그것이 얼마나 뒤쳐졌는가에 대해서 깨닫는다고 생각하지 않는다.
그리고 바로 이때 우리의 비유에서 무언가가 부족해지기 시작한다.
만약 우리가 그저 우리들의 개인적인 취향에 대해서 이야기하고 있을 뿐이라면 나는 '삶이 어쩌고 저쩌고... 당신의 삶을 바꾸고...' 하는 그런 블로그포스팅을 쓰지 않을 것이다. (특히 내 정도의 나이대를 살고서는 말이다) 누가 신경이나 쓰겠는가? 당신이 좋아하고 만족한다면 그걸로 충분하다.
하지만 음악이나 다른 당신의 삶에 만족에 관한 어떤 부분과 달리, 우리가 프론트엔드 영역에서 도구를 선택하는 일은 다른 누군가에게 경험적으로 측정할 수 있는 영향을 끼친다.
그 선택은 실질적인 책임을 동반한다. 그것은 단순히 우리가 좋아하고 말고의 문제가 아니다. 만약 우리가 순수하게 우리 자신을 위해서 무언가 만들고 있는 것이 아니라, 진지하게 개발의 영역에 관한 선택을 내리는 것이라면 우리의 만족은 두 번째 순서이다. 사용자의 경험, 그것이 가장 중요한 전제이다.
당신이 만약 당신의 도구들을 좋아한다면, 좋다. 그것은 참 잘된 일이고 나는 당신이 그러기를 바란다. 그런데 그건 아무리 잘쳐줘봐야 곁가지에 불과하다. 하지만 최악의 경우에 그것은 아주 끔찍하게 당신을 훼방놓을 가능성을 지니고 있다. 개발자 경험(DX, Developer Experience)은 절대로 사용자 경험(UX, User Experience)을 앞서서는 안된다.
그러니 처음 시작을 좀 형편없는 비유를 통해 이야기를 시작했다고 하더라도 용서해주길 바란다. 나는 당신이 진정으로 원한다면, 당신의 남은 삶 동안 똑같은 음악을 매일 듣기를 바란다. 하지만 이 이야기가 우리의 도구의 선택에 관한 이야기라면, 우리는 우리가 가지고 있는 개인적인 기호와 편안함을 뛰어넘어 더 앞으로 나아가야만하는 매우 타당하고 중요한 이유들을 가지고 있다.
아마 React가 그것의 비교군들보다 뒤쳐졌다는 생각은 당신에게는 새로운 사실처럼 들릴 것이다. 많은 사람들과 같이 당신은 아직도 React가 현대 프론트엔드의 기준이라고 생각할테니까 말이다. 그러니 내용의 본론들로 들어가기전, 이 마지막 섹션에서 이러한 거품을 빠르게 터뜨려보도록 하자.
여기 Mastodon의 Alex Russel이 한 이야기 때문에 나는 이 블로그 포스팅을 작성하기 시작했다.
누군가 오늘 내게 IE를 지원할 필요가 없는 새로운 어플리케이션에서 React를 사용하는 경우가 있느냐고 물었다.
나는 어떤 하나의 이유도 생각해낼 수 없었다...
React가 이정도로 뒤쳐졌다는 게 굉장히 놀랍게 느껴졌다.
Alex는 해당 대화(thread)에서 React가 웹 컴포넌트(Web components)들에 대한 지원이 부족하다고 이야기한다. 해당 기능은 분명히 수년동안 React에서 빠져있었다. 그리고 맞다, "개발 예정 기능"에는 포함되어 있다. 하지만 지금 이 글을 작성하는 시점에서 해당 기능에 대해 명백히 구현된 부분이나 배포 시점이 공표된바가 없다.
반면, React 대신 당신이 선택할만한 대부분의 최신 프레임워크나 기술들의 경우 이미 이러한 기능에 대한 지원이 진행되고 있다.
웹 컴포넌트들은 이러한 부분의 한 영역이다. 이들은 밑에서 소개하게될 "다른 프레임워크들은 이미 했거나 더 잘하는 리스트" 들에서 일부에 불과하다.
React는 프레임워크 시장에 선두로 뛰어들어서 이점을 분명하게 얻을 수 있었다: 기준(standard)을 세울 수 있게 된 것이다. 하지만 이러한 점은 그들의 기민함과 적응성에 크게 부정적으로 작용하는 결과를 낳았다. React가 대략 처음 개시된 2013년 이래로, 그들이 내리는 모든 결정은 또 하나의 기술 부채를 얹는 것과 같았다. 하지만 그들의 기술 부채들은 다른 더 현대적인 프레임워크들에서는 전혀 구애받지 않는 사항들이었다.
Alex의 말을 한 번더 빌리자면 다음과 같다.
React는 08년도의 제한점들을 달고 설계된 13년도의 기술이다. 2023년에 놓고 보았을 때, 어떠한 점도 혁신적으로 다가오지 않는다.
사실 현대 시장에서 React는 "가장 느린 방법(the slowest way)"으로 함수형 반응형 프론트엔드를 프로그래밍 하는 방법일 것이다...
React는 나이가 들었다. 그리고 나는 많은 사람들이 그것이 얼마나 그리고 어느정도로 안좋게 나이가 들었는지 알지 못한다고 생각한다. 그러니 음악에 비유했던 도입부는 뒤로 하고, 위의 인용문으로 대체하도록 하겠다.
그 때 우리나라에서는 EXO의 '으르렁'이 유행하고 있을 때였다.
(새로운 테일러 스위프트 앨범 7개 발매 전이라는 뜻이다. 이건 심지어 테일러의 버전 릴리즈를 반영하지도 않은 것이다.)
만약 당신이 지난 몇년 동안 React가 당신의 개발 세계의 전부였던 개발자중에 한 명이라면, 아마 당신이 모르고 지나쳤을 (혹은 정말 존재하는지도 몰랐을) 여러가지 사실들이 존재할 수 있다. 당신이 React를 너무 오랫동안 사용해왔기 때문일 것이다.
현대 프론트엔드 생테계가 앞서 나갈수록, 우리는 많은 부분에서 React 왕이 다스리고 있는 세계가 더 이상 존재하지 않는 다는 사실을 매우 천천히 깨닫고 있다는 것을 알게 된다.(만약 그런게 실재로 존재했다면 말이다. Facebook이 직면했던 특정한 문제들과 비슷한 문제들을 가지고 있던 단체들은 많지 않았다.)
브라우저들은 지난 10년동안 Javascript 와 CSS 영역의 다양한 기술들을 받아들이면서 굉장히 공격적으로 성장했다. 기술과 사용자의 기대치는 계속해서 진화해왔고, 현재 도구들의 생태계에서는 당신이 다시 또 과거의 React를 도입해 하려는 것 보다 더 많은 것들이 이루어져 왔다. 그러한 레거시 소프트웨어들은 하지 못하는 방식을 통해서 말이다.
Side Note
나도 React를 레거시 소프트웨어라고 부르는 것이 논란이 있을 것이라는 걸 잘 알고있다. 하지만 나는 이게 맞다고 생각한다. React는 비교적 복잡하고 상대적으로 오래되었으며 여러 규칙들과 발목을 붙잡는 부분들을 많이 포함하고 있다. 초심자들은 자주 React에 대해서 겁내고 있으며, React가 따르고 있는 구조적인 결정들은 React의 반복 능력에 장애가 된지 꽤 오래되었다.
만약 당신이 내가 이 부분까지 사용한 현학적인 어휘들, 구구절절한 서문들, 괄호를 과도하게 사용해 참견하는 행위들을 참아낼 수 있었다면, 나는 당신이 React 세계에 너무 오랫동안 있었기 때문에 놓치고 넘어갈 수 있었던 몇 가지 사실들을 나누려 한다. 그래서 내가 소개한 것들이 당신의 현재 플레이리스트들보다 훨씬 좋을 수도 있음에 당신이 깜짝놀라길 바란다.
나는 이 주제에 관해서 다른 포스트에서도 다룬 바가 있다. 하지만 언제고 '증명되지 않은' 프레임워크의 이름이 개발 프로젝트의 하나의 도구로 거론되게 될 때면, 이에 관심있는 어떤 사람이든지 "얼마나 큰 생태계를 갖추고 있는가?"를 처음으로 질문하게 될 것이다.
당신은 아마 이 포스트의 첫 전제를 보자마자 이와 같은 생각을 했을 지도 모르겠다. "React를 버리고 다른 프레임워크로 갈아타라고? 그 프레임워크의 생태계가 얼마나 큰데?"
그런데 우리는 도대체 왜 생태계의 크기에 그토록 집착하고 있는 것일까?
그렇다, 우리는 그 프레임워크가 우리 앞에서 갑자기 사라지길 확실히 바라지 않기 때문이거나 몇 년뒤에 지원이 중단되기를 바라지 않기 때문일 것이다. 충분히 맞는 말이다. 그리고 사실이다. 우리는 너무 시작되지 얼마 안되어 너무 이르거나 증명되지 않은 농장에 투자하고 싶어하지 않을 것이다. 하지만, 'Vue', 'Svelte', 'Preact', 'Solid', 'Astro' 그리고 다른 많은 프레임워크들은 이미 이러한 지점을 넘어섰고 유지보수를 보장하는 환경을 지원하며 충분히 잘 관리되어지고 있다. 그러니 이러한 것들이 문제가 되는 부분은 아닐 것이다.
그렇다면 도대체 마음에 걸리는 부분이 무엇인가? 나는 이에 대한 하나의 가설을 가지고 있다.
"우리는 패키지들이 반드시 우리들이 사용하는 프레임워크에 적절하게 맞추어 개발 되어져야 한다고 훈련받았다."
당신은 jQuery 때 부터 이러한 마음 가짐이 시작되었다고 토로할지도 모르겠지만, 내 생각은 다르다. React가 이러한 풍조를 더 가속화시켰다.
React를 사용하면서 우리가 어떤 모듈이라던지, 위젯, 혹은 특별한 일을 하기 위한 라이브러리 (캐러셀, 지도, 아코디언 등의 어떤 것들)가 필요하다면 그것은 React의 것(React thing)이어야만 했다. 그저 순수한 웹 기반 이거나 바닐라 자바스크립트라면 충분하지 않았다. 모든 React의 규칙들과 상태들(states)을 다루는 행위들 그리고 컴포넌트 라이프사이클이라는 독특한 특징들이 의미하는 바는 패키지나 라이브러리가 특별하게 React 방식으로 작성되있지 않으면 작동하지 않을 것이라는 것을 의미했다.
React는 우리에게 특정 프레임워크에 맞추어서 이러한 것들이 개발되어져야 한다고 훈련시켰다. 하지만 이것은 더 이상 사실이 아니며, 이렇게 되어서는 안되었다.
우리는 이러한 것들을 필요로 해서는 안되었다. 특히 그 프레임워크가 만약 '그저 자바스크립트'일 뿐이라서 불평 불만하는 경우가 잦다면 더더욱 그랬다. 만약 그 패키지가 '그저 자바스크립트'일 뿐이라면 작동하지 않을 이유가 없기 때문이다.
물론 다른 프론트엔드 프레임워크들 또한 그들만의 상태와 구조들에 관한 규칙들과 컨벤션들이 존재한다는 사실을 알고 있다. 당연히 그러한 그들의 시스템에 대해서 위와 똑같이 얘기해도 괜찮다. 그리고 React와 마찬가지로 Svelte 나 Vue 또는 다른 프레임워크들에도 언제나 그들만의 시스템을 목표로 하고 그틀 안에서만 개발되어야하며 사용되어져야만하는 패키지들이 존재할 것이다.
하지만 근본적으로 아래와 같은 사실을 내가 강조할 수 있는 최대한 강조하고 싶다.
어떤 현대 프론트엔드 프레임워크든 간에, React만큼 플랫폼(웹, 자바스크립트 플랫폼)과 완고하게 호환되지 않는 환경을 제공하지 않는다.
만약 당신이 React가 아닌 다른 현대 도구들과 프레임워크들을 사용해서 개발을 진행하고 있다면, 바닐라 자바스크립트 패키지만으로 그저 충분할 가능성이 더욱 높다는 사실을 의미한다. (그리고 그러한 패키지들은 수 천개가 넘는다.) 그들은 렌더 사이클(render cycles)에서 문제를 일으킬 가능성이 더욱 적고, 특별하게 프레임워크에 관련된 문제들을 일으킬 가능성이 적다. 말할 것도 없이 웹 컴포넌트들을 사용할 수 있다는 옵션을 추가해줄 수도 있다.
당신은 그렇게 매번 프로젝트를 위해서 특별히 재단되어진 라이브러리나 패키지를 필요로 하지 않아도 된다. 왜냐하면 이미 당신이 만들고 있던 것은 아마도 세상에 플랫폼 환경 안에서 작동하고 있을 것이며, 세상에 나와있는 다른 패키지들과도 마찬가지일 것이기 때문이다.
Preact Signals가 이러한 경우의 훌륭한 예시라고 할 수 있다. 비록 Preact 환경에서의 사용을 전제로 하기는 하지만 어떠한 프레임워크에서든지 import 될 수 있고 사용될 수 있다. 심지어 바닐라 자바스크립트 환경에서도 말이다. 웹 컴포넌트 또한 React를 제외한 어떤 현대 프레임워크들과도 같이 공존할 수 있다.
프레임워크들을 사용하는 것이 조금 필요하지 않다고 느껴지는 시점으로, 플랫폼이 이미 당신이 필요한 것들을 전부 제공하고 있을 경우이다. (예를 들어, React에서 항상 고통스러운 지점이라고 짚어지는 폼 제출 기능을 들 수 있을 것이다. 양방향 데이터 바인딩 과 브러우저가 제공하는 컨벤션들을 사용하면 매우 매우 편하게 처리할 수 있다.)
그리고 최악의 경우는 React에서 있는 것을 사용하는 것보다 스스로 필요한 것을 만들어내서 사용하는 것이 훨씬 쉬운 경우일 것이다. (이를 위해 React의 useState 와 다른 프레임워크들의 상태 생성 패턴을 비교하는 것은 일도 아니다.)
강을 건너기 전에 가능한 한 모든 각도에서 모든 방법으로 치밀하게 계산하고 테스트 해보아야만 하는, 보수적인 개발자들에게 새로운 환경에 처해지는 것은 굉장히 큰 취약점으로 작용한다. 하지만 새로운 환경에 처해지는 것은 또한, 기술 부채를 줄이고 낡은 브라우저를 지원해야한다고 걱정하지 않아도 될 수 있는 이점으로도 여겨질 수 있다. 그리고 새로운 기능들은 현재 존재하는 좋은 아이디어들과 보다 현대적인 브라우저로부터 자유롭게 확장될 수 있다.
Hooks는 클래스컴포넌트를 대신하는 React에서 가장 새로운 혁신이었다. 칭찬해야할 것은 칭찬하도록 하자. Hooks는 프론트엔드 영역에서 거대한 변경점 중 하나였다. Hooks는 우리가 어떠한 방식으로 상태와 로직을 우리의 어플리케이션에서 구축하는지에 대해서 혁신적으로 뒤바꾸어 놓았다. Hooks는 부정할 것 없이 훌륭하며 거의 모든 프레임워크들에서 상태를 관리하는 Hooks와 닮은 모델을 개발하도록 만들었다.
하지만 React Hooks는 이제 더 이상 새롭지 않다. (사실, Hooks와 함께 안정적으로 동작하는 React 환경은 내 아이의 나이만큼이나 오래되었다. 내 아들은 몇 주후에 어린이집에 다니기 시작한다.)
Hooks 는 더이상 경쟁력있는 장점을 가지고 있지 않으며 심지어 주목할 만한 기능을 제공하지 않는다. 그들은 이제 그저 환경을 구축하는 기준선이 되었다. 어플리케이션이 그저 그렇게 동작하게 되는 방식, 그런 것 말이다.
모든 다른 프레임워크는 이러한 Hooks의 동작 방식을 자신들의 스타일로 구축해 내었으며 심지어 모든 것들이 더욱 빠르거나, 똑똑하거나, 사용하기 더 쉽거나, 심지어 세 가지 장점을 모두 포함하기도 한다.
Preact의 Signals는 이러한 말의 분명한 예시이다. Svelte의 매우 간단한 stores 또한 그렇다. Solid 또한 Signals를 가지고 있다. 심지어 Hooks에 영향을 받은 것이 분명해 보이는 Vue 3의 컴포지션 API 또한 React의 구현환경 보다 더 나은 핵심적인 장점들을 가지고 있다.
Hooks는 훌륭한 패턴이며, React는 이러한 방식을 대중화 시킨 것에 대한 공로를 인정받아야 마땅하다. 하지만 꽤 많은 수의 다른 프레임워크들은 Hooks를 더 나은 방식과 더 적은 규칙들과 더 적은 보일러플레이트 코드로 이를 제공하고 있다.
Side Note
Signals에 대한 개념에 익숙하지 않은 사람들을 위해서 준비했다. Signals는 반응형 상태(reactive state)의 개념을 실로 과하게 단순화시킨 것이라고 이야기할 수 있을 것이다. 반응형 상태의 다음 단계의 더 좋고 혁신적인 버전임을 포함하면서 말이다. Signals는 어떠한 환경에서 re-renders를 일으키는지에 대한 더 나은 기본 값들을 통해서 Hooks를 업데이트 하고, 모든 컴포넌트들을 re-render하는 대신 re-render가 필요한 node들에 한해서만 re-render를 일으킨다.
사실 고백할 것이 하나 있다. 나는 아직도 useMemo를 사용하는 것과 useCallback을 사용하는 것의 차이점이 정확히 무엇인지 알지 못한다. 또는 언제 사용해야하고 언제 사용하지 말아야할지도 알지 못한다. 심지어 오늘 이에 대한 관련 글들을 여러번 읽었음에도 불구하고 말이다. (농담이 아니다.)
두 번째로 고백해야할 것은 useEffect 의 의존성 배열에 어떠한 것이 들어가야 하고 어떤 것이 들어가면 안되는지에 또 왜 그래야하는지에 대한 개념이 내게는 아직도 직관적이지 못하다는 사실이다. 내가 매번 useEffect 함수를 작성할 때면, 나는 15분 정도를 내 린터가 마음에 들어하도록 리팩토링하는데 쓴다. 심지어 내가 작성한 것이 실제로 괜찮고 내 어플리케이션을 끝도 없는 공허속에 빨려들어가게 하지 않을 것이라고 99% 확신할 때에도 그렇다.
당신이 만약 React를 사용하고 있다면, 이러한 내 고백들에 대해서 아마 공감할 수 있을 것이라고 어느정도 확신한다. 그리고 만약 당신이 이러한 혼란과 모호함을 일반적이라고 받아들인다면 당신은 이 사실을 깨달아야 한다.
우리는 수 년동안 이러한 방식의 렌더링 사이클에 관한 미시적인 관리 방법을 다른 프레임워크에서 사용하지 않아왔다.
요즘 프레임워크들은 이러한 종류의 것들을 당신이 직접 어떻게 처리해야 하는지 설명할 필요 없이 알아서 해결해줄 수 있을 만큼 똑똑하다.
프레임워크들은 렌더링이 정말로 필요하지 않다면, 귀중한 리소스를 낭비하지 않을 수 있는 방법을 이미 알고있다. 이들은 필요한 값만을 업데이트하고 필요하지 않은 값을 계속해서 재계산하지 않을 수 있을만큼 똑똑하다.
...대부분은 그렇다는 말이다. 완벽한 프레임워크는 없다. 하지만 이들은 기본적으로 React가 활용하는 방식보다는 더 나은 방식으로 이것들을 수행해낼 수 있고, 더 효율적인 방식으로 이를 해결한다.
당신은 아마도 다른 프레임워크를 사용해서 프로젝트를 최적화하는 경험을 할 수도 있겠다. 그들도 완벽하지는 않다. 하지만 당신이 그러한 상황에 처해질 때, 당신은 과거 React에서 지나쳤어야 했던 지점들을 훨씬 훨씬 지난 후일 것이다.
당신이 만약 DOM에 삽입되어 어떠한 일을 하는 하나의 컴포넌트를 만들고 싶고 그 컴포넌트가 어떠한 다른 데이터나 변수에 따라서 그들의 값을 동적으로 재계산하게 만들길 원한다면, 다른 모든 프레임워크들은 useEffect를 사용하는 것보다 더 나은 방법을 제공하고 있다.
나는 이러한 부분에서 구구절절하게 많은 것을 나열하고 싶지 않다. 왜냐하면 React 커뮤니티내에서도 useEffect 자체가 위험하다고 악명이 자자하기 때문이다. 그리고 종종 심지어는 사용하는 것 자체가 꺼려지기도 한다. 하지만 React 기반 프레임워크들을 제외하면, 이러한 일반적이고 유용한 기능을 사용하는 것을 어느 누구도 두려워하지 않는다. 그리고 어떤 프레임워크라도 이렇게 두루뭉술한 규칙을 제공하지 않는다.
어떤 누구도 그저 컴포넌트가 상황을 망쳐버리지 않고 마운트되어 어떤 일을 하게 하기 위해서 제3의 패키지를 찾지 않는다.
사람들이 React가 아닌 다른 프레임워크의 이름을 들으면 즉각적으로 하는 질문이 하나 더 있다. "그 프레임워크가 확장성을 가지고 있는가?" 가 그것이다. 하지만 나는 이러한 질문이 조금 낡아빠진 질문이라고 생각한다.
이러한 사실을 기억하는 것이 좋을 것이다.
React를 우리에게 가져다준 세상은 다양한 문제들을 떠안고 있었다.
그 세상에서, 대부분의 프론트엔드 UI들은 바닐라 자바스크립트를 사용해서 만들어져있거나 아니면 jQuery를 통해서였다. (혹은 비슷한 다른 대체제들을 통해서였다.) 그리고 그러한 방식으로 어플리케이션을 만들어내는 것은, 지금 우리가 알고 있기로는, 특정 한계에 부딪히면 더 이상 확장하기 힘들었다.
그러나 이 사실은 당신이 상호작용 하기 위한 DOM 노드들을 직접 매번 선택자들을 통해서 작성해야했기 때문이며 이들에 대해서 당신 스스로 해당 상태들을 추적하고 동기화 시켜야했기 때문이다. 이러한 상황은 대개 DOM 에 접근하여 데이터를 뽑아내어 작성하는 과정을 포함하고 있었고, 이러한 과정들은 지저분했고, 에러가 발생하기 쉬웠으며, 가장 중요하게도 느렸다. (이 과정에서 가상 DOM(Virtual DOM)이 탄생하게 된 것이다. 하지만 이 마저도 완전히 시대에 뒤떨어진 것으로 여겨진지 꽤 되었다.)
모듈러 코드를 작성하는 것은, 그 때에는 매우 어려웠으며 거의 불가능에 가까웠다. JS 파일들은 대부분 수 천줄 아니면 수 백줄의 코드로 풍선처럼 부풀어 올랐다. 만약 여러 명의 개발자가 같은 프로젝트의 작업하고 있었다면 그들은 대게 만들었던 것을 또 만들던가, 반복하던가, 아니면 심지어 서로의 코드들을 오버라이드하여 작업하였다. (이러한 일이 일어난 많은 이유들이 바로 전역적인 네임스페이스를 공유하는 방식을 취했기 때문이다. 글로벌 네임스페이스는 충돌들이 잘 일어날 수 밖에 없는 환경을 만들어낸다.) 그리고 점점 더 당신의 어플리케이션이 커지고 복잡해질 수록 (Facebook 처럼), 이러한 문제는 더 끔찍해질 수 밖에 없는 것이다.
이러한 과거의 상황이 프론트엔드 영역에서 확장성을 논의할 때의 기준선이라는 것을 기억하는 것이 중요하다. 나의 어플리케이션이 기하급수적으로 성장하더라도, 지금과 같이 합리적인 방법으로 유지 보수할 수 있는 상태로 남아있는가?
프론트엔드 프레임워크가 확장성이 떨어진다는 걱정은 마치 jQuery만큼 오래된 생각이라고 할 수 있다. 그리고 이러한 생각은 현대적인 웹 개발 환경에서 굉장히 골동품같은 생각이라고 여겨져야 한다.
그렇다, React가 이러한 많은 종류의 문제들을 해결해주었다. 하지만 마치 현대 엔지니어링의 하나의 걸작처럼 매우 간편하고 좋은 상태 공유 방식을 생각해내거나, 데이터들을 리액티브하게 만들어주거나, 복잡함을 추상화시켜주거나, 개발자들로 하여금 그들이 기존의 사용하던 프로그래밍 패턴을 문제들과 네임스페이스 충돌과 오버라이딩들의 문제에서 벗어나서 마음 껏 공유할 수 있게끔 만들어준 것은 아니었다.
React는 프론트엔드 확장성분야에 제시되었던 최고의 대안도 아니었고, 유일한 대안도 아니었으며, 심지어는 가장 첫 번째로 제시된 대안도 아니었다. React는 그저 비슷한 패러다임에서 제시 될 수 있는 다양한 해결법중에 하나였을 뿐이다.
(그래도 React는 가장 오래된 녀석들 중에 하나에 포함되기는 한다.)
내가 어떻게 이런 사실을 아느냐고? 그것은 대중에게 공개된 수도 없이 진행되었던 벤치마킹 테스트 결과와 다른 프론트엔드 프레임워크와 React를 비교했던 수 많은 결과가 존재하기 때문이다. (굳이 여기서 링크를 걸도록 하지 않겠다. 왜냐하면 인터넷을 통해서 이미 쉽게 찾을 수 있다.) 이러한 결과들은 모두 프론트엔드 영역에서 React의 다른 대안들이 React만큼 좋거나 React 보다 더 나은 성능을 보여준다는 데 동의하고 있다. 그리고 많은 상황에서, 드라마틱하게 더 좋다는 것이다.
Side Note
여기서 언급하고 있는 확장성은 일반적인 의미에서 확장을 의미한다. 여기서 복잡성은 반드시 최소한으로 남아있어야하며, 어플리케이션의 성장이 선형적인 성장을 의미하는 것이 아니다. 분명히 어떠한 프레임워크들은 마크다운 파일들로부터 정적인 HTML을 생성해 내거나 하는 특정한 역할이 필요한 환경에서 더 나은 확장성을 제공하거나 더 안좋은 환경을 제공할 수 있다.
Side Note
이 섹션에 대한 이전 버전은 React 서버 컴포넌트를 활용한 서버사이드 렌더링에 대해서 너무나 뭉뚱그려 설명해 오류가 많았었다. (이러한 점에서, 네이밍 컨벤션에 대한 혼란을 고려하더라도 많은 부분에서 적어도 이해가 가능했으면 한다.)
몇 년전만 하더라도 이러한 때가 있었다. React가 서버 렌더링 콘텐츠에 대해서 유일하게 고려될 수 있는 옵션이었던 시절이 말이다. (이는 대부분 Next JS를 통해서 였다.) 사람들은 React가 클라이언트에서 SPA(Single Page App)가 아닌 서버에서 HTML로 렌더링이 될 수 있다는 사실에 굉장히 흥분했었다. 그 속도와 SEO의 지원은 무시하기에 불가능 할 정도로 컸고, 결국 다른 프레임워크들을 조금 앞서 가기 시작했다.
하지만, 이러한 서버사이드와 같은 주제가 일반적으로 논의 될 때, 아니면 적어도 이 블로그 포스팅에서 만큼은, 처음으로 열거되는 이름은 최고가 되기 힘들다.
SvelteKit을 사용하면 서버 렌더링 기능을 어떠한 것도 할 필요 없이 기본값으로 사용할 수 있다. 또한 렌더링 패턴에 대한 매우 세세한 부분 까지도 조절할 수 있는 환경을 제공한다. Vue의 메타 프레임워크인 Nuxt의 경우 일찍이 이 분야에 뛰어들었다.(Next의 영향을 받은 것이 분명해 보인다.)
Deno의 프론트엔드 프레임워크인 Fresh의 경우 "island"라고 불리는 클라이언트 렌더링 영역을 당신이 설정하지 않는다면 전체가 정적인 HTML로 서버사이드 렌더링된다. Fresh는 또한 Preact 를 사용한다. (다시 한 번 말하지만, React보다 훨씬 빠르게 동작하고 Signals라는 useState 의 훨신 효율적이고 친화적인버전을 사용한다.)
Astro 또한 서버사이드렌더링 기능을 가지고 있으면서, 당신이 원하는 컴포넌트들만을 서버 렌더링할 수 있도록 하는 환경을 제공한다. Astro는 다른 프레임워크들의 컴포넌트를 렌더링 할 수 있으면서 몇몇의 경우에서는 Next를 뛰어넘는 준수한 퍼포먼스를 보여주는 것으로 주목받아왔다.
Solid의 메타 프레임워크인 SolidStart 의 경우에도 서버렌더링기능을 포함한다. Qwik는 프레임워크 전체가 이러한 개념을 가지고 개발되었다. 심지어 몇몇 오래된 프레임워크인 Ember나 Angular의 경우에도 관련된 이야기가 있으니 나머지들도 역시 그럴 것이라고 생각한다.
논점은 과거에 React가 서버에서 클라이언트 뷰 컴포넌트를 렌더링할 수 있었던 몇몇 프레임워크들 중에 하나였었던 시절이 있었다는 것이다. 하지만 지금은 서버렌더링 기능은 핵심 기능이 되었다. 많은 새로운 프레임워크들은 이러한 기능들을 그저 옵션을 제공하는 것이 아니라 기본 값으로 이를 지원 한다.
"이봐, PHP 가 돌아왔다고"
React가 Facebook을 통해서 탄생하게 된 이유가 바로 Facebook이 처한 특수한 문제들을 해결하기 위해서였기 때문이라는 것을 상기하는게 중요하다고 생각한다.
React가 택하고 있는 가장 강력한 입장중에 하나는 데이터는 반드시 단방향으로 흘러야만 한다는 것이다. (Top-down 방식으로) 이것은 Facebook이 2010년대 초에 직면했던 기술적인 문제점이 React의 설계에 지워지지 않는 큰 영향을 남겼다는 것을 보여준다.
때때로 단방향 데이터 흐름이 가장 좋은 관습으로 여겨졌던 때가 있었다. 하지만 요즘 들어 우리는 양방향 데이터의 위험성에 대한 해결책을 거의 발견했고, 많은 경우에 이것이 실제로 훨씬 유용하다는 것을 찾아내었다.
React에서 폼들을 작업하는 것이 번거로운 것으로 악명 높은 것을 알고 있을 것이다. 왜냐하면 사용자가 키를 한 번 누르는 모든 과정이, 두 번에 걸친 프로세스로 진행되기 때문이다. 1. 인풋으로부터 값을 얻어오고, 2. 그후에 그에 맞게 상태를 설정한다 (그리고 이 과정은 말할 것도 없이 이미 얻었던 값을 보여주기 위해서 인풋을 re-render 하도록 한다. React 상태에 맞추기 위해서이다.) 물론, 이 과정은 너무 빠르게 일어나서 알아차릴 수도 없다. 하지만 불필요한 과정이 꽤 많다는 것도 사실이다.
Svelte, Vue 그리고 다른 많은 프레임워크에서는 이러한 문제가 없다. 당신은 그저 자동적으로 상태가 업데이트 되도록 하는 방식으로 양방향에 상태를 바인딩하기만 하면 된다. 만약 상태가 변한다면, DOM이 업데이트 된다. DOM에 변경이 일어나면, 상태도 업데이트된다.
이러한 방식으로 당신은 다단계의 작업들을 겪지 않아도 되는 것이다. 예를 들어 만약 당신이 텍스트 박스의 값을 가져오고 싶다고 하자. 그렇다면 당신은 그저 양방향 데이터 바인딩을 하면 된다. 그 후에 사용자가 필드에 타이핑을 하게되면 그 데이터는 자동적으로 업데이트 된다. 그리고 당신은 추후의 과정에서 적절한 때에 그 값을 가져와 사용하기만 하면 된다. 만약 그 과정중에 값을 설정하거나 필드의 값을 비워야할 일이 생긴다면 그것 또한 간단하게 한줄로 처리할 수 있다.
양방향 데이터 바인딩은 추가적으로 이 값이 다른 값과 동일하게 맞추어져 있는지 끊임없이 확인하는 과정 없이 DOM과 데이터를 동기화 시킬 수 있다.
이러한 기능을 사용하면서 문제 상황에 처해질 수 있을까? 물론이다. 하지만 나는 최선의 방법들의 이상적인 교리들을 따른다고 할 지라도 그것들이 더 많은 경우에서 도움이 되기 보다는 문제를 만들어낸다는 것을 알게되었다. 단방향 데이터 흐름은 그 탁월한 예시이다.
만약 당신이 React에서 대부분의 작업을 하고 있다면, 프론트엔드 컴포넌트들에서 두 개 혹은 세 개 혹은 그 이상의 스타일링을 다루는 방식들을 동시에 사용하게 되는 상황을 겪었을 확률이 높다.
당신은 아마 .css 파일들을 JSX 컴포넌트들에 곧 바로 불러왔을 것이거나 CSS 모듈, Styled Componenets, 혹은 Tailwind (아마도 tailwind-classnames, tailwind-merge 패키징을 사용하거나 혹은 두 개 다 또는 그 이상의 Tailwind 애드온들을 사용했을 것이다.) 를 사용해보았을 것이다. 그런데 이들은 이러한 분야 에서 가장 유명한 옵션들일 뿐이다.
Tailwind는 스스로의 토끼굴을 지니고 있다. (그리고 나는 별로 선호하지 않는 스스로의 프론트엔드 프레임워크를 가지고 있기도 하다. 나는 이 프레임워크가 플랫폼의 요소들과는 반대로 가면서 단기적인 이익과 장기적인 손실을 교환하고 있다고 생각한다.) 하지만 무엇을 사용하든 간에, 이러한 스타일링 솔루션들의 존재와 이렇게 널리 사용되고 있는 이유는 바로 React가 나온지 오래 되었음에도 불구하고 스타일링에 관한 제 1의 솔루션 자리를 공석으로 두었기 때문일 것이다.
당신은 아마 다른 몇몇 프레임워크들에서 스타일링이슈가 이미 해결된 문제라는 것을 몰랐을지 모른다.
특별히 Vue 와 Svelte의 경우에 그들의 방식대로 스타일링을 해결하는 한 방식을 가지고 있다. 이 둘은 컴포넌트 레벨의 스코핑을 지원한다. (Vue의 경우에는 선택적으로 사용할 수 있고, Svelte의 경우에는 선택적으로 제외하여 사용할 수 있다.) 만약 당신이 바닐라 CSS를 프로젝트에 사용하고 싶다면, 이 둘의 경우 바닐라 CSS와 함께 놀랍도록 잘 동작한다. 하지만 이 둘 또한 다른 프론트엔드 프레임워크들과 마찬가지로, CSS 모듈과 Tailwind, Sass 또는 당신이 쓰고 싶은 어떤 다른 것들과도 호환이 가능하다.
그러나 가장 중요한 것은 CSS를 통해 발생할 수 있는 모든 문제들은 당신이 그것을 실제로 문제라고 여기든 아니든 간에 빌트인 솔루션 방식을 통해서 해결될 수 있다는 것이다. 당신은 CSS 스코프의 방식을 통해서 당신이 상상할 수 있는 모든 문제들을 다른 많은 패키지 묶음들이나 config을 통해 해결할 필요가 없다는 것을 알게 될 것이다.
진심으로 CSS가 나쁘다고 이야기하는 이유들을 쭉 살펴보기를 원한다. (CSS가 정말로 그렇다는 것은 아니다. 다만 CSS에 익숙하지 않은 사람들은 이렇게 이야기하곤 한다.) 당신이 상상할 수 있는 모든 CSS의 비판점들은 스코프 스타일링 방식을 통해 해결될 수 있다. 그리고 React가 아닌 프레임워크들은 이미 이러한 방식을 빌트인으로 갖추어서 나와있다.
나는 React에 대해 주로 훈련받았던 많은 개발자들이 그것을 배우는 것이 굉장히 어려운 과정이라고 느꼈을 것이라고 상정한다. 그리고 그들이 다른 프레임워크를 배우는 러닝커브를 평가하는 것도 크게 다르지 않을 것이라고 생각한다. 그리고 바로 이러한 부분이 우리가 새로운 것들을 배우는 것으로부터 거리를 두게 만드는 주된 이유이다. 새로운 것을 배우는 것은 매우 어려워보인다. 실제로 처음에 그랬었기 때문이다.
상태 관리의 모든 면면들, 프롭스(props), 네스팅(nesting), 컴포넌트 라이프사이클, Hooks, 그리고 당연히 어떻게 JSX 문법을 작성해야 하는지... 이러한 것들은 양이 꽤 많다. React의 최고 열성팬들일지라도 이것들이 초심자들이 빠르게 습득하고 사용할 수 있는 내용이 아니라는 것에는 동의할 것이다. (동의하지 못하는 사람들은 아마도 초심자가 되는 것이 어떤 것인지를 아마 잊어버린 사람들일 것이다.)
만약 당신이 이에 공감할 수 있다면, 좋은 소식이 있다.
React를 배우는 것만큼 배우기 어려운 프레임워크는 없다. 그리고 이미 하나의 프레임워크를 배운적이 있다면 당신은 다른 어떤 것들에서든 그만큼 훨씬 더 쉽게 배워나갈 수 있다.
나는 이러한 것을 두 번째 악기를 배우는 것에 빗대서 표현한다. (다시 음악에 대한 비유를 시작하려고 하는 게 아니다.) 당신이 처음에 어떻게 악기를 연주하는지에 대해서 배울 때, 당신은 음악에 대한 모든 것을 배워야한다. 거기에 그 특정한 악기에 대해서 배워야하며, 그리고 당신이 원하는 만큼 좋은 소리를 내기 위해서는 어떻게 해야하는지에 대해서도 배운다. 하지만 당신이 두 번째 악기를 배울 때는 다르다. 당신은 많은 부분을 생략할 수 있다. 대부분의 개념들이 매우 친숙하게 느껴지며, 당신은 음악을 이해하고 있다. 당신이 해야할 일은 단지 당신이 지니고 있는 지식들과 머슬 메모리들을 조금 다른 방식으로 변경하기만 하면 되는 것이다.
프론트엔드도 이와 비슷하다. 모든 프론트엔드 프레임워크들은 컴포넌트들로 구성되어있다. 그들은 Typescript와 같이 사용가능하다. 그들은 모두 props, children, reactive-state와 같은 개념들을 동일하게 사용한다. 이러한 사실들은 일반적으로 우리 모두가 좋아하고 또 좋다고 동의하는 사실들이기 때문이다. 그들은 그저 조금 다른 방식으로 구현되어있을 뿐이다.
그리고 말이 나온김에, React가 의심할바없이 이러한 개념들을 널리 알리고 퍼뜨리는데에 도움을 주었지만 그렇기 때문에 React가 가장 이상적인 구현방식이라고 생각하는 것은 바보같은 생각이라는 것을 이야기해야겠다.
훌륭한 일들은 반복된 시도에 의해서 탄생한다. 프론트엔드 영역에서 선택할 수 있는 다른 대부분의 선택지들은 React보다 나중에 등장했으니, React의 핵심 아이디어에서부터 시작되어 많은 시도들을 반복한 끝에 얻어낸 이점을 분명히 가지고 있다.
한 마디로, React가 main 브랜치에서 저 멀리 떨어져 있는 어느 한 git 브랜치라는 뜻이다. 만약 당신의 은하가 React라는 별을 중심으로 돌고 있다면, 당신은 아마 잘 깨닫지 못할 수도 있다. 하지만 글쎄... 프론트엔드 영역은 항상 앞으로 나아가왔다. 이 생태계는 항상 그러한 아이디어들을 취하고서는 이들을 통해서 더 나은 것들을 만들어 내기 위해서 계속해서 달려나가왔다.
우리는 현재 더 효율적이면서 덜 복잡하고 배우기 좀 더 쉬운 옵션들을 부족함 없이 가지고 있다. 그리고 당신이 이미 React를 알고 있다면, 이러한 것들은 그보다는 배우기 쉬울것이다.
당신은 아마 몇 문단 전부터 궁금하기 시작했을 것이다: 만약 React가 오래된 것이라면, 그것을 대체할 방법으로는 뭐가 있을까?
이제부터 여기서 몇몇의 대안들을 살펴 보고 그들이 어떻게 사용되는지 이야기할 것이다. React의 문제점들중 하나는 React가 오래전부터 모두를 위해서 모든 기능들이 전부 시도 되어왔다는것이다. React같은 도구들이 유용하다는 것은 분명하지만, 나는 두 가지 또는 세 가지의 다른 도구들이 하나의 스위스 만능 칼보다 나을 수 있다고 생각한다.
본격적으로 살펴보기전에 두 가지를 짚고 넘어가고 싶다.
React를 제외한 다른 현대 프레임워크들을 다루기 위해서 앞으로 몇몇의 옵션들을 살펴볼 것이다. 하지만 나는 이 당신이 이 모든 것들을 배우거나 사용하기를 기대하는 것은 아니다. 당신이 하나를 선택해야 한다면, Svelte 나 Vue 정도를 선택하는 것이 좋을 것이다. 어떤 경우든지 내가 이 모든 리스트를 다루는 것이 최대한 많은 옵션을 전달하기 위해서일 뿐이라는 것을 명심해라.
나는 모든 가능한 옵션들을 설명하지는 않을 것이다. 여기 소개된 것들 말고도 다른 옵션들이 존재한다. 예를 들어서 나는 Ember 와 Angular를 언급하고 넘어가지 않을 것이다. 왜냐하면 이들은 React보다도 오래된 프레임워크이며 React보다 더 나은 성능을 벤치마크 테스트들에서 보여주지 못했기 때문이다.
그리고 나는 보다 가벼운 선택지라고 할 수 있는 Alphine 이나 Petite Vue에 대해서도 다루지 않을 것이다. 왜냐하면 이들은 React의 대체재라기 보다는 jQuery의 대체재라고 하는 것이 맞기 때문이며, 프레임워크같은 환경을 필요로 하지 않는 상황에서 더 빛날 수 있기 때문이다.
마지막으로 나는 또한 한 특정 영역에서만 뛰어난 성능을 가지고 있는 Eleventy 같은 옵션도 제외했다. 왜냐하면 이들 역시 프레임워크라고 하기 보단 순수하게 정적 사이트 생성기에 가깝기 때문이다. (하지만 당신이 Gatsby를 사용하고 있다면 한 번 살펴볼 가치는 있다.)
모든 이야기를 마쳤으니, 이제 한 번 '금주의 발견'을 살펴보도록 하자.
2023학번 수강생 여러분! Svelte를 사용하십시오.
만약 내가 여러분들의 미래를 위해 딱 하나의 팁만 드릴 수 있다면, 바로 Svelte를 추천해주는 것일 겁니다.
농담은 잠시 치우고, 내가 만약 React보다 나은 무언가들 중에서 딱 하나만 고를 수 있다면, 그건 바로 Svelte일 것이다. 나는 오래전 부터 계속해서 "Svelte는 개똥같은 부분이 없는 React이다."라고 계속해서 주장해왔다. 나는 2019년에 이 이야기를 트위터(RIP)에 장난스럽게 올려놓았었는데, 시간이 지나면서 점점 더 사실이 되어가고 있다.
Svelte는 사용하기 즐거울 만큼 쉽다. 비교적 배우는 것 또한 쉽다. (특히 당신이 React 세계에서 넘어온 상황이라면 말이다. 심지어 문법마저 비슷하다.) 성능 또한 모든 상황에서 훨씬 훨씬 좋으며, React가 할 수 있는 것들은 전부 할 수 있거나 더 많은 것들을 할 수 있다. 지금 당신이 보고 있는 이 블로그 사이트와 요새 진행하고 있는 내 모든 사이드 프로젝트들은 모두 SvelteKit을 통해 개발되었다.
Svelte는 빠르며 가장 빠른 옵션들과 견주어 보았을 때도 훌륭하다. 개발자 경험 또한 환상적이어서 가장 사랑받는 프레임워크를 고르는 개발자 설문에서 대부분 거의 정상을 차지하곤 한다.
Svelte 는 웹 플랫폼과 할 수 있는 만큼 최대한 가까이에 위치해 있으며, 놀라울만큼 좋은 성능을 보여줌에도 불구하고 사용하고 있는 개념들은 굉장히 친숙하다. Svelte는 또한 트랜지션, 트랜지션 조절(easing), CSS 핸들링, 컴포넌트 스코프 스타일링 등의 굉장히 편한 도구들을 빌트인으로 제공한다.
아마 당신은 프레임워크의 용량에 대해서 궁금할 수 있겠다. 하지만 바로 이점이 Svelte가 다른 프레임워크들과 차별점을 두는 것이다. Svelte는 자바스크립트의 런타임 환경으로 존재하는 것이 아니라 컴파일러가 되기로 했다. 당신이 사용하지 않는 어떤 것이든 빌드하는 동안 제거할 수 있으며 당신의 코드는 굉장히 작은 양의 바닐라 자바스크립트로 변환된다. 이것이 바로 Svelte의 번들 사이즈가 React의 그것에 비교했을 때 굉장히 작게 느껴지는 이유이다.
프레임워크처럼 느껴질 수는 있어도, Svelte는 근본적으로 자그마하고 우아한 HTML의 상위호환이라고 할 수 있다. Svelte는 즐겁고 쉬운 문법, 빠른 컴파일 환경, 최소화된 번들 사이즈를 제공한다.
Svelete는 스스로의 메타 프레임워크인, SvelteKit을 가지고 있다. SvelteKit은 굉장히 다재다능하고, 강력하며, 정적 사이트 생성 과 서버렌더링을 지원하고, edge 네트워크를 통해 배포가 가능하며, 심지어는 라우트 마다 이를 선택해서 사용할수도 있다. 2022년 말에 1.0 버전을 발표했으며 프로덕션환경에서 사용하기에 충분할정도로 준비되어있는 상태다. (Next JS를 만든 Vercel에서도 이를 지원하고있다.)
Svelete는 이런 사람에게 추천한다.
Svelete는 이러한 것들을 대체할 수 있다.
Vue는 아마 React와 가장 비슷한 옵션이라고 할 수 있을 것이다. 그리고 React 다음으로 거대한 생태계를 가지고 있을 가능성이 있다. 하지만 React 보다는 주목할만큼 더 좋은 성능을 보여주고 있고 보다 UI에 중심이 맞추어져 있다.
몇몇 부분에서 Vue는 React를 아주 작은 걸음만큼 뛰어넘은 것 같이 느껴지기도 한다. 특히 Vue 3에서 React hooks 와 비슷한 접근법을 시도한 시스템을 가지고 있기 때문이다. 하지만 Vue는 JSX 보다는 기본 HTML에 가까운 템플리팅 문법을 사용하고 있다. 이러한 환경은 map 이나 삼항연산자 같은 우회를 사용하지 않고도 편하게 조건문이나 루프를 템플릿 파일에서 사용할 수 있게 만들어준다.
Vue는 Nuxt라는 새롭고 강력한 기능들을 제공하면서 잘 유지보수 되어지고 있는 Next와 비슷한 메타 프레임워크를 가지고 있다. Vue는 또한 스코프 CSS 핸들링과 트랜지션/애니메이션 사용을 쉽게 만들어주는 기능들을 빌트인으로 제공하고 있기 때문에 React보다 더 나은 사용자 경험을 제공한다.
Vue는 이런 사람에게 추천한다.
Vue는 이러한 것들을 대체할 수 있다.
나는 Solid를 더 나은 버전의 React라고 부르고 싶다. Solid는 거의 많은 부분에서 (아니면 통째로) React와 동일하게 느껴진다. 하지만 Solid는 React보다 훨씬 훨씬 더 성능이 좋다. 실제로 Solid는 선택할 수 있는 가장 빠른 옵션들 중에 하나이다.
Solid는 근본적으로 React에서부터 시작했다. 그리고 React의 복잡성을 제거하기로 마음먹었고, 퍼포먼스 이슈들을 해결하고, 많은 보일러플레이트 코드들을 제거하기로 했다. Signals 는 Solid의 주요 개념으로 등장해 컴포넌트 렌더링이나 라이프사이클과 같은 성능을 잡아먹는 기능들을 제거하고 많은 혼란들을 해결했다. React가 만약 2013년에서부터 지금까지의 모든 경험들을 바탕으로 지금과 같은 때에 개발되었다면 Solid를 React라고 부르는 것이 틀린말은 아닐것이다.
Solid도 자신들만의 메타 프레임워크인 SolidStart를 제공하고 있다. 하지만 아직 개발 완료되지 않은 베타버전이다. 그래도 Solid 그 자체는 사용해도 좋을만큼 꽤 성숙해있고 꽤 유명한 많은 스폰서들로부터 지원을 받고있다.
Solid는 이런 사람에게 추천한다.
Solid는 이러한 것들을 대체할 수 있다.
Fresh는 아일랜드 아키텍쳐(island architecture)를 활용하여 Deno 환경에서 개발된 서버 렌더링 프론트엔드 프레임워크이다. 여기에서 소개하고 있는 다른 프레임워크들보다 조금 나온지 얼마되지 않았다. 하지만 Fresh는 최소화된 JS 번들, Deno를 통해 엣지환경에서 동작할 수 있는 아일랜드 기반의 프레임워크를 보장한다. 이러한 것들이 의미하는 것은 당신의 서버코드가 보다 빠르고 안정적으로 동작할 수 있으며 타입스크립트를 기본값으로 사용하고, Deno가 Node와 비교했을 때 제공할 수 있는 모든 다른 장점들을 누릴 수 있다는 것을 뜻한다. (예를 들면 더 쉽고, 린팅을 기본적으로 제공하고, 테스팅 환경과 코드 포매팅 설정을 사용할 수 있다)
모든 Fresh 컴포넌트는 정적으로 렌더링 되거나 자바스크립트 없이 HTML 만으로 서버를 통해 전달할 수 있다. 혹은 "아일랜드"를 활용해 클라이언트 사이드 렌더링되도록 할 수 있다. 당신은 원하는 대로 이 세 가지 옵션을 모두 조합하여 사용할 수 있다. 왜냐하면 Deno가 굉장히 빠르게 동적으로 세계 어떤 곳에서 무엇을 사용하든지 간에 콘텐츠를 전달할 수 있는 문을 열어주었기 때문이다.
Fresh는 Preact를 사용한다. 그러니 당신도 Fresh가 빠르고 React로 부터 넘어왔다면 배워 사용하기 그다지 어렵지 않다는 것을 알 수 있을 것이다. 그리고 또 다시 이야기하지만, Deno를 통해 빌드하는 건 훌륭하다.
Fresh는 이런 사람에게 추천한다.
Fresh는 이러한 것들을 대체할 수 있다.
Astro는 그저 정적 사이트 생성 보다 더 많은 것을 할 수 있는 굉장히 성능 좋은 차세대 정적 사이트 생성기이다. Astro는 소개하고 있는 옵션들 중에서 역시 가장 최신 프레임워크 중에 하나이다. 하지만 이미 안정적인 1.0 버전의 릴리즈 단계를 지났고 여러 곳들에서 사용되고 있으며 칭찬을 받고 있다.
차세대 SSG를 위해서 개발된 Astro는 (React 팬 여러분들, Astro는 JSX와 MDX를 지원합니다.) 현재 동적인 서버 사이드 능력들 또한 갖추고 있다. 나는 분명하게 Astro를 Gatsby 보다 혹은 또 다른 콘텐츠 위주거나 정적인 사이트들을 생성하는 것에 추천한다.
Astro의 정말 유용한 기능은 기본적으로 Astro가 자바스크립트를 전혀 포함시키지 않는다는 것이다. 당신이 사용하고 싶을 경우에만 선택해 사용할 수 있다.
Astro는 당신이 어떠한 프론트엔드 프레임워크를 사용하든지 간에, 그와 같이 사용할 수 있다. 그러니 만약 당신이 React, Vue, Svelte 혹은 다른 프레임워크들의 템플리팅을 좋아한다면 사용하면 된다!
Astro는 이런 사람에게 추천한다.
Astro는 이러한 것들을 대체할 수 있다.
만약 당신이 React 세계에서 살고 있다면, Preact에 대해서 이미 들어봤을 것이다. Preact는 훨씬 더 가볍고 더 빠르게 동작하는 React이다. 처음에는 다소 React의 대체안으로 갑작스럽게 등장하기는 했지만, React가 제공하지 못하는 우수한 기능들을 조금씩 갖추어 나가고 있다. (예를 들면, 이미 말한적이 있었던 Signals 같은 것 말이다.)
Preact는 이런 사람에게 추천한다.
Preact는 이러한 것들을 대체할 수 있다.
Qwik은 React와 비슷한 코드들(JSX)을 하이드레이션(hydration)과 성능에 관련된 새로운 접근법을 통해서 서버렌더링 해준다. 사실, Qwik이 동작하는 것을 살펴보면 "하이드레이션"이라고 전혀 부르기 힘들기는 하다. 다만 Qwik은 자바스크립트를 직렬화화여 DOM에 집어넣고 필요한 경우에만 조금씩 빼서 가져다 사용한다. Qwik은 지금 소개하고 있는 목록들중에서 가장 딥한 주제이기는 하다. 하지만 당신의 사이트가 많은 상호작용을 포함하고 최대한 빠르게 동작하길 원한다면, 한 번 살펴볼 가치는 충분하다.
Qwik은 이런 사람에게 추천한다.
Qwik은 이러한 것들을 대체할 수 있다.
이 주제에 대해서 깊게 다루지는 않을 생각이다. 왜냐하면 솔직히 나도 이 분야에 적합한 사람이 아니기 때문이다. 나는 이 주제에 대해서 잘 이야기할 수 있을 만큼 웹 컴포넌트 그 자체나 웹 컴포넌트를 활용한 프레임워크들을 충분히 사용한 경험이 없다.
그래도 몇몇 분야의 프로젝트가 Lit 이나 Stencil 혹은 Polymer와 같은 다른 웹 컴포넌트 프레임워크나 라이브러리를 통해서 도움을 얻을 수 있다는 것은 이야기할 수 있을 것이다. 다른 프론트엔드 프레임워크들과는 다르게 이러한 라이브러리들은 특정 프레임워크에 종속된 컴포넌트들 대신 실제로 어떤 웹 프로젝트에서도 사용 가능한 웹 컴포넌트들을 만들어줄 수 있게 도와준다.
나는 많은 프로젝트들에 아직까지는 순수하게 웹 컴포넌트들만을 사용하는 것보다 프론트엔드 프레임워크를 사용하거나 아니면 적어도 둘을 섞어서 사용하는 것이 더 도움이 된다고 생각한다. 미래에는 이러한 상황들이 바뀔 수도 있겟지만, 현재로써는 나는 대부분의 경우에서 이러한 교환이(프론트엔드 프레임워크 vs 웹 컴포넌트) 한쪽으로 기울어져있는 상황이라고 생각한다.
하지만 순수한 웹 컴포넌트를 기반으로 한 접근법들이 유용한 상황들이 분명히 존재한다. 그리고 그러한 프로젝트들에서 React를 사용하는 것은 당연히 과하다. 위에서 언급한 웹 컴포넌트 라이브러리들을 사용하는 것이 좀 더 적절할 것이다.
웹 컴포넌트 라이브러리는 이런 사람에게 추천한다.
웹 컴포넌트는 이러한 것들을 대체할 수 있다.
이 포스트는 분명하게도 내가 작년에 작성했던 포스트 (React의 자기충족적인 예언)와 굉장히 비슷하다. 그 포스팅은 이 포스팅과 비슷한 영역에 대해서 다루고 있고 몇몇 같은 주장을 하고 있다. (그렇기는 하지만 이 포스팅이 새로운 방식과 새로운 시각을 전달하기를 바란다.)
내가 했었던 말을 스스로 다시 되풀이하고 싶지는 않았지만, 분명히 나는 이러한 생각들을 많이 하곤 한다. 우연하게도 그 포스팅이 작성되었을 때 즈음, 다시 React를 풀타임으로 사용하는 곳으로 직장을 옮기게 되었고 의심할 여지 없이 그 영향을 받았다.
나는 적지 않은 부분에서 React의 명성을 믿게 되었다. 왜냐하면 사람들이 그 너머를 보려고 하지를 않았기 때문이다. React는 최고의 프레임워크가 아니다. 하지만 대부분의 사람들이 최고의 것을 찾으려 하는 것은 아니다. 그들에게는 그저 충분히 괜찮기만 하면 된다. (우리는 인간이다. 우리는 선택을 할 때 많은 개인적이고 감정적이고 비논리적인 이유들을 통해 결정을 내린다. 우리 모두가 그러하고 그것은 나쁜 것이 아니다. 우리는 바쁘기 때문이다.)
적어도 프론트엔드 영역에서는, 우리의 기술이 선형의 방식으로 성장하는 것이 아니라 한 단계 한 단계 뛰어넘는 방식으로 성장한다고 느껴진다. 당시에 React 라는 수레 위로 모두가 올라타게 만들었던 이유 중 하나는 그때의 고루한 기술에 모두가 골머리를 앓고 있어서 무언가 더 나은 것을 찾고 있었기 때문이었다. 우리는 점진적으로 조금씩 새로운 것으로 나아가지 않는다. (말하자면 아마도 그렇게 하는 것을 우리가 선택할 수 없기 때문이다.) 그렇기에 우리는 다음 것이 존재하는 곳을 향해 크나큰 한 걸음씩을 내딛는 것이다.
중요한 것은 우리가 한 곳에 너무 오랫동안 머물러있었다는 사실이다. 심지어 우리가 수 년전에 내딛어 도착했던 바로 그 곳에서만 머무르면서 말이다.
나는 우리가 이제 곧 그 새로운 발걸음을 내딛기 시작할 것이라고 느낀다.
나도 그것이 무엇이 될지, 이유가 무엇이 될지는 알지 못한다. 다만 나는 우리가 React가 우리를 위해서 해결해주지 못하는 그 모든 문제들에 대해서 느끼기 시작했다고 생각한다. 마치 그 시절 jQuery가 그랬던 것처럼 말이다. 그리고 나는 결국 이것이 분명히 발전할 때라는 것을 의미한다고 생각한다.
다음에 우리에게 찾아오게 될 것은 무엇인가? 나도 알지 못한다. 아마도 그것은 그저 웹 플랫폼이 될 수도 있다. 아마도 우리는 프레임워크 같은 것들을 필요로 하지 않게 될지도 모른다. 아마도 그것은 프레임워크 그 이상의 것이 될 수도 있고, 우리가 여태까지 보지 못했던 어떤 것이 될 수도 있다. 어쩌면 그것은 물건이 아닐지도 모른다. 어쩌면 도구의 다양성이 더욱 더 확장되어서 공통의 규칙으로 받아들여질 어떠한 구심점으로 모이지 않으려 할지도 모른다. (이러한 모든 것들이 가능한 선택지들이기는 하지만, 나는 이 말이 가장 일어나지 않을 것 같다고 느껴진다. 왜냐하면 또 다시, 우리는 인간이기 때문이다. 우리는 바쁜 원숭이들이기 때문에 우리는 기본값을 좋아한다.)
그럼에도 나는 React와 뭐가 될지는 모르겠지만 그 "어떤 것" 사이의 변화의 가파르기가 시간이 지나면서 계속해서 점차 커질 것이라고 생각한다.
그렇기에 당신이 놓치고 살아왔던 것들을 발견하기에, 새롭게 다가올 모든 날들이 그 전날들 보다는 훨씬 좋을 것이다.
즐거운 시간이 되기를.
React 말고도 이렇게 많은 프레임워크가 있는 줄 몰랐네요..! 긴 글 번역하시느라 고생하셨습니다. 잘 읽었어요!