2024년 최신 웹 개발 트렌드 정리

2024년 최신 웹 개발 트렌드 정리
Cozy CodingPosted On Aug 26, 202416 min read

웹크랩이 통제를 가져갔다

웹 개발이 오랜 시간 동안 문제가 있었다는 것은 비밀이 아닙니다. 매년 더 많은 도구들이 만들어지면서 웹 크랩웨어를 해결하기 위한 궁극적인 해결책이라고 주장합니다. 그러나 그것들이 무슨 일을 이루고 있는 걸까요?

웹크랩이 통제를 가져갔다

2016년, Jose Aguinaga가 Hacker Noon에 게시한 훌륭하고 재미있는 기사 [1]에는 두 웹 개발자 간의 일화적 대화에 관한 내용이 포함되어 있습니다. 한 명은 몇 년 동안 웹 코드를 건드리지 않았고 다른 한 명은 여전히 그 분야에서 일하고 있습니다. 8년이 지난 지금도 여전히 유효하며, 글의 끝에서 저자가 웹의 손이 얼마나 멀리 뻗어갈지 명백히 과소평가했던 부분만 빼고요:

리액트 소개

페이스북 소셜 미디어가 공개되자마자 금세 인기를 끌게 되었고, 기능이 계속해서 확장되어 매우 복잡하고 느린 응용 프로그램으로 변모하게 되었습니다. 이를 극복하기 위해, 현재는 '메타'로 불리는 사람들이 새로운 자바스크립트 라이브러리인 리액트를 만들기로 결정하고, 2013년에 공개했습니다. 오늘날 다양한 프론트엔드 프레임워크가 존재하지만, 리액트 에코시스템이 시장을 지배하며 여러 가지 특이한 점들을 부과하고 있습니다.

이미지

리액트는 페이스북에게 망치가 나사를 박는 데 필요한 적절한 도구인 것과 같습니다. 하지만, 페이스북이 리액트를 만들고 사용하는 것보다 더 나쁜 것은, 공개된 지 얼마 안 가 아주 빠르게 전 세계의 대부분의 기술 회사들이 페이스북만큼 성공하기 위해 리액트가 필요하다고 믿기 시작했다는 것입니다. 이제는 페이스북의 명성이 사라지고 있는데, 삶은 농담으로 가득 차 있는 것 같습니다.

React에서 소개된 가장 큰 변화 중 하나는 이제 모든 것이 동기화되어 있어야 한다는 것입니다. 업데이트가 발생할 때 UI가 잠기지 않도록하기 위해서입니다. 따라서 무언가의 상태를 변경하고 나중에 확인하려면 간단히 이렇게 하면 안 된다는 것을 알아두세요:

let variable = "test"

if (variable === "test")
  console.log("hello")

React에서 변수의 상태를 변경하려면 비동기 메서드를 호출해야 합니다. 그 결과로 IF 문이 변수의 값을 확인할 때 이미 업데이트되었는지 보장할 수 없습니다. 해결책은 useEffect() 콜백을 구현하고 IF 문을 그 안으로 옮기는 것입니다. 이렇게요:

import { useState, useEffect } from "react"

const Example = () => {
  const [variable, setVariable] = useState("")

  useEffect(() => {
    setVariable("test");
  }, []);

  useEffect(() => {
    if (variable === "test")
      console.log("hello")
  }, [variable])
}

궁금하고 계신가요? setVariable()을 호출하면 약속이나 그런 것은 절대 반환되지 않을 거예요. 그래서 맞아요, 처리할 변수를 담은 배열이 있는 useEffect() 콜백이 필요합니다. 이 문제는 코드 양을 세 배로 늘리고 훨씬 혼란스러운 구문을 갖는 것에 한정되지 않아요. 이 문제는 바로 콜백 지옥이죠. 실제로 코드 흐름이 매우 복잡해져서 이제 코드를 디버깅할 수 없다는 단점이 있어요. 이렇게 되면 console.log("passed here")와 같은 것들이 코드 여기저기 흩어지는 것이 놀라운 일이 아니에요.

