프론트엔드 개발의 변천사

김동환·2023년 8월 19일
34

개발자 이야기

목록 보기
2/9
post-thumbnail

자바스크립트 여명기와 제이쿼리의 인기

  • 자바스크립트의 유용한 활용 방법은 폼의 유효성 검사(validation)정도 였다.
  • 과도한 애니메이션 구현이나 브라우저에 부담을 주어 브라우저 크래시를 일으키는 구현이 증가하면서 자바스크립트는 악질적인 사이트를 만들어내는 원인이 되었었다. 시간이 지남에 따라 사람들이 받아들이게 되면서, 결과적으로 당시 자바스크립트는 프론트엔드의 겉모습을 꾸미는 정도의 보조적인 요소로만 쓰였다.
  • 2005년에 구글에서 Google Maps 를 출시하면서 판도가 바뀌었다. 구글 지도는 비동기로 HTTP 통신을 하는 Ajax 를 활용해 웹에서 인터랙티브한 애플리케이션을 구현했다. Ajax는 Asynchronous JavaScript and XML의 약어로 자바스크립트를 사용해 비동기로 데이터 통신을 하는 구현 방법을 나타낸다.

제이쿼리의 전성기

  • Ajax 의 충격 이후, 웹 앱의 진화가 계속된다. 기존보다 많은 기능을 가진 RIA(Rich Internet Application)이라 불리는 클라이언트 사이드의 구현으로서 Ajax나 고도의 DOM 조작이 요구되었다.
  • 당시 제이쿼리는 다음과 같은 점에서 획기적이었다.
    • 크로스 브라우저 호환을 구현할 수 있다.
    • DOM을 간결하게 조작할 수 있다.
    • 애니메이션을 간결하게 구현할 수 있다.
    • jQuery UI 등 주변 라이브러리가 풍부하다.
  • 풍부한 웹 앱에 자주 사용되는 대화 상자(dialog)나 폼의 구현 등을 간략하게 구현할 수 있는 패키지가 제공되어, 당시 많은 프론드엔드 엔지니어가 제이쿼리를 무조건 사용할 정도로 널리 보급되었다.

제이쿼리의 인기 하락

  • 제이쿼리 전성기 이후 프론트엔드의 요건은 점점 복잡해졌다. 이런 흐름 가운데, 제이쿼리는 점차 자취를 감췄다. 이유는 다음과 같다.
    • 글로벌 스코프를 오염시킨다.
    • DOM 조작 구현이 복잡해지기 쉽다.
    • 라우팅(routing)등 여러 페이지의 웹 앱을 구현하는 구조가 없다.
    • 브라우저의 표준화로 작동의 차이가 점점 눈에 띄지 않아, 브라우저 호환 코드가 필요하지 않게 됐다.
  • 제이쿼리를 사용하는 대규모 앱 개발에서 자바스크립트의 글로벌 스코프가 오염되는 점이 특히 큰 문제였다. 이것은 모던한 프론트엔드 개발의 축이 되는 SPA나 컴포넌트 지향 사고방식과 잘 맞지 않다. 이런 배경으로 제이쿼리는 점점 쓰이지 않게 됐다. 웹사이트 제작 애니메이션을 만드는 자바스크립트 구현으로서는 아직 쓰이지만, 대규모 웹 앱 개발에 제이쿼리를 활용하는 사례는 줄어들고 있다.

SPA의 등장과 MVC/MVVM 프레임워크

  • 싱글 페이지 애플리케이션(SPA)란 기동 시에 한 차례 HTML 전체를 로드하고, 이후에는 사용자 인터랙션에 맞춰 Ajax 로 정보를 얻고, 동적으로 페이지를 업데이트하는 웹 앱을 말한다. SPA에서는 페이지 이동을 클라이언트 사이드에서 수행한다. 이때 Ajax 를 사용해, 필요할 때 필요한 부분만 데이터를 얻어 뷰를 표시하므로 오버헤드가 줄어든다.

