← 목록으로

선언형 vs 명령형 프로그래밍, 그리고 JavaScript 프레임워크의 변화

YEJI · 2025. 05. 28. 21:16 · 9분
목차

서론

얼마 전, 이해가 부족하다고 느꼈던 프로그래밍 패러다임을 시작으로 JavaScript 프레임워크의 변화 과정을 간단히 정리해 보려 합니다.

사실 관련 자료를 찾아보면서 정말 많은 글을 접는데 어떤 정보가 신뢰할 만한지 판단하기 어려워 여러 글을 읽어보았습니다. 다행히 대부분 비슷한 이야기를 하고 있었습니다. 그래서 그 내용들을 토대로, 그나마 신뢰성이 높다고 판단되는 아티클이나 공식 사이트들을 참고하여 글을 작성했습니다.

그럼 시작해보겠습니다! 🤩


프로그래밍 패러다임

프로그래밍 패러다임은 컴퓨터 프로그램을 구현하는 방식을 고수준에서 구조화하고 개념화하는 방법입니다. 하나의 프로그래밍 언어는 한 가지 이상의 패러다임을 지원할 수 있습니다. 패러다임은 다양한 프로그래밍의 차원을 기준으로 구분되며 설명됩니다.

  • 어떤 패러다임은 실행 모델의 영향을 중심으로 구성되며, 예를 들어 부작용(side effects)의 허용 여부나 명령의 실행 순서를 시스템이 결정하는지 여부가 해당됩니다.
  • 또 어떤 패러다임은 코드를 조직화하는 방식을 중심으로 구성되는데, 예를 들어 상태(state)와 동작(behavior)을 함께 묶어 관리하는 방법이 있습니다.
  • 그 외에도 문법과 구문(syntax and grammar) 중심으로 나뉘는 패러다임도 있습니다.

출처: 위키피디아 번역 인용


명령형 프로그래밍: '어떻게' 할지 지시하기

명령형 프로그래밍은 컴퓨터가 무엇을 '어떻게' 수행할지 단계별로 명확하게 지시하는 방식입니다. 개발자는 코드를 통해 프로그램의 실행 흐름을 직접 제어하며, 각 명령문이 순서대로 실행됩니다.

대표적인 언어와 예시

  • 언어: 포트란, 알골, 파스칼, C, 에이다 등

  • 코드 예시:

    js
    let numbers = [1, 2, 3, 4, 5];
    let doubled = [];
     
    for (let i = 0; i < numbers.length; i++) {
    doubled.push(numbers[i] * 2);
    }

    위 코드에서 우리는 i를 직접 증가시키고, push() 메서드로 배열에 값을 넣는 등 모든 과정을 명령형으로 제어합니다.


선언형 프로그래밍: '무엇을' 얻을지 선언하기

선언형 프로그래밍은 '무엇을' 달성하고 싶은지에 집중하고, '어떻게' 수행할지는 시스템에 맡기는 방식입니다. 개발자는 연산 논리를 표현하는 데 초점을 맞추며, 구체적인 제어 흐름은 명시하지 않습니다. 이러한 접근 방식은 특히 병렬 프로그래밍 작성을 단순화하는 데 효과적입니다.

대표적인 언어와 예시

  • 언어: 데이터베이스 질의 언어(SQL, XQuery), 정규 표현식, 함수형 프로그래밍 언어 등

  • 코드 예시:

    js
    const numbers = [1, 2, 3, 4, 5];
    const doubled = numbers.map((n) => n * 2);

    이 코드에서는 "각 요소를 2배로 만들어줘"라는 '무엇'을 하고 싶은지만 말합니다. 반복, push, 변수 제어 등 구체적인 흐름은 map 메서드 안에 숨겨져 있어 결과 중심의 표현이 가능합니다.

  • React 코드 예시:

    js
    import { useState } from "react";
     
    function Counter() {
    const [count, setCount] = useState(0);
     
    return (
    <div>
    <button onClick={() => setCount((c) => c + 1)}>+1</button>
    <div>{count}</div>
    </div>
    );
    }

    React 컴포넌트에서는 상태(count)가 바뀌면 UI가 자동으로 갱신됩니다. 개발자는 DOM을 직접 조작하지 않고, "상태가 바뀌면 UI가 이렇게 보여야 한다"는 연결을 선언합니다. 이는 최종적으로 무엇을 보여줄지를 선언하는 선언형 스타일의 대표적인 예시입니다.


jQuery를 선택하지 않고 React, Vue.js를 사용하는 이유

jQuery는 왜 사용되지 않게 되었을까?