우리는 기본적으로 모든 것을 비동기적으로 구현할 필요 없이 이미 50년 이상 UI와 함께 일해왔어요. 싱글 코어 CPU조차도, 이 방식은 꽤 잘 작동했어요. 앱이 백그라운드에서 무거운 작업을 수행해야 하는 특정한 경우에만 새로운 스레드가 차단되지 않도록 도와주는 유용한 도구일 뿐이에요. 예를 들어, 순수 JavaScript에서 setTimeout(), fetch(), 심지어 for await...of와 같은 메소드들은 비동기적으로 동작하기 때문에 호출될 때 UI가 멈추지 않아요. 개발자들은 자신만의 메소드를 비동기로 만들 수도 있어요. 이러한 접근법은 사용자 경험을 희생하지 않고 더 쉽고 빠른 개발 프로세스를 제공해요.

그러나 React는 엄격한 스쿨에서 나온 것 같아요. 그에게 정적 HTML이란 없어요. 사용자가 보는 모든 화면은 JavaScript 코드의 결과물이에요. React 자체를 포함해서, 서버 측(SSR)이나 클라이언트 측(CSR)에서 HTML을 생성하는데, 후자가 기본이라서 가장 일반적이에요. 대부분의 개발자들은 이 개념에 대해 전혀 들어본 적이 없는데, 응용프로그램이 성능이 좋지 않다는 것을 깨닫기 전까지요. 하지만 그런 피치 못할 상황에 이르기 전엔 이미 늦은 것이에요, 왜냐하면 React에서 SSR로 이전하는 작업은 딴 문제가 나타나거든요. 심지어 그렇게 해도, 효율성 문제는 여전히 봐줄 수 없을 거예요. 바로 이걸 해결해야겠어요.

사용자는 브라우저에게 페이지 소스를 표시하도록 요청하여 CSR을 사용하는지 확인할 수 있어요. 콘텐츠가 단순한 템플릿이라면, 사용자의 기기는 HTML을 생성하는 JavaScript 코드를 실행하고 있다는 의미에요. 그렇죠, 여러분, 여러분의 배터리 수명이 아마도 아무 이유없이 희생되고 있을 것입니다.

리액트에서는 HTML과 비슷한 리액트 구문 가운데에서 코드를 다루어야 하는 일이 자주 발생합니다. 아래는 예시 코드입니다:

return (
 <Container maxWidth="lg">
   <Header />
   <div className={classes.root}>
     <Grid container direction="row" justify="center">
       <Typography variant="h4" className={classes.heading}>
         Create User
       </Typography> 
       { sbOpen ? <NotificationSnackBar onClose={sbHandleClose} /> : "" }
     </Grid>
     { working ? <Spinner /> : 
     <Grid container direction="column" alignContent="center">
       [...]
     </Grid>
   </div>
 </Container>
)

이 난잡한 코드를 어떻게 진전이라고 부를 수 있을까요? 자바스크립트 프레임워크가 없던 시절에는 코드가 HTML, CSS, JavaScript 세 가지 유형의 파일로 분리되어 있었습니다. 분리가 명확했고, 개발자가 모든 것을 HTML에 통합하려고 해도 서로 완전히 분리된 태그를 사용했습니다. 이것이 화려한 꿈 속의 순수한 즐거움이었던 것은 아니지만, 분명히 이러한 프레임워크들이 부과하는 것보다 훨씬 나은 해결책이었습니다. 그러나 함께 참아주시기 바랍니다. 우리는 아직 표면만 긁고 있는 것 뿐입니다.

죽은 패키지를 보았네요

자바스크립트 프레임워크 열풍은 애플리케이션이 타사 플러그인 또는 그들이 부르는 이름대로 패키지의 도움을 받아 개발될 것을 시사합니다. 현대 웹 개발자들은 종종 이러한 패키지에 매우 의존하여 수학과 알고리즘의 기본을 잊어버리는데, 그래서 is-odd [3]나 left-pad [4]와 같은 패키지들이 무서울 만큼 인기가 많습니다. 이는 조립 라인의 공장 근로자들과 닮았습니다: 부품을 어떻게 만드는지 알지 못하지만 단지 어떻게 꽂아넣는지만 알 뿐입니다.

더 나쁜 것은 자바스크립트의 옛 제한들이 여전히 최신 버전에서 볼 수 있다는 것입니다. 예를 들어, JSON을 구문 분석할 때 유효하지 않은 문자가 있으면 언어가 그 색인을 알려주지 않기 때문에 문제가 되는 문자를 특정하기 어려울 수 있습니다, 특히 입력이 긴 경우에는 더욱 그렇습니다. 그래서 이 문제를 해결하기 위해 하나의 패키지를 추가해볼까요?

귀찮은 점들의 목록이 너무 길기 때문에, 마이크로소프트는 TypeScript라는 언어를 만들기로 결정했습니다. 이 언어는 자바스크립트의 일부 제한을 극복하기 위해 개발되었습니다. 하지만 브라우저가 TypeScript를 이해하지 못하기 때문에 애플리케이션이 자바스크립트로 변환될 수 있도록 트랜스 파일 패키지가 필요합니다. 그리고 자바스크립트를 클라이언트 측에서 컴파일해야 하기 때문에, 브라우저 버전이 최신 자바스크립트 기능과 호환되지 않을 수도 있어서 최신 자바스크립트를 레거시 버전으로 변환해서 오래된 브라우저에서 애플리케이션이 올바르게 실행될 수 있도록 하는 단계가 필요합니다.

각 반복마다 코드는 더욱 비대해집니다. 이 계속 성장하는 비효율성의 결과는 간단한 애플리케이션들이 일반적으로 수천 개의 직접적인 의존성과 엄청난 수의 간접적인 의존성을 가지게 되어 매우 커진 자바스크립트 파일들을 가지게 된다는 것입니다. 보통 이 모든 것을 클라이언트 기기로 보내 다운로드, 구문 분석, 컴파일 및 실행하여 HTML을 생성하기만 합니다. 이것이 중요한 점입니다. 미친 일이죠.

어느 경우에는 이 알려지지 않은 패키지 개발자 중 한 명이 코드를 망가뜨려서 전 세계의 수많은 애플리케이션이 붕괴되는 원인이 되곤 합니다. 바로 이런 일이 left-pad에서 일어났습니다. 이에 관한 이전 기사에서 기술된 대로 기술 업계가 시급한 미신으로 점령되었다고 합니다.

이미지

웹 개발자가 자신의 프로젝트를 체크아웃하고 npm install(또는 yarn install - 오, 또 다른 패키지 매니저!)을 호출하면, 보통 'node_modules' 하위 폴더로 많은 패키지가 다운로드됩니다. 함정은 이 패키지들의 주요 버전이 프로젝트의 'package.json' 파일에 하드 코딩되어 있다는 것입니다. 매우 조심스럽게 다루어야 합니다! 이것은 사용자들이 시스템을 최신 상태로 유지해야 한다는 압력이 웹 애플리케이션의 종속성에 적용되지 않는다는 것을 의미합니다. 당연히 매주 각 종속성을 수동으로 확인하는 것은 매우 어렵습니다.

그리고 각 종속성은 자체 종속성을 가질 수 있으므로, 패키지 폴더 내에 다른 'node_modules' 하위 폴더가 있을 수 있습니다. 이 폴더 또한 자체 종속성을 가질 수 있고, 이와 같이 계속됩니다. 이러한 요소들이 로딩되는 순서에 따라 동일한 패키지의 다른 버전이 동시에 실행되어 프로젝트가 망가질 수 있습니다. 이 문제를 해결하기 위한 패키지들이 있기는 하지만, 물론 다른 문제를 유발하여 다른 패키지가 필요할 수 있습니다... 이것은 '안녕, 세계' 프로젝트가 40,000개 이상의 파일이 필요하다는, 진정으로 혼란스럽고 재미있는 일입니다.

하지만 기다려 보세요, 상황은 악화됩니다: 일부 종속성이 Node.js, Java 및 yarn과 같은 시스템 관련 요소인 경우, 개발자가 OS를 업데이트하면 애플리케이션이 손상될 수 있습니다. 이것이 Docker가 매우 구체적인 OS 상태를 컨테이너에 동결하여 특정 프로젝트에 사용할 수 있도록 하는 이유 중 하나입니다. 결국 문제가 발생하면 원인을 해결하는 대신 새로운 도구를 만드는 것이 좋은 아이디어가 아닐까요? 이것이 현대 웹의 요지입니다.

깃허브의 blame 페이지[6]에서도 놀라운 예제를 볼 수 있습니다. 이 페이지는 이 바보 같은 React 뷰포트 '최적화'를 구현했는데, 브라우저 검색 기능을 사용하여 뷰포트 바깥의 내용을 찾으면 결과가 표시되지 않습니다. 이처럼 천재들은 무엇을 했을까요? React와 쓰레기 npm 패키지를 사용하여 자체 검색 기능을 만들었고, 결과로 거의 3MB의 최소화된 JavaScript 코드가 생성되었습니다. 단순한 정적 HTML만으로도 수 천 개의 행이 있는 상호작용하는 테이블을 중저가 폰에서도 잘 렌더링할 수 있다는 것을 알았다면 어땠을까요?

거북보다 더 빠르거나 아닐지도 모릅니다

2015년 발표에서 React의 주요 개발자 중 한 명인 Tom Occhino은 다음을 말했습니다 [7]:

JavaScript land에서는 추상화가 많을수록 성능이 떨어진다는 것을 모두 알고 있었습니다. 그들은 누군가가 마법을 부리길 바라고 있었지만, 우리가 알다시피 그런 일은 결코 일어나지 않았고 아마도 결코 일어나지 않을 것입니다. 2018년, Netflix가 React에서 순수 JavaScript로 포털을 마이그레이션했다고 발표했는데, 결과적으로 JavaScript 번들 크기가 1/5로 줄어들어 페이지 로드 시간이 50% 빨라졌다고 합니다 [8].

2020년, Jeremy Wagner가 React와 순수 JavaScript를 비교하는 성능 테스트를 진행한 놀라운 기사를 썼습니다. 화면에 컴포넌트 하나만 표시하는 것을 보여주기 위한 것이었습니다 [9]. 여기서 두 배 빠르다는 얘기가 아닙니다. 아니요, 24배 빠른 것을 말하는 것입니다:

이미지

Material UI는 React를 위한 가장 인기 있는 라이브러리 중 하나입니다. 매주 400만 번의 다운로드 [10]를 기록하고 있습니다. 이는 React 생태계에서 성능 재앙의 또 다른 예입니다. 모바일 모드에서 단순한 버튼으로 화면을 로드하는 데 사용된 전체 시간은 JavaScript와 함께 소모됩니다. 똑같이 보이는 스타일의 버튼만 있는 화면입니다:

화면 로딩 시간

어떤 사람들은 '한 페이지에 수천 개의 버튼을 넣는 사람은 없다'는 주장으로 혼동시키려 할 수도 있습니다. 하지만 중요한 점을 놓쳐버리는데요. 이러한 인기 있는 React 패키지들은 순수한 React와 비교했을 때 극도로 비효율적입니다. 이미 우리는 React가 느리다는 것을 알고 있습니다. 반면, 이 테스트에서 정적 HTML은 JavaScript가 필요하지 않기 때문에 0밀리초가 걸립니다.

Material UI로 인한 엔트로피의 증가는 JavaScript 프로세스 뿐만 아니라 최종 HTML에도 영향을 미칩니다. Material UI의 경우 DOM 요소 수가 두 배로 늘어나고 파일 크기는 10배나 증가했습니다! 사용자 관점에서 다시 말하면, 이 테스트에서 Material UI와 순수 React는 똑같이 보입니다.

리액트 네이티브에서는 50개 이상의 텍스트만 있는 FlatList 구성 요소가 있으면 성능이 좋지 않을 수 있고 리액트가 이 문제를 확인하면 다음과 같은 메시지를 표시할 수 있습니다:

우리가 뭘 잘못했는지 알면서도, 그럼에도 불구하고 기본적으로 올바른 작업을 왜 하지 않는 걸까요? 이건 핵심을 놓치고 있는 걸까요? 사실은 2024년에도 여전히 누군가가 우리에게 리스트 같은 간단한 것이 합리적인 시나리오에서도 느릴 수 있다고 설득하려고 시도한다는 것 자체가 단지 수용할 수 없어요. 리액트 공식 문서를 읽으면서 점점 더 현실감을 잃게 됩니다 [11]:

이미지

리액트는 코드에 버그가 있을 수 있다고 인정하며, 절대 위치 지정을 '복잡한' 것이라고 부르기까지 해요. 정말 그런가요?! 이 부분이 비참해 보이지 않는다면, 다른 방법을 시도해보세요.

1997년 Id software에서 Quake 2를 출시했어요. 이 게임은 그 당시의 기계에서 초당 60프레임을 제공할 수 있었어요. 이것은 엔진이 16 밀리초마다 수백 개의 다각형, 텍스처, 다이나믹 라이트, AI, 물리학, 애니메이션, 다중 디바이스 입력, 복수 채널 오디오, I/O, 네트워크 동기화, HUD 등을 처리해야 했다는 뜻이에요. 우리가 오늘날 보는 대부분의 웹 애플리케이션에 비해 훨씬 복잡한 애플리케이션에 대해 언급하고 있습니다.

현재 우리 주머니 속에 있는 작은 기기는 1997년의 컴퓨터보다 100배 빠릅니다. 그런데도 단순한 정적 표만 표시하는 웹사이트조차 사용자를 위한 HTML을 생성하는 JavaScript 코드를 생성하는 데 몇 초가 걸리죠. 우리가 이런 것을 이루지 못한 것뿐만 아니라, 더 나쁜 것은 이런 상황을 정상화했다는 것에 대해 얘기하고 있어요. 현재의 웹 애플리케이션은 적어도 Quake 2가 사용된 시대의 기계에서 사용했던 것보다 100배 빠르게 실행되어야 해요!

개발자들은 HTML과 CSS가 얼마나 빠르게 구문 분석되고 렌더링될 수 있는지 전혀 모르는 것 같아요. 웹의 느림은 이 두 가지가 원인이 되는 것이 아니에요, 제 개발자가 무언가 놀라운 바보 같은 일을 하는 경우를 제외하면요. 바닐라 JavaScript조차 사용량에 맞게 사용하면 꽤 괜찮은 성능을 발휘할 수 있어요. 예를 들어, JSON에서 천 개의 항목을 구문 분석하고 해당 내용을 HTML 표에 채워 넣을 수 있어요. 그 정도로 빠른 속도로요. JSON을 다운로드한 후, 나머지 과정에는 비동기 호출이 필요하지 않아요.

웹의 성능 저하를 피하기 위해 개발자들이 갈망하는 모든 최적화는 대부분 이 종대한 프레임워크와 그 패키지들의 비효율성 때문이에요. 현대적인 도구들이 기본적으로 쓰레기를 전달할 것이라는 개념을 정상화하고, 만약 결과에 만족스럽지 않으면 개발자가 해결책을 찾아야 한다는 것은 완전히 어처구니 없어요. 자동차 제조사가 정비사에게 말하는 것을 상상해보세요: 엔진을 최적화해서 고객의 자동차가 제대로 작동하게 하세요.

오, 그리고 마주한 문제를 해결하기 위해 외부 도움을 찾아보는 데는 행운이 따를 겁니다. 각 상황마다 적용되는 답변이 수십 개씩 있기 때문에 애플리케이션 뒤에 있는 도구/버전의 마법 조합에 따라 적용 여부가 달라질 수 있습니다. 그리고 가능한 조합이 많아서 당신의 경우가 독특할 가능성이 높습니다. '답변 A가 작동하지 않았지만, 답변 B는 됐다'와 같은 내용을 읽는 것은 흔치 않죠.

JavaScript 번들 치료

웹 애플리케이션의 JavaScript 코드를 구문 분석하고 번들링하는 끝없는 도구들이 있지만 웹팩이 가장 인기가 많다는 사실을 알게 될 겁니다. 왜냐하면 JavaScript로 작성되었기 때문이겠지만, 맞죠? 하지만 놀라운 점은 그 성능이 얼마나 끔찍한지입니다. CPU 성능만큼이나 특히 메모리 측면에서: 5GB의 RAM이 필요하다니, React 애플리케이션을 15만 줄의 코드로 번들링하려면 (의존성을 제외하고 말이죠). 이런 압도적인 상황이 현대적으로 정상으로 여겨집니다. 더 이상 이에 대해 의문을 제기하는 사람은 없습니다. 우리는 이따금 이 쓰레기 생태계에 대해 고마워해야 한다고 침묵하고 있어야 합니다.

더욱 짜증나는 점은 웹팩의 주요 미션을 제대로 수행하지 못한다는 점입니다. 사용되지 않는 JavaScript 코드를 모두 제거하는 대신 (그렇게 불리는 트리 셰이킹), 도달할 수 없는 불필요한 코드를 번들링하려고 밀어붙입니다. 예를 들어, 클래스 A를 상상해보세요:

import React from 'react'
import { myEnum } from './classB'

const classA = () => {
  if (myEnum)
    console.log("hello")
}

그리고 classB:

import React from 'react'
import { CssBaseline } from '@mui/material'

export enum myEnum {
  item
}

const classB = () => {
  return (
    <div>
      <CssBaseline />
    </div>
  )
}

클래스 A는 클래스 B에서 분리된 enum을 import하고 CssBaseline을 사용하지 않으므로 JavaScript 번들러가 해당 부분을 제외하도록 예상됩니다. 그러나 그렇지 않습니다! 다시 말하면, 선언된 클래스의 모든 import를 재귀적으로 번들링하게 됩니다. 이러한 실수를 모두 합치면 다음과 같은 결과가 나옵니다:

Web Crap Has Taken Control

하지만 코드가 사용되지 않는다면 괜찮을거라고 생각하시나요? JavaScript 코드는 보통 클라이언트 측에서 다운로드되고 구문 분석되며 컴파일되므로 그 크기와 기기에 따라 성능이 매우 나쁠 수 있습니다. 캐싱 후에조차 악화되는 경우가 있으며, 배터리 수명이 줄어드는 경우도 있습니다. 이것이 대부분의 애플리케이션이 코드를 "최소화된 버전"으로 제공하는 주된 이유입니다. 개념상 결함이 있는 것을 최적화하기 위한 또 다른 해결책일 뿐입니다.

가끔 웹 개발이 그냥 장난일까 생각해봅니다. yarn install [패키지]를 호출하려고 할 때 이 가닥쓰레기를 보세요:

Web Crap Has Taken Control

Yarn 프로젝트의 개발자들이 패키지를 설치하는 데 사용했던 검증된 키워드를 그냥 제거하기로 결정했어요. 그리고 더 나빠진 점은, 사용자가 올바른 방법을 알려주는 메시지를 추가했어요. 사실 사용자가 뭘 하려는지 정확히 알기 때문에, 그냥 물건을 설치하는 것보다 더 번거로운 작업이죠! 이들의 마음속에는 분명히 약간의 즐기는 측면이 있어 보여요.

WebCrapHasTakenControl_10 이미지

웹 쓰레기가 얼마나 나아질까요

서버 쪽은 어떤가요? 아마도 더 상식적이고 효율적이며 안정적일 거예요, 맞죠? 2009년에 Node.js가 출시된 이후로, 모든 종류의 서버가 이 JavaScript 프레임워크로 작성되거나 이식되었어요. 이 시점에서 Node.js가 주로 JavaScript로 작성되어 있다는 사실은 더 예측할 수 없을 정도에요. JavaScript는 매우 한정적이고 비효율적이며 분명히 서버를 다루기에는 설계된 것이 아니에요. 심지어 멀티 스레드를 지원하지도 않죠.

여기서 조금 멈추고 일어나서 일어나서 무슨 일이 일어나고 있는지 생각해 봅시다. C/C++ 또는 Rust와 같은 정적 컴파일된 언어에서는 개발자가 애플리케이션을 한 번 컴파일하기 때문에 사용자들이 이를 절대 해 줄 필요가 없습니다. 하지만 JavaScript와 같은 JIT(Just-In-Time) 컴파일된 언어에서는 각 사용자가 코드를 컴파일해야 하는데, 애플리케이션을 실행할 때마다 다시 컴파일해야 합니다. 또한 컴파일된 후에도 정적으로 컴파일된 언어만큼 빠르게 작동하지 않을 것임을 언급할 필요가 있습니다. 게다가 JavaScript 프레임워크에 의해 소개된 이 모든 쓰레기 코드를 첨가하면서 비효율성이 정말 미친 듯 하게 커지고 있는 것 같아요.

좋아요, 온라인 애플리케이션은 가능한 최대로 피하고 대부분이 분명히 망가진 상태라는 점을 염두에 둬요. 우리가 필요한 애플리케이션의 데스크톱 버전을 시도해 봅시다, 예를 들면 Postman 같은 도구로 엔드포인트를 테스트하는 데 개발된 이 도구를 말이에요.

Postman

이 데스크톱 애플리케이션에서 웹의 냄새가 난다면, 틀린 건 아닙니다. Postman은 Electron을 사용하여 작성되었으며, 이는 Chromium 브라우저가 포함된 전체 환경을 내장하고 있습니다. 또한 놀랍게도 React Native로 작성되어 있습니다.

2024-08-26-WebCrapHasTakenControl_12.png

네, 당신의 데스크톱 애플리케이션은 사실상 단조로운 HTML을 생성하기 위해 끔찍한 React Native 코드에 의존하고 있는 브라우저에 접근하는 것입니다. 그래서 그 모든 것의 가격은 무엇인가요? 11.3.2 버전의 리눅스에서는 22,000개의 파일이 410MB의 저장 공간을 차지하고, 용의 초기 화면을 로드하기 위해 700MB 이상의 RAM이 소비됩니다. 최신의 curl 8.8.0 버전은 더 강력하지만 공간을 1MB 차지하는 파일 3개만 사용하며, 단지 10MB의 RAM을 소비하는 이 가벼움은 UI가 없기 때문이라고 주장합니다. 물론, 물론...

2024-08-26-WebCrapHasTakenControl_13.png

이 Electron 악몽은 Discord, Dropbox, GitHub, Teams, Spotify, Visual Studio Code, WhatsApp 등 많은 인기 있는 데스크톱 애플리케이션들을 포함하여 모든 곳에 퍼져 있습니다. 이 모든 것들은 Postman과 비슷하게 동작합니다. 또한 모바일 영역에 있어서도 마찬가지입니다. 대부분의 소프트웨어 회사들은 각 플랫폼마다 다른 애플리케이션에 투자하고 싶어하지 않기 때문입니다. 그래서 웹 애플리케이션이 모바일 또는 데스크톱 버전도 가지고 있다면, 그 모든 것들이 느린 JavaScript 프레임워크를 사용하여 작성되고 내장 브라우저를 갖고 온다는 것이 많습니다.

과거에는 유연한 프로그래밍 언어가 다중 플랫폼을 지원하고, 컴파일러가 각 플랫폼용 이진 파일을 생성하는 것이 일반적이었습니다. 그러나 JavaScript 컴파일러는 브라우저 안에 있기 때문에, 개발자들은 데스크톱 및 모바일 애플리케이션을 내장된 브라우저와 함께 제공하는 것 외에 대안이 없다고 보고 있습니다. 그런데 현재 브라우저는 리눅스 커널보다 더 많은 코드 라인을 갖는 거대한 몬스터들입니다. 이 정도까지 얘기하면 부끄러워지는데 이걸 적는 것 자체가 어리석은 것 같습니다.

JavaScript에 의해 건드려지지 않은 유일한 범주는 운영 체제인 것일까요? 정확하게는 그렇지 않습니다. 가장 인기 있는 리눅스의 그래픽 환경인 GNOME은 그 쉘 코드의 50%가 JavaScript로 작성되어 있으며, GNOME을 위한 타사 확장은 완전히 JavaScript로 작성되어야 합니다. 특권 프로세스에게 권한이 없는 프로세스가 특권 프로세스와 대화할 수 있게 해주는 인기 있는 리눅스 애플리케이션인 PolicyKit도 JavaScript 엔진에 의존합니다.

웹젭이 제어를 쥐고 있다

명센스의 한 줄기

어떤 해결책이 있을까요? 대부분의 웹 애플리케이션에는 정적 HTML만으로도 충분하다고 말할 수 있지만, 개발자가 템플릿/컴포넌트, 자동 DOM 업데이트, 제3자 플러그인 지원 등과 같은 편의 기능을 원할 수 있다는 점은 이해할 만하죠. 다행히 세상에는 아직 정상적인 사람들이 몇 명 있고, 그 중 일부가 성능에 중점을 둔 경량 멀티플랫폼 프레임워크인 SvelteKit을 만들기로 결정했습니다. 각 주요 릴리스마다 더욱 빠르고 작아지는 이 프레임워크는 React에서 선전하는 바보같은 트렌드를 강요하지 않고, 우리가 도구에서 기대하는 것을 제공하는 역할을 합니다: 개발자를 돕는 동시에 사용자에게 훌륭한 경험을 제공합니다.

image

하지만, 웹 애플리케이션이 본질적으로 복잡한 경우에는 JavaScript만으로는 부적합합니다. 이 경우에는 올바른 프로그래밍 언어를 사용하는 것이 좋습니다. 예를 들어, 브라질로 프레임워크는 웹어셈블리를 사용하여 브라우저에서 C# 코드를 직접 실행하는 방식입니다. 기이한 문법, 복잡한 코드 흐름, 인프라 혼란, 특히 예측할 수 없는 성능 없이 진행되는 것이 없습니다.

가장 중요한 것은 복잡성을 피하는 것입니다. React는 단 하나의 큰 예시일 뿐이지만, 프로젝트에 불필요한 엔트로피를 추가하는 다른 많은 방법들이 있습니다. 하루 종일 코드를 싸우는 데 투자할 필요가 있는 줄 알지 마세요. 가능한 한 가장 간단한 생태계로 시작하고, 여러 요소를 실험해보세요. 가능한 한 의존성을 피하세요. 움직이는 부분이 적을수록 좋습니다. 무언가가 과도하게 복잡해지기 시작하거나 내부에서 무엇이 일어나고 있는지 제어할 수 없다고 느낀다면, 다시 되돌아가서 팀에게 변칙적인 사고를 하도록 도전하세요. 방향이 잘못된 것 같으면 포기하는 것도 전혀 괜찮습니다. 우리는 지금 이 분야에 몇 십 년의 인간 경험과 놀라운 하드웨어와 도구를 가지고 있기 때문에 변명할 것이 전혀 없습니다.

일부 사람들이 중간(Medium)이 이 기사에서 논의된 같은 문제를 겪고 있다고 불평했습니다. 그게 사실이죠. 중간은 분명히 부풀려져 있고 끊임없는 팝업이 귀찮습니다. 죄송합니다. 하지만 이 기사로 돈을 받지 않고 있고 다른 플랫폼으로 전환을 고려 중입니다 — 암튼, 대부분은 처음에는 좋았지만 시간이 지날수록 배짱하게 변합니다.

토론: 해커 뉴스(Hackers News)