SPA 를 도입하는 장점은 다음과 같다.

  • 고성능의 애플리케이션을 제공할 수 있다.
  • 서버 사이드 엔지니어와 프론트 엔드 엔지니어의 분업이 쉬워진다.
  • JSON API 를 통해 느슨한 결합의 설계를 할 수 있다.
  • IOS나 안드로이드등 네이티브 앱 클라이언트에 대해서도 API를 통한 느슨한 결합의 시스템을 구성해 대응할 수 있다.

반대로 다음과 같은 단점도 있다.

  • 자바스크립트 읽기와 렌더링이 발생하며, 이에 대한 대책이 없으면 초기 표시에 다소 시간이 걸린다(Next.js 에서는 해결 됨)
  • 프론트엔드 학습 비용이 높다.
  • 프론트엔드 코드양이 많아진다.
  • 경험이 풍부한 사람을 채용하기 어렵다.

SPA는 다음과 같은 기술 요소로 구성된다.

  • URL 경로와 뷰의 라우팅 관리
  • 클라이언트 사이드에서의 브라우저 이력 관리를 통한 페이지 이동
  • 비동기를 통한 데이터 얻기
  • 뷰 렌더링
  • 모듈화된 코드 관리

따라서 React Router 같은 라우팅 기능을 가진 라이브러리를 사용해 SPA를 구현하는 것이 일반적이다.

Next.js는 라우팅 기능을 내장하고 있으며, 그 밖에도 SPA 와 같은 앱을 개발하기 위한 편리한 기능이 모여있다.

  • History API 는 HTML5 에 도입된 기능으로 페이지 이동/이력을 자바스크립트로 다룰 수 있다.

MVC/MVVM 자바스크립트 라이브러리 난립 시대

  • 2009년 경부터 웹 앱은 SPA를 대표로 복잡한 요건이 요구되는 경향이 있었으며, 프론트 엔드 개발의 패러다임 시프트가 일어났다. 제이쿼리는 자취를 감추고 MVC/MVVM 을 활용한 Backbone.js , AngularJS 등 새로운 웹 앱 프레임워크, 라이브러리가 나타났다.
  • MVC  프레임워크로서 당시 경량으로 인기가 높았던 것이 Backbone.js 였다. MVC모델을 도입함으로써 뷰와 모델이 직접 연동하는 것이 사라지고, 프론트엔드 프레임워크의 아키텍처가, 유지보수성이 높은 프론트엔드 개발을 지탱하는 것이라는 인식이 많아졌다.
  • Backbone.js 가 유행한 뒤 MVVM 라이브러리가 난립하기 시작했다. MVVM이란 데이터를 관리하는 Model, 화면 표시와 관련된 View, 데이터와 표시의 가교 역할을 하는 ViewModel을 사용한 아키텍처다.
  • MVVM에서는 모델로부터 뷰로 데이터를 연동하고, 뷰로부터 모델로 데이터의 양방향 바인딩을 수행하는 아키텍처로, DOM 조작 코드를 작성하지 않고도 데이터 변경을 반영할 수 있다. 그리고 UI로부터 정보 입력이 데이터와 자동으로 동기화됨에 따라 생산성이 높은 프론트엔드를 구현할 수 있다. 유명한 라이브러리에는 AngularJS, KnockoutJS, Riot.js, Vue.js 가 있다.

리액트의 등장과 컴포넌트 지향/상태 관리

  • 리액트는 2013년에 페이스북이 공개한 UI 라이브러리 이다.
  • 리액트의 특징으로 다음이 있다.
    • 가상 DOM
    • 선언적 UI
    • 단방향 데이터 전달
    • 컴포넌트 지향 / 함수 컴포넌트
    • 플럭스(Flux) 아키텍처와의 친화성
  • 리액트의 특히 획기적이었던 점은 가상DOM과 상태 관리 설계라고 할 수 있다.
  • 리액트는 API를 작게 유지하는 등 학습 비용을 함부로 늘리지 않도록 설계한다.