jQuery는 2006년 출시되어 웹 개발에 혁신을 가져왔습니다. 복잡한 DOM 조작, 이벤트 처리, AJAX 요청 등을 '적게 쓰고, 더 많이' 할 수 있도록 단순화했고, 특히 브라우저 간 호환성 문제를 해결해 주어 개발자들의 폭넓은 사랑을 받았습니다. 하지만 시간이 흐르고 웹 환경이 발전하면서 jQuery의 한계가 드러나기 시작했습니다.


  • 과거 jQuery가 필요했던 브라우저 호환성 문제는 현대 브라우저의 발전과 웹 표준화로 대부분 해결되었습니다.
  • querySelector, fetch() API 등 네이티브 JavaScript만으로도 jQuery의 많은 기능을 대체할 수 있게 되었고, Promise, async/await 같은 비동기 처리 문법의 도입은 콜백 지옥을 효과적으로 해결했습니다.

React, Vue.js와 같은 프레임워크가 부상하는 이유

React, Vue.js와 같은 현대 프레임워크들은 이러한 jQuery의 한계를 극복하고, 복잡하고 동적인 현대 웹 애플리케이션의 요구사항을 충족시키기 위해 등장했습니다.


  1. 선언형 프로그래밍 패러다임:

    • 이들 프레임워크는 '무엇을' 보여줄지 선언하면, 프레임워크가 '어떻게' DOM을 업데이트할지 알아서 처리합니다. 개발자는 UI의 '최종 모습'에만 집중할 수 있어 코드의 가독성과 유지보수성이 크게 향상됩니다.
  2. 컴포넌트 기반 아키텍처:

    • UI를 작고 독립적이며 재사용 가능한 '컴포넌트' 단위로 나누어 개발합니다. 이는 코드의 모듈성과 재사용성을 극대화하여 대규모 애플리케이션을 효율적으로 구축하고 관리할 수 있게 합니다.
  3. 가상 DOM (Virtual DOM)을 통한 성능 최적화:

    • 실제 DOM을 직접 조작하는 대신, 메모리에 가상 DOM이라는 경량의 UI 표현을 만듭니다. 변경 사항이 생기면 먼저 가상 DOM에 적용한 후, 실제 DOM과 비교하여 최소한의 변경사항만 실제 DOM에 반영합니다. 이는 렌더링 성능을 개선합니다.

검색하며 더 알게된 것

Angular

검색하면서 React, Vue 그리고 Angular가 같이 언급되는 상황이 많았습니다. 우선 제게 가장 익숙한건 React 였고 Vue에 대해서도 꽤나 들어봤습니다. Angular는 듣긴 했지만 사실상 거의 듣지 못해서 그런게 있구나였기 때문에 이번 기회에 Angular에 대해서도 살짝 정리해보고자 합니다.

사실 공부할 때도 React와 Vue의 특징과 차이는 정리한 적 있어도 Angular는 아예 본적이 없는 것 같습니다. 이번에 검색하면서 어떠한 느낌인지 알게 되어서 좋았습니다.

가장 인상깊게 읽은 블로그의 내용에 따르면

장점

  • 뛰어난 개념과 구조: Angular는 컴포넌트, 디렉티브, 서비스, 파이프, 인터셉터 등 매우 잘 구조화된 개념들을 제공. 어떤 기능적 역할이나 파이프라인이 필요할 때, Angular는 개입할 수 있는 명확한 방법을 제시하며, 이는 다른 프레임워크에서는 찾기 어려운 장점이라고 강조.
  • 증분 DOM (Incremental DOM): React나 Vue와 달리 가상 DOM을 사용하지 않고 증분 DOM을 사용. 이는 템플릿을 명령으로 컴파일하여 동작하며, 특히 메모리와 컴퓨팅 파워가 낮은 모바일 환경에서 효율적이라는 점에서 긍정적으로 평가합. (가상 DOM은 전체 트리를 JS 객체로 표현하여 메모리 사용량이 많을 수 있음)
  • 양방향 통신 지원: 자식-부모 컴포넌트 간의 @Input과 @Output을 통한 양방향 데이터 통신을 지원.
  • RxJS를 통한 데이터 파이핑: RxJS와 모든 데이터 파이핑 구조를 사용하며, 이를 통해 많은 것을 배웠다고 언급.

Angular의 약점 (단점)

  • Zone.js를 통한 변경 감지 방식: React가 상태 변화를 통해 변경을 감지하는 것과 달리, Angular는 Zone.js를 사용하여 이벤트(eventListeners, setTimeout, setInterval, 소켓 등)를 추적하여 변경 감지(change detection)를 트리거. 작성자는 이 방식이 "좋은 구조와 개념에도 불구하고 뒤처질 수 있다"고 평가하며 -1점을 부여.

