발전한 자바스크립트와 현재 jQuery의 위치
이틀 전에 '제이쿼리는 왜 FD 로드맵에서 삭제 되었을까?'라는 글을 재밌게 읽었습니다. 문득 jQuery의 흔적을 자주 볼 수 있는 인트라넷에 이 글과 제가 개발 공부를 하면서 느낀 JavaScript와 jQuery에 관해서 쓰면 좋을 거 같아서 남겨봅니다.
주의
- 부족한 경험과 기억에 의존해서 적는 글이라 틀린 부분이 있을 수 있습니다.
- 오류나 틀린 부분이 있다면 지적 부탁드립니다!
jQuery가 개발되기 전의 웹
초창기(1995~1996) 웹 브라우저
jQuery가 개발되기 전의 JavaScript는 브라우저 제조사 별로 표준이 달라서 같은 JavaScript 코드라도 어떤 브라우저에서는 동작하지만 어떤 브라우저에서는 안 돌아가는 경우가 많았습니다. 그래서 개발자에게 JavaScript는 손이 여러모로 가는 정말 골치 아픈 언어였습니다. 특히, 마이크로소프트는 독자적인 노선을 달렸는데 당시 유행하던 브라우저(Netscape)를 뜯어서 분석한 뒤(리버싱) 다시 구현해서 만들어낸 파생 버전인 JScript를 Internet Explorer(3.0)에 내장시켰습니다. 결국, 개발자는 같은 JavaScript라도 브라우저별로 다른 표준을 가졌기 때문에 개발할 때 모든 브라우저에서 동작하도록 대응해주는 귀찮고 짜증이 나는 작업을 해야 했습니다. 이렇게 모든 브라우저에 대응해주는 것을 크로스 브라우징이라고 합니다.
jQuery의 등장
이때 존 레식이라는 분이 크로스 브라우징을 신경 쓰지 않고 개발에만 집중할 수 있도록 해주는 jQuery라는 라이브러리를 개발했습니다.
라이브러리(Library)? 번역하면 도서관입니다. 코드 모음집을 도서관처럼 찾아 쓸 수 있게 자주 사용하는 JavaScript 코드나 함수를 미리 이쁘게 정돈해서 만든 것입니다.
jQuery를 사용하면 jQuery가 알아서 내부적으로 브라우저별로 대응해줍니다. 개발자들은 jQuery의 API만 사용하면 크로스 브라우징을 신경 쓰지 않고 신나게(?) 효율적으로 개발만 할 수 있게 됐습니다. 게다가 당시 순수한 JavaScript로만 짠 코드보다 jQuery의 API를 사용해서 짠 코드가 더 간결하고 직관적이었습니다. 마지막으로 무료(오픈소스)였기 때문에 인기가 폭발했습니다.
- 장점 1. 크로스 브라우징
- 장점 2. 간결하고 직관적인 문법
이러한 장점들 덕분에 거의 'JavaScript' = 'jQuery'라는 공식이 나올 정도로 인기를 끌게 됩니다.
API(Application Programming Interface)?
간단히 설명하자면 여러 기능을 구현해주고 그 기능들을 사용하는 방법에 관한 표준을 만들어서 제공해주는 것을 말합니다. 개발자들은 어떤 API의 표준에 맞춰서 사용함으로써 내부의 구현을 신경 쓰지 않고 편리하게 API기 제공해주는 기능을 사용합니다.
ex) 마우스로 비유하자면, 마우스에서 제공하는 API는 우클릭, 좌클릭, 마우스 휠 스크롤, 마우스 휠 클릭이라고 할 수 있습니다. 그리고 마우스 API 사용자들은 그 API를 씀으로써 어떻게 우클릭과 같은 게 내부적으로 일어나는지 신경 쓰지 않고 편리하게 추상화된 기능을 사용할 수 있습니다.
웹의 변화
현대의 웹이 어떻게 편했는지 이해를 하려면 먼저 DOM(Document Object Model)에 관해서 알아야 합니다.
DOM API란?
먼저 DOM에 관해서 간단하게 설명하고 넘어가겠습니다.
웹 사이트는 보통 HTML, CSS, JavaScript로 이루어져 있다고 합니다. HTML과 JavaScript만 따로 떼서 생각해봅시다.
마크업 언어인 HTML 문서와 프로그래밍 언어인 JavaScript 코드는 전혀 다릅니다. HTML은 여러 의미의 태그로 구성된 구조적인 문서이고 JavaScript는 프로그래밍 언어입니다. 이 둘은 전혀 호환 안 될 것 같지만 JavaScript로 전혀 관계없는 HTML 문서의 특정 부분(예를 들어서, 버튼)을 클릭하거나 드래그했을 때 새 페이지로 이동하거나 창을 닫는 등 여러 가지 상호작용을 하도록 만들 수 있습니다.
어떻게 JavaScript로 HTML 문서의 특정 요소에 접근해서 그것을 조작할 수 있고 어떻게 JavaScript로 HTML 문서 일부분에 이벤트를 걸고 원할 때 이벤트를 발생시키게 할 수 있을까요?
이것은 브라우저가 DOM API를 제공하기 때문에 가능한 일입니다. 브라우저는 HTML의 문서를 파싱해서 DOM으로 만들고 DOM Selector API를 통해 HTML 문서의 특정 부분(DOM)을 선택하고 이벤트를 걸 수 있게 합니다. JavaScript를 사용해서 HTML로 된 UI를 이리저리 조작해보셨다면 익숙하실 겁니다.
한번 카운터를 예로 들어보겠습니다.
HTML 문서는 아래와 같이 되어 있다고 합시다.
<h1 id='counter'>0</h1>
<button id='plus'>+</button>
<button id='minus'>-</button>
JavaScript로 부여된 id를 이용해서 각각의 DOM을 선택한 뒤에 원하는 이벤트(여기서는 버튼 클릭)가 일어났을 때 DOM을 알맞게 업데이트시키게 해봅시다.
const counter = document.getElementById('counter');
const plus = document.getElementById('plus');
const minus = document.getElementById('minus');
plus.onclick = () => {
counter.innerText = parseInt(counter.innerText, 10) + 1;
}
minus.onclick = () => {
counter.innerText = parseInt(counter.innerText, 10) - 1;
}
id가 counter인 DOM에 +버튼이 눌리는 이벤트가 발생하면 1을 더해주고 -버튼이 눌리는 이벤트가 발생하면 1을 빼주라고 짰습니다.
감이 오시나요?
본론으로
이제 본론으로 돌아와서 jQuery가 유행한 이후인 현대의 웹 페이지는 어떤지, 복잡해지는 웹 페이지를 해결하기 위해 어떤 기술이 발달했는지 알아봅시다.
새로운 라이브러리와 프레임워크의 등장
사용자와 상호작용이 별로 없는 웹사이트를 만든다면 상관이 없겠지만 요즘 기업에서 만드는 사이트를 보시면 상호작용도 많고 갱신되는 UI도 많고 애니메이션도 다양한 사이트가 많습니다. 그리고 스마트폰이 보급되면서 여러 가지 해상도에 따른 반응형 웹앱도 유행합니다. 그리고 우리는 아니지만, 누구나 스마트폰을 들고 다니며 자주 웹 사이트를 접속할 수 있게 되었기 때문에 여러 콘텐츠가 추가로 개발되고 있습니다.
인스타그램과 같은 사이트를 생각해보면 계속해서 새로운 데이터가 들어옵니다. 시간이 지나면서 자체적인 기능이 업데이트되고 많은 이벤트도 추가가 됩니다. 이에 따라 사이트에 많은 DOM 업데이트가 필요하게 됐고 그에 따른 이벤트 핸들러도 엄청 많이 필요하게 됩니다. 이렇게 관리해야 할 상태(값)들도 늘어나고 DOM도 엄청 많아지면 저와 같은 초보 개발자는 순수하게 JavaScript로 짠다면 코드도 난잡해지고 이벤트 발생에 따라서 DOM을 업데이트하는 순서도 제대로 못 정해서 웹 애플리케이션이 엄청 복잡해지고 느려지며 유지보수를 하기 어렵게 될 겁니다. 특히, 여러 이벤트가 많아지면서 웹이 복잡해지면 "DOM을 어떻게 업데이트를 할 것인가"에 대한 고민을 할 수밖에 없습니다. 이런 것들을 해결하기 위해 Ember, Backbone, AngularJS와 같은 프레임워크가 등장합니다. 이런 프레임워크들은 어떤 상태가 바뀌면 원하는 DOM에 연결해줘서 DOM을 업데이트하는 작업을 간소화하는 것에 집중했습니다.
그리고 페이스북이 만든 전혀 다른 방식의 라이브러리도 등장합니다.
이벤트가 많고 복잡한 것으로는 페이스북이 최고입니다. 여러 피드가 갱신되면서 데이터가 실시간으로 들어오는 페이스북에 얼마나 많은 데이터와 이벤트가 필요할지 상상해봅시다. 좋아요를 누르면 좋아요 아이콘이 색칠되게끔 DOM이 업데이트돼야 하고 글을 새로 게시해도 새로 뜨게끔 DOM이 업데이트돼야 하고 메신저도 수신하면 창도 뜨고 알림을 위한 DOM도 업데이트돼야 하고 거기에 스토리 기능도 있고 등 계속 나열할 수 있을 것 같습니다. 엄청 많은 데이터가 실시간으로 오가고 많은 DOM이 업데이트돼야 하는 복잡한 사이트를 효율적으로 만들기 위해 페이스북은 React를 만들어냅니다.
React는 기존의 프레임워크들과 달리 '어떤 상태가 바뀌었을 때, 그 상태에 따라 DOM을 어떻게 업데이트할지 규칙을 정하는 것이 아니라 그냥 싹 다 날려버리고 처음부터 모든 것을 새로 만들어서 보여준다면 어떨까?'라는 아이디어에서 출발했습니다. 하지만 실제로 기껏 만들어놓은 DOM을 갈아엎고 웹 페이지를 새로 그리면 상당히 비효율적일 겁니다. 이 문제는 메모리에만 존재하는 가상의 Virtual DOM이라는 JavaScript 오브젝트를 사용해서 해결했습니다. Virtual DOM은 실제로 사용자들에게 보이지 않고 메모리 상에 존재하므로 성능이 상당히 빠릅니다. React는 어떤 상태가 업데이트되면 업데이트가 필요한 곳의 UI를 Virtual DOM을 통해서 실제 브라우저에 보이는 DOM과 아주 빠른 속도로 비교합니다. 그리고 실제 DOM에 차이가 있는 곳에만 Patch를 하는 방식으로 동작합니다.
- 장점 1. 웹이 커질수록 골치 아파지는 DOM 업데이트를 어떻게 해야 할지에 대한 고민을 하지 않아도 된다.
- 장점 2. 빠른 성능.
이렇게 SPA(Single Page Application)의 많은 문제를 해결한 React가 유행하게 됩니다.
JavaScript의 표준화
웹에 무수히 많은 변화가 일어나면서 JavaScript도 같이 성장하고 사용하는 환경도 개선됩니다.
1996년에 웹 브라우저 최강자인 Netscape Communications라는 회사가 ECMA라는 표준화 기관에 맡겨서 1997년 7월에 ECMAScript1(ECMA-262) Specification을 완성했습니다. 하지만 당시의 브라우저 업체들은 이 표준을 잘 지키지 않았습니다. 현재는 다행히도 예전의 브라우저별로 표준이 달랐던 악몽에서 벗어났습니다. 대표적인 브라우저는 모두 ECMAScript라는 표준을 잘 지키고 있습니다.
현재의 JavaScript는 TC39 위원회가 관리하고 TC39 위원회가 명시한 것들을 ECMA에 맡겨서 표준화하고 있습니다. 그리고 2016년부터는 표준화한 언어를 그것을 검토한 연도를 뒤에 합쳐서 부릅니다. 예를 들어서, ECMA에서 표준을 검토한 날짜가 2019년이면 ECMAScript2019(또는 줄여서, ES2019)라고 부릅니다.
이렇게 표준화한 JavaScript는 상표권 문제로 JavaScript라고 부르지 못하고 ECMAScript라고 공식적으로 부릅니다. 잘 기억은 안 나지만 자바를 개발한 오라클 사에서 JavaScript라는 상표권을 가지고 있었다고 얼핏 들은 것 같은데 확실하진 않습니다.
현재의 거의 모든 브라우저(또는 Node.js)에서 실행되는 JavaScript는 ECMAScript를 구현한 것입니다. 그래서 이제는 같은 JavaScript인데 브라우저마다 가진 다른 표준에 대비해서 코딩하면 고통받을 필요가 없어졌습니다. (군대와 같은 망이 사회와 분리된 특수한 환경을 제외하고는) jQuery의 필요성도 점점 없어져 갑니다.
그리고 브라우저들이 표준을 지켜주면서 JavaScript에서 보장해주는 하위 호환성도 지켜집니다.
하위 호환성이 보장된다면?
어떤 것이 언어의 유효한 것으로 받아들여지면 언어의 유효한 것으로 받아진 것을 붕괴시킬만한 업데이트를 하지 않는다.
상위 호환성이 보장된다면?
언어의 새로운 기능으로 구현한 프로그램을 구버전 자바스크립트 엔진에서 돌렸을 때 오류가 나서 멈추지 않는다.
JavaScript는 하위 호환성을 보장합니다. 그러므로 (표준이 잘 지켜졌다는 가정 하에) 제가 태어났을 때쯤에 짠 코드도 현재 웹 브라우저에서 잘 실행할 수 있습니다. 이러한 특성은 '우리가 짠 코드가 나중에 브라우저 업데이트로 안 돌아가면 어떡하지'라는 걱정을 할 필요 없이 편안하게 코딩을 할 수 있게 해줍니다.
반대로 장점만 있는 것은 아닙니다. 하위 호환성을 보장한다는 말은 향후 JavaScript를 바꾸는 모든 변경점들이 JavaScript에 영구적으로 적용된다는 것입니다. 이것은 큰 부담이 됩니다. JavaScript에 이상한 것을 표준으로 넣어버리면 수정할 수가 없으므로 평생 치명적인 문제를 남기기 때문입니다.
거의 없지만 하위 호환성을 위반하는 변화를 적용한 작은 예외가 있다고 합니다. TC39 위원회에서 기존 웹에 있는 코드를 조사하고 문제를 해결하여 얻을 이득과 망가질 코드들에 의한 손해를 저울질해서 아주 조심히 적용했다고 합니다.
참고로 JavaScript는 상위 호환성을 보장하지 않습니다. 새로 업데이트된 최신 ES2019 문법을 구버전 자바스크립트 엔진을 사용하는 예전 브라우저에서 실행하면 높은 확률로 오류가 납니다. 반대로 HTML과 CSS는 상위 호환성을 보장합니다.
인기가 떨어진 jQuery
이런 말을 하는 게 슬프지만, jQuery가 JavaScript를 대신하지 않는다. jQuery가 성공한 것은 DOM이 문제가 많다는 증거일 뿐이다.
존 레식, jQuery의 개발자
jQuery VS JavaScript
jQuery의 장점 1. 크로스 브라우징
jQuery가 크로스 브라우징을 지원한다는 말은 그만큼 무겁다는 말입니다. 그저 표준대로 jQuery API를 사용하는 입장에서는 알아차리기 어렵지만 여러 브라우저에 대응해서 jQuery의 내부적으로 엄청 많은 명령어가 돌아가고 있습니다. 과거에는 크로스 브라우징 작업을 해야 했기 때문에 jQuery를 쓰는 게 더 편했지만, 앞에서 언급했듯이 요즘의 브라우저는 ECMAScript라는 표준을 따르고 있어서 필요성이 많이 줄어들었습니다.
성능이 엄청 복잡합 웹이 아니고서야 체감할 정도는 아니라고 할 수도 있습니다. 하지만 부족한 부분만 구현한 가벼운 라이브러리를 쓰면 되지 쓰이지 않을 크로스 브라우징 기능과 다른 것들이 들어 있는 jQuery를 사용해서 굳이 메모리 낭비를 할 필요가 없기도 합니다.
jQuery의 장점 2. 간결하고 직관적인 문법
jQuery의 또 다른 장점으로는 JavaScript의 DOM API를 추상화해서 코드를 더 간결하고 직관적으로 만들어 준다는 점입니다.
눈으로 확인하기 좋게 몇 가지 예제를 작성해봤습니다.
DOM 선택
<div id='root'></div>
다음과 같은 DOM을 id로 접근해봅시다.
JavaScript
document.getElementById('root'); // 또는 document.querySelector('#root');
jQuery
$('#root')
Event 처리
JavaScript
document.addEventListener('DOMContentLoaded', () => {/*DOM 객체가 생성이 완료되면...*/});
jQuery
$ready(() => {/*DOM 객체가 생성이 완료되면...*/});
특정 DOM에 대한 클릭 이벤트
JavaScript
document.getElementById('root').addEventListener('click', (event) => {/*클릭하면 발생할 event...*/});
jQuery
$('#root').on('click', (event) => {/*클릭하면 발생할 event...*/});
비동기 Request 보내기
Javascript
const req = new XMLHttprtequest();
req.open('GET', '/path', true);
req.onreadystatechange = () => {
if (req.readyState === 4) {
if (req.status === 200) success();
else fail();
}
}
jQuery
$.ajax('/path').then(success, fail);
확실히 jQuery가 더 간결합니다. 하지만 요즘은 이러한 간결함은 다른 라이브러리에서도 찾을 수 있습니다. 기술적인 제약이 있는 것이 아니라면 굳이 다 활용하지 않는 무거운 jQuery를 사용할 것이 아니라 필요한 부분만 있는 라이브러리만 선택해서 사용하는 게 맞다고 생각합니다.
예를 들어서, 요즘은 HTTP Request를 보낼 때, 많은 기능이 있어서 무거운 jQuery를 쓰기보다 필요한 통신 부분만 있는 Request나 Axios 같은 가벼운 라이브러리를 써서 호환성과 편리함을 챙깁니다.
Axios로 마지막 예제와 동일한 Request를 보낸다면 아래와 같이 쓸 수 있습니다.
axios.get('/path').then(success).catch(fail);
jQuery 못지않게 간결하고 직관적입니다.
jQuery는 너무 사용하기 쉬웠습니다. 그만큼 내부 동작이 많이 추상화되어 있습니다. 그렇기 때문에 내부 동작을 신경 쓰지 않고 사용될 가능성이 큽니다. 쉬운 문법에 의존해서 jQuery의 API를 원래의 의도와 다르게 사용한다면 가볍게 구현 가능한 것을 오히려 불필요하게 낭비할 수도 있습니다.
결론
모던 웹은 많은 데이터를 효율적으로 처리하고 컴포넌트를 이용한 재사용성으로 인한 유지보수성의 증대를 추구한다고 합니다. 이런 트렌드에 따라서 SPA가 주축인 Frontend 생태계에서 jQuery가 부합하지 못하게 되었고 18년도에 로드맵에서 삭제가 되었다고 합니다. 하지만 클라이언트가 구버전 IE에서 호환되길 바라거나 무리한 일정 속에서 jQuery로 된 레거시 코드를 작업하는 상황이라면 오히려 사용하는 게 좋을 것입니다.
라이브러리나 프레임워크는 도구입니다. 저도 개발하면서 내가 좋아하고 익숙한 도구를 쓸 수 있으면 좋겠지만 팀의 기술 스택이나 클라이언트의 요구 등에 의해 바뀌는 상황에 맞게 판단해서 수용할 수 있어야 한다고 생각합니다.
그리고 라이브러리나 프레임워크는 지속해서 업데이트되거나 트렌드에 따라서 다른 것으로 대체되지만 JavaScript는 바뀌지 않습니다. ECMAScript2015 이후로 JavaScript에도 많은 발전이 있었기 때문에 JavaScript 자체로도 충분히 강력해졌습니다. 요즘 유행하는 TypeScript를 쓰려고 해도 모던 JavaScript에 관한 이해가 필요합니다. 상황과 여건이 된다면 모던 JavaScript를 쓰는 게 개발하는 데 있어서 좋은 연습이 될 것 같습니다. 다른 전우님들은 어떻게 생각하시는지 궁금합니다!
긴 글 읽어 주셔서 감사합니다.
정정
초창기 웹에 관해서 설명할 때 자연스러운 설명을 위해 정확하지 않은 이름으로 설명한 부분이 있습니다. 1996년 12월 전까지는 현재 JavaScript로 알려진 언어는 "JavaScript"라는 이름이 붙기 전이였습니다. Netscape Communications에서 내부적으로 1996년 3월에는 "Mocha", 몇 개월 뒤에는 "LiveScript"로 이름이 변경했습니다. 최종적으로 밖으로 공개할 때는 당시 인기가 많았던 Java의 사용자들을 끌어들이기 위해서 '가벼운 자바'라는 느낌을 주기 위해 우리가 아는 "JavaScript"라는 이름으로 공개되었습니다. 계속 바뀌는 이름으로 인한 혼동을 방지하기 위해 "JavaScript"라는 이름이 붙기 전인데 그냥 "JavaScript"라고 통일해서 말했습니다.
출처
- velog에 sik2님이 작성하신 "제이쿼리는 왜 FD 로드맵에서 삭제 되었을까" 글을 재구성했습니다.
- 여러 용어에 관한 설명과 부연 설명을 추가하고 JavaScript의 역사와 표준화, 호환성, 카운터 예제, 프레임워크와 라이브러리에 관한 내용을 추가했습니다.
- Js file icons created by Flat Icons - Flaticon
댓글
이 글 공유하기
다른 글
-
모던 JavaScript 튜토리얼 파트 1 :: 6장 "함수 심화학습" 정리
모던 JavaScript 튜토리얼 파트 1 :: 6장 "함수 심화학습" 정리
2023.01.16 -
모던 JavaScript 튜토리얼 파트 1 :: 5장 "자료구조와 자료형" 정리
모던 JavaScript 튜토리얼 파트 1 :: 5장 "자료구조와 자료형" 정리
2023.01.09 -
모던 JavaScript 튜토리얼 파트 1 :: 3장 "코드 품질", 4장 "객체:기본" 정리
모던 JavaScript 튜토리얼 파트 1 :: 3장 "코드 품질", 4장 "객체:기본" 정리
2023.01.02 -
모던 JavaScript 튜토리얼 파트 1 :: 1장, 2장 정리
모던 JavaScript 튜토리얼 파트 1 :: 1장, 2장 정리
2022.12.26