대규모용 상태관리 Flux

  • 컴포넌트 지향 앱을 개발하면서 앱이 복잡해지면 상태(state) 관리가 중요해진다.

  • 페이스북은 KnockoutJS 와 AngularJS를 필두로 빠르게 보급된 MVVM 프레임워크의 양방향 데이터 바인딩 기능에 대해 문제를 제기했다. 양방향 데이터 바인딩을 활용해 앱을 개발하면 코드가 간략해지는 장점이 있지만, 지나치게 사용하면 어디의 변경이 어디에 영향을 미치는지 추적하기 어렵고, 코드의 복잡성이 높아진다는 이유였다.

  • 그래서 2014년에 페이스북은 플럭스 앱 아키텍쳐를 제안한다. 플럭스를 사용하면 데이터 흐름을 단방향으로 한정 함으로써 상태를 좀 더 쉽게 관리할 수 있다. 다음 그림에 플럭스의 데이터 흐름의 구조를 나타냈다. MVC와 같은 설계상의 지침으로서 기능하며, 데이터 흐름이 단방향이라는 점이 특징이다.

    현재는 플럭스를 발전적으로 계승한 리덕스(Redux)라는 라이브러리가 인기를 얻고 있다.

  • 리액트가 등장한지 수년이 지난 지금도 인기를 유지하고 있는 이유로 가상DOM의 발명뿐만 아니라, Flux와 같은 ‘데이터 흐름’에 관한 제안도 적극적으로 있었던 것을 들 수 있다.


Node.js의 약진

  • Node.js는 서버 사이드에서 자바스크립트를 실행 할 수 있는 환경이다. 2009년에 라이언 달이 구글 크롬에 탑재된 자바스크립트 실행 엔진인 V8 을 사용해서 만들었다. 논블로킹(non-blocking) I/O라 불리며 여러 요청을 짧은 지연으로 처리할 수 있는 성능이 주목을 받았다.
  • 이제까지 웹 앱에서는 웹 서버 측의 프로그램은 PHP나 자바 등의 언어로 개발하고, 프론트엔드는 자바스크립트로 개발하는 것이 일반적이었다. Node.js가 등장함에 따라 프론트엔드 엔지니어가 사용하는 언어를 그대로 사용해 서버 사이드를 구현할 수 있게 되어, 서버 사이드와 프론트엔드 사이의 코드 공통화도 가능하게 됐다.
  • Node.js는 그저 서버 사이드에서도 자바스크립트를 실행하는 기능에 그치지 않고, 진화를 계속하고 있다. CLI 도구 등 로컬에서 활용할 수 있는 도구에서도 자바스크립트 에코 시스템을 만들어냈다.
  • Node.js의 공적에는 npm이라 불리는 패키지 관리자, 패키지 시스템의 존재도 빼놓을 수 없다. npm은 프론트엔드 개발에 패키지 개념을 도입했다.
  • npm 을 활용해 얻을 수 있는 장점은 다음과 같다.
    • 모듈 로딩 구조
    • 패키지 관리
    • 빌드 시스템
    • 엔지니어 채용 시 기술 스택 동일
  • 현재 많은 OSS(Open Source Software)가 npm을 통해 배포되고 있으며, 앱 측은 사용할 라이브러리와 버전을 package.json에 지정해서 기술하기만 하면 해당 라이브러리를 삽입할 수 있다. 이 구조로 인해 자바스크립트의 프로그램이 모듈이라는 단위로 분할되므로, 유지보수성이나 재사용성이 향상된다.
  • 현재 프론트엔드 개발은 모듈을 import해 트랜스파일(transpile)하기 위한 빌드 시스템도 당연하게 보급 됐다. 이 빌드 시스템을 통해 많은 모듈로 개발된 것을 하나로 압축된 자바스크립트로서 브라우저에 쉽게 로드할 수 있다. 또한 개발 시, 배포 시에 빌드라는 프로세스를 통해 자바스크립트 파일을 수행하므로, 개발자는 자바스크립트뿐만 아니라 다른 언어에서 기술할 수 있는 AltJS라는 발상도 생겨났다.