아래는 Angular 공식 페이지에서 소개한 내용을 정리해봤습니다.

Angular는 Google에서 개발하고 유지 관리하는 강력한 웹 프레임워크입니다. 빠르고 안정적인 애플리케이션 개발을 돕기 위해 다양한 도구와 API를 제공합니다.

주요 강점

  • 잘 짜여진 구조와 확장성:

    • 컴포넌트 기반: 코드를 재사용 가능한 작은 단위로 나누어 관리하기 쉽습니다.
    • 의존성 주입(DI): 코드를 모듈화하고 테스트하기 쉽게 만듭니다.
    • 다양한 개념: 컴포넌트, 디렉티브, 서비스, 파이프, 인터셉터 등 체계적인 개발 환경을 제공합니다.
  • 향상된 성능 및 반응성:

    • Signals 기반의 반응성: 세밀한 변경 감지로 빠른 상태 업데이트를 제공합니다.
    • 증분 DOM: 가상 DOM 대신 증분 DOM을 사용하여 메모리 사용량을 줄이고 모바일 환경에 유리합니다.
    • SSR/SSG 및 지연 로딩: 서버 사이드 렌더링, 정적 사이트 생성, 하이드레이션, 그리고 @defer 블록을 통한 코드 분할로 성능을 최적화합니다.
  • 개발 생산성 도구:

    • Angular CLI: 프로젝트 생성, 빌드, 테스트, 배포 과정을 간소화하여 개발 속도를 높입니다.
    • Angular DevTools: 브라우저 확장으로 컴포넌트 구조, 의존성, 성능 등을 시각적으로 디버깅하고 분석할 수 있습니다.
    • ng update: 자동화된 코드 변환으로 버전 업데이트를 쉽게 만들어 최신 버전을 유지하게 돕습니다.
    • IDE 통합: 코드 자동 완성, 리팩토링 등 개발 환경의 생산성을 높입니다.
  • 안정성과 확장성:

    • Google의 내부 검증: Google의 대규모 제품에 사용되며 수십만 개의 테스트를 통과하여 안정성이 검증되었습니다.
    • 예측 가능한 릴리스: 명확한 지원 정책과 LTS(장기 지원)를 통해 안정적인 개발을 보장합니다.
    • 보안: 기본적으로 HTML 새니티제이션 등 강력한 보안 기능을 내장하고 있습니다.
    • 대규모 팀 및 코드베이스 지원: Vite, ESBuild 통합으로 대규모 프로젝트의 빌드 속도를 개선합니다.
  • 활발한 오픈 소스 커뮤니티:

    • GitHub를 통해 투명하게 개발되며, 공개 로드맵과 RFC(Request for Comments)를 통해 커뮤니티의 피드백을 반영합니다.
    • 풍부한 학습 자료와 Google 개발자 전문가(GDE) 등 활발한 커뮤니티 지원을 받을 수 있습니다.
    • Chrome의 Aurora 팀과의 협력 등 다른 Google 기술과의 통합을 통해 웹 환경 개선에 기여합니다.

글을 마치며

선언형 프로그래밍과 명령형 프로그래밍 들어만 봤지 제대로 알아본 적은 처음인데 저렇게 나눠서 설명을 했지만 결론적으로는 무조건적으로 하나만 쓰일 순 없고 위키피디아에서는 몇몇 개발자는 이런 식으로 나누는 것 자체를 반대한다고 하더라고요. 제가 이해하기로는 지금 방향성이 가독성 유지보수가 용이한 선언형 방식을 지향, 선호한다는 것이고 그에 따른 변화 그리고 기존 JavaScript와 여러 기술이 발전하면서 프레임워크에도 자연스럽게 변화가 왔다고 이해했습니다.

저는 정말 React밖에 모르던 우물안 개구리더군요... 친구 회사 Vue 관련해서 작업 의뢰 왔었는데 한번도 사용해보지 않은 프레임워크라 시도해보지 않았는데 후회가 됩니다. React와는 다른 양방향 데이터 바인딩이라는 경험을 해볼 수 있었을 텐데 ...

글 작성하면서 그 생각이 가장 먼저 났습니다. 이제부터 경험 편식하지 않아야지 기회가 오면 무조건 잡아봐야겠다고 다짐하게 됩니다.

그리고 정말 프론트엔드 개발 동향은 정말 빠른 것 같아요. 제가 프론트엔드 개발에 입문하기 전에 이 모든 변화가 빠르게 일어났다는게 너무 놀랍습니다.

그럼 이만 줄이겠습니다.

참고 👀