Deno

  • Deno는 JSConf EU 2018 에서 라이언 달의 강연 ‘Node.js에 관한 10가지 반성’ 에서 발표된 새로운 자바스크립트, 타입스크립트 런타임 이다. 특히 보안 부분과 npm등의 패키지 관리 도구를 별도로 준비하지 않는 설계를 채용한 점이 Node.js와 다르다.
  • Node의 앞 글자인 No와 de를 반대로 하여 붙인 이름이다. 특징은 다음과 같다.
    • 파일이나 네트워크 접근 등은 명시적으로 선언한 경우에만 허가한다.
    • 타입스크립트를 기본으로 사용할 수 있다.
    • 모듈 의존 환경인 npm과 package.json 폐지
    • ES 모듈 형식으로 지정해 import를 수행하고, 실행시 모듈 관리가 수행된다.
    • 실행 환경은 단일 바이너리 파일로 제공된다.

더 자세히 알아보기


AltJS의 유행과 타입스크립트의 꾸준한 확산

  • AltJS는 컴파일을 통해 자바스크립트를 생성하는 프로그래밍 언어이다. 자바스크립트는 프로그래밍 언어로서 인기가 있고 특히 프론트엔드 개발에서의 입지를 굳건히 지키고 있지만, 자바스크립트 언어 문법 등에 문제가 있다고 생각하는 개발자도 적지 않다. 2010년경부터 커피스크립트(CoffeScript)를 시작으로 자바스크립트가 아닌 언어로 코드를 기술하고, 그것을 자바스크립트로 컴파일하는 방식의 클로저스크립트(ClojureScript)와 다트(Dart)같은 AltJS가 다수 생겨났다. 한 언어를 다른 언어로 컴파일하는 것을 트랜스파일이라 부른다.
  • AltJS 와는 다소 발상이 다르지만 바벨(Babel) 이라는 도구도 주목을 받고 있다. ECMA가 매년 명세를 결정하면 브라우저 벤더의 구현이 그 사양에 따라 기능을 제공할 때까지 시간이 걸려 상당히 균형이 맞지 않았다.바벨은 새로운 ES6사양의 자바스크립트 로딩. 그리고 표준 구현되지 않은 브라우저용의 ES5 형식으로 출력을 할 수 있어 자바스크립트의 최신 사양에 앞서는 도구다.

빌드 도구와 태스크 러너

  • 빌드 시스템이란 소스 코드상에 로딩한 모듈의 의존성을 해결하고, 실행 가능한 자바스크립트 형식으로 변환하는 구조이다. 이 구조는 자바스크립트를 사용한 서버 사이드/프론트엔드 양쪽의 개발에도 사용된다.
  • 2012년경 Node.js, npm을 통해 서버 사이드 자바스크립트 패키지 관리가 용이하게 되고, 그 구조를 프론트엔드 개발에 가지고 오려는 움직임이 활발했다. RequireJS 나 Browserify등이 각각 AMD 형식과 CommonsJS 형식의 모듈을 브라우저에서 사용할 수 있도록 한 도구로서 사용됐다.
  • 태스크 러너 도구 자체의 학습 비용이 있기 때문에 그 사용도가 점점 줄어들었다. 패키지를 관리하는 npm 스크립트를 활용한 커맨드 실행을 사용하는 방향으로 바뀌었다.
  • 2015년경부터 웹팩(Webpack)을 시작으로 빌드 도구의 존재감이 커졌다. 빌드 도구는 많은 기능을 가진 프론트엔드 개발 환경을 극적으로 변화시켰다. 커맨드라인에서 빌드를 실행할 수 있고, 필요한 파라미터나 플러그인을 임의로 삽입할 수도 있다.
  • 웹팩을 활용하면 다음과 같은 장점이 있다.
    • 사용하는 의존 모듈의 버전 관리와 해결을 자동화할 수 있다.
    • 파일 결합이나 코드 압축 등을 자동화할 수 있다.
    • 플러그인 메커니즘을 통해 다양하게 커스터마이즈할 수 있다.
    • hot report 등 개발 효율화 도구를 포함하고 있다.

최근에는 ES 모듈 기반으로 라이브러리 배포 등에 사용되는 rollup.js이나 Next.js에서도 채용된 고속의 러스트(Rust) 기반 SWC 라는 빌드 도구도 등장했다.


SSR/SSG의 필요성

  • SPA등의 클라이언트 사이드 렌더링은 그대로 사용하면 초기 표시가 지연되는 문제가 있다. 이를 해결 하는 데 중요한 것인 SSR / SSG 이다.

SSR

서버 사이드 렌더링은 서버 사이드 자바스크립트 실행 환경에서 요청에 대한 페이지를 생성해서 HTML을 반환하는 것이다. 리액트에서는 보통 사용자의 브라우저가 자바스크립트를 실행하고, JSON을 기반으로 페이지를 구축한다. 그에 반해 SSR은 서버측에서 이를 수행하고 HTML을 생성해서 반환한다.

  • SPA로 대표되는 클라이언트 사이드에서의 구현에 비해 SSR을 도입해서 얻을 수 있는 장점은 다음과 같다.
    • 렌더링을 서버 사이드에서 수행한 결과를 반환하므로, 사이트를 빠르게 표시할 수 있다.
    • 서버 사이드에서 콘텐츠를 생성하므로 SPA에서는 복잡했던 SEO를 향상할 수 있다.
  • 한편 단점은 다음과 같다.
    • Node.js 등 서버 사이드 자바스크립트 실행 환경이 필요하다.
    • 서버 사이드에서 렌더링하므로 서버 CPU의 부하가 증가한다.
    • 서버와 클라이언트에서 자바스크립트의 로직이 분산될 가능성이 있다.

SSG

  • 정적 사이트 생성(SSG : Static Site Generation)은 사전에 정적 파일로서 생성, 배포하는 구조이다.
  • SSR에서는 서버로 접근할 때 HTML을 생성하므로, 트래픽이 많을 때는 서버의 부하에 관해 고려해야만 한다. SSG의 개념은 SSR의 관점을 보완한다.
  • 예를들어, 블로그 같은 사이트 구축을 가정한 경우 등, 포스트의 상세 페이지를 사전에 렌더링한 결과를 서버상에서 처리하지 않고, 정적 HTML 파일로서 호스팅할 수 있다. 그에 따라 보다 경량의 부하로 강력한 서비스를 구축할 수 있다.
  • 단 예를 들어 로그인하는 사용자에 따라 표시를 전환할 필요가 있는 동적 콘텐츠를 송신해야 할 때는 상성이 좋지 않으므로, 사용하는 경우에 따라 적절하게 구분해서 사용해야 한다.

Next.js 등장

Next.js는 버셀사가 개발했으며, 리액트 기반 모던 애플리케이션을 위한 풀 스택 프레임워크이다. 리액트의 기능에 SSR 과 SSG 등의 기능을 추가해서 구현했다.

기존의 모던 웹 앱을 개발할 때는 리액트 기반의 React Router 를 사용해 SPA로서 렌더링하는 것이 주류였다. Next.js 에서는 앱의 특징에 맞춰 페이지의 렌더링을 서버 측에서 수행할 수 있기 때문에, SEO나 성능 측면에서도 뛰어나다.

Next.js는 프론트엔드 엔지니어들을 고민하게 했던 복잡한 프론트엔드 개발 환경을 단순화할 수 있는 다양한 기능을 포함한다.

  • 리액트 프레임워크
  • SPA / SSR / SSG 의 쉬운 전환
  • 간단한 페이지 라우팅
  • 타입스크립트 기반
  • 간단한 배포
  • 낮은 학습 비용
  • 웹팩 설정 은폐
  • 디렉터리 기반의 자동 라우팅 기능
  • 코드 분할 및 결합

참고자료 : <타입스크립트, 리액트, Next.js로 배우는 실전 웹 애플리케이션 개발>

profile
프론트엔드 개발자

8개의 댓글

comment-user-thumbnail
2023년 8월 20일

많은 분들이 봤으면 좋겠어요! 좋은 글 잘 보고 갑니다 :)

1개의 답글
comment-user-thumbnail
2023년 8월 25일

시간 가는 줄 모르고 재밌게 봤네요! 감사합니다~

1개의 답글
comment-user-thumbnail
2023년 8월 25일

잘봤습니다 :)

1개의 답글
comment-user-thumbnail
2023년 8월 30일

우와 잘 보고 갑니닷!! :)

1개의 답글