프로젝트에서 jQuery 의 사용을 그만두겠다고 결심한 이유

Moon
Moon
Nov 3 · 11 min read
Photo by Stanley Dai on Unsplash

[번역] — Why I decided to Break up With jQuery

많은 사람들은 자신이 개발자라면 한 번쯤은 들어보거나 사용해봤을 법한 라이브러리인 jQuery 는 이미 너무나도 유명한 라이브러리다. 그러나 적어도 나한테는, 아니 좀 더 정확히는 2010년도 중반부터 웹을 공부하기 시작했던 나는, jQuery 는 정말이지 참신하고 새롭기 그지없었다. 그럼에도 불구하고 jQuery 의 사용을 이제는 그만둬야겠다는 생각이 들었던건 다음과 같은 이유에서였을 것이라고 생각한다.


읽기 전에 …
이 포스트는 이 글을 읽고 있는 다른 사람들이 jQuery 를 사용하지 말아야한다고 주장하는 글이 아니다. 아마도 누군가는 여전히 jQuery 를 프로젝트에서 열심히 사용하고 있을테다. 이 글이 설명하게 될 것들은 다른 라이브러리에서도 얼마든지 같은 잣대로 들이대 비판적인 입장을 취할 수 있음을 참고해줬으면 한다. 이 글은 어디까지나 개인적인 의견을 담은 글이다.


처음 jQuery 를 사용하게 된 계기부터 설명하자면

나는 컴퓨터 공학과였지만 커리큘럼의 거의 대부분이 C 언어에 집중되어 있는 과를 졸업했다. 포인터, 연결 리스트, 공용체, 뭐 기타 등등 … C 언어에는 생각만해도 머리가 아파오는 복잡한 내용들이 너무 많았다. 뭐 누구나 다들 한 번쯤은 입문자 때 그랬을 법 하듯이 나도 프로그래밍이라는 녀석한테 한동안은 조금 정이 떨어졌었다. 아마도 한 2년 좀 넘게 프로그래밍을 안 했었던 것 같으니까.

그런데 언제인지는 기억나지 않지만 언젠가 인터넷 좀 끄적거리다가 자바스크립트라는 것을 처음으로 접했다. 당연히 그 때는 자바스크립트가 뭔지도 몰랐고 내가 보고 있던 페이지는 jQuery 도 같이 소개가 되어있었던 것으로 기억한다. 그리고 사람들이 글에서 jQuery 가 더 쉽다고 했다. DOM 을 조작했을 때 결과를 화면에서 바로 볼 수 있었기도하고 무엇보다 사용하기가 엄청 간편했다.

// JavaScript
document.getElementById('myDiv')

이렇게 엄청나게 간단했다.

그래도 jQuery 가 어떤 다른 기능들을 갖고 있는지는 전혀 알지 못했다.

아마 animate, bind, fadeIn 같은 메소드 다 포함한다고 해도 내가 사용했었던 메소드는 10 개 남짓 할거다. 실제로 이 정도면 거의 document.getElementById 를 쓰기 싫어서 jQuery 썼다고해도 할 말이 없을 정도긴 하다. 그렇지만 최신 버전 (v.3.4.1) 기준으로 jQuery 는 무려 1만 줄이 넘는 라인을 갖고 있는 라이브러리다.

아마 여러분들은 내가 사용했던 것 보다는 더 많이 사용해봤을 수도 있다. 그래도 뭐 조금 건방지게 자신하자면 그래봤자 도합 30 개를 넘는 메소드를 사용하지는 않았을 거다. (아마도?) 혹시라도 어떤 메소드가 있었는지 기억이 나지 않으면 이 곳을 클릭하면 jQuery 에서 자주 쓰이는 메소드들을 확인할 수 있다.

모던 자바스크립트의 시대가 열린 후로는 정말 많은 개발자들이 jQuery 를 사용하고 싶지 않아한다. 그런데 왜 그런지는 혹시 생각해봤는지 묻고 싶다. 그저 사람들이 안 좋다고하니까 나도 덩달아서? 에이. 모든 것엔 다 이유가 있는 법. 적어도 나는 그 “왜" 라는 부분에 대해서 이렇게 생각한다.

첫 번째, jQuery 가 아무리 간편하다고해도, 대부분의 우리가 필요한 기능들에 비해 너무 크기가 비대하다.

jQuery 는 개발자들이 DOM 조작을 좀 더 편리하게 할 수 있도록 도와주는 기능들을 갖고 있다. 가장 대표적으로 선택자 $ 를 예로 들 수 있다. 그렇지만 라이브러리라는 것이, 기존 네이티브 코드나 무언가를 래핑(wrapping)해서 새롭게 만든 코드 패키지이다 보니, jQuery 역시 그런 것들의 묶음집인데, 문제는 이 래핑(wrapping) 을 너무 많이 해놨다. 심지어 엘리먼트 하나 가지고 오는데도 한 세월이다. (조금 과장해서)

예제를 한 번 보자.

다음과 같은 형태로 html 이 만들어져 있다고 가정한다. 보는 것과 같이 jQuery 는 CDN 으로 가져왔다.

이 예제들을 이해하는데엔 크게 어려움이 없을 것이라고 본다. 둘 다 p 태그를 10,000 개를 생성해 div 태그에 추가하는 코드다. 실제 프로젝트에선 이렇게 무식하게 태그를 다 때려박지는(?) 않을 테지만, 성능 비교를 위한 예제니까 적당히 넘어가주자.

jQuery 를 사용했을 때의 퍼포먼스
Vanilla 자바스크립트를 사용했을 때의 퍼포먼스

위의 두 스크린샷은 크롬 개발자도구에서 Performance Record 를 실행하고 난 후의 모습이다. 위의 스크린샷은 jQuery 를 사용했을 때, 밑의 스크린샷은 바닐라 자바스크립트를 사용했을 때의 모습이다. 뭔가 한 눈에 봐도 제법 다름을 알 수 있다.

여기서 눈여겨 볼 만한 것은 Evaluate Script 부분인데, jQuery 는 10,000 개의 태그를 추가하는데 걸린 총 시간이 1.13 초, 바닐라 자바스크립트는 0.013초(13.01ms) 가 걸렸음을 알 수 있다. 이는 바닐라 자바스크립트의 코드가 jQuery 의 코드보다 약 87 배 가량 더 빠르다는 뜻인데, 아니 결국 같은 자바스크립트 코드 베이스인데 이렇게 차이가 날 수가 있나?

아래는 왜 바닐라 자바스크립트가 더 빠를 수 밖에 없었는지에 대한 근거가 되어주는 스크린샷이다.

jQuery 의 콜 트리(Call tree)
바닐라 자바스크립트의 콜 트리(Call tree)

아까의 작업 실행 결과에 대한 콜 트리(Call tree) 기록이다. jQuery 의 결과가 위의 스크린샷인데, buildFragment 가 무려 약 1 초를 차지하고 있다. buildFragment 가 뭐냐면 jQuery 내부 코어 메소드인데 새로운 DOM 을 생성하고 프래그먼트 엘리먼트에 추가하는 작업을 수행한다. 반대로 밑의 스크린샷은 바닐라 자바스크립트의 수행 결과에 대한 콜 트리다. 상대적으로 상당히 깔끔하다.

// jQuery
... [Total Time] [Activity]
... 1041.4ms buildFragment --> slower!

퍼포먼스 탭에서 볼 수 있었던 것처럼, jQuery 는 단순하게 처리할 수 있는 작업임에도 불구하고 여러 코드들로 래핑이 되어 있어서, 실제 태그를 추가하는 작업을 수행하기까지 상당히 많은 과정들을 거치게 된다. 당연히 코드 실행 한 번 한 번은 리소스 자원을 필요로 하니까 그 만큼 아주 조금이라도 시간이 더 걸릴 수 밖에 없는 것이다.

여기서 당연히,

“내가 퍼블리싱 해보니까 jQuery 써도 속도 전혀 느려지지 않던데?”

라는 의문은 자제해주길 바란다. 몇 줄 안되는 코드는 당연히 그 차이가 매우 적을테고, 밀리 세컨드(ms) 를 육감으로 느낄 수 있는 동체시력을 가졌다면 날아오는 화살도 입으로 낚아챌 수 있을 거다.

두 번째, 한 가지 기능에만 집중적으로 개발된 라이브러리들이 많이 있다.

요즘 같이 npm 이 굉장히 활발한 시대엔 더 적은 용량으로 더 좋은 코드 베이스의 라이브러리들이 아주 즐비하다. 아래는 리액트 기반의 엘리먼트를 가져오는 코드다.

리액트에서 ref 를 사용하면, 리액트는 ref 가 가리키고 있는 DOM 을 ref tree 에 따로 저장을 해둬 기록하고 있다가 필요할 때 바로 사용할 수 있는 기능을 제공한다. 그런데 jQuery 는 우선 최초로 DOM 을 찾으려면 document 에서부터 쭉 타고 내려오면서 찾아야한다. 그러면 원하는 태그를 찾을 때까지 최상단 엘리먼트에서 트리 탐색을하며 내려오니까 더 많은 검색이 발생하는 셈이다.

만약에 리액트 훅이 좀 더 익숙하다면 아래의 코드로 참조하면 되겠다.

여기서 마찬가지로 한 가지 참고해줬으면 하는 점은, 리액트로 예를 들어 jQuery 와 비교했지만, 이는 단순히 내가 리액트에 익숙해서 그런 것일 뿐, 리액트가 jQuery 보다 항상 더 우수하다고 말하는 것이 아니다. 상황에 따라선 jQuery 가 훨씬 좋을 때도 있을 수 있다.

세 번째, jQuery 는 성능 최적화를 고려하고 만들어진 라이브러리가 아니다.

jQuery 는 2006 년도에 만들어진 나름 역사와 전통이 깊은, jQuery 가 마음 먹고 “니 위로 내 밑으로 다 집합 시켜” 라고 하면 몇 십만개는 우습게 집합시킬 수 있는 그런 오래된 라이브러리다. 자바스크립트가 수 많은 개발자들로부터 “그런 것도 언어야?” 와 같은 멸시와 통곡의 암흑 시대를 보낼 때도 jQuery 는 존재했었다.

그러나 웹은 시대가 변하는 속도를 훨씬 상회하듯이 엄청나게 빠른 성장을 이뤘고 지금은 프론트엔드, 백엔드 할 것 없이 기술 하나만으로 프로젝트의 관리를 하는 것은 거의 불가능하다. 그 만큼 웹은 현대화가 많이 진행 됐다.

그럼에도 불구하고, jQuery 는 아직 과거에 머무르고 있는 코드들이 많다. 수 많은 업데이트를 거쳤음에도 불구하고, 코드를 싹 갈아엎는 게 아닌 이상 업데이트의 한계점은 당연히 존재하는 법. 일부 코드에서 그런 흔적들을 몇 개 발견할 수 있었다.

애니메이션 메소드 실행 도중 불리는 메소드

scheduletick 이라는 애니메이션 관련 메소드를 실행하는 jQuery 의 코어 메소드이다. 코드를 잠깐 살펴보면, requestAnimationFrame 이 존재하는 경우 requestAnimationFrame 을 생성해 실행하는 부분이 보이고, 존재하지 않는다면 setTimeout 을 실행하고 있다.

setTimeout 과 달리 requestAnimationFrame 은 그 동작 방식이 살짝 다르다. requestAnimationFrame 을 사용한다는 것은 cancelAnimationFrame 역시 사용해야 함을 의미하는데 jQuery 코드엔 그 부분이 존재하지 않는다.

requestAnimationFramesetTimeout 에 대한 포스팅은 이 곳에서 좀 더 자세히 다루고 있다.

또 하나 예를 들어보겠다(사실 겨우 찾았다). 역시나 jQuery 가 갖고 있는 코어 메소드인데 특정 엘리먼트의 top 이나 left 에 대한 값을 호출할 때 실행된다. 이상한 점을 혹시 찾았는가?

elem.getBoundingClientRect().left

이 부분이 반복되고 있다. 충분히 변수로 빼서 재사용할 수 있을텐데 말이다. 코드의 내용을 몰라도 이 부분만 봐서는 확실히 리팩토링이 필요해보이긴 한다. 이게 왜 짚고 넘어갈만 하냐면, getBoundingClientRectreflow 를 강제하는 메소드 중 하나다. 만약 그렇다면, 불필요하게 두 번씩이나 호출할 필요가 전혀 없는 셈이다. 다시 한 번 강조하자면 jQuery 는 만들어질 때 이런 것들을 고려하고 만들어진 라이브러리가 아니다. 그래서 성능면에서 아쉬울 수 밖에 없는 게 당연한 셈이다.

물론, PR 을 보내 코드 수정을 할 수도 있지만 그 것은 귀ㅊ, 아니 무언가 jQuery 제작자들의 숨겨진 의도가 있을 것으로 생각하기로 하자.

reflow 를 강제하는 요소들은 이 말고도 매우 많은데, 이 곳에서 목록을 확인할 수 있다.

정리하자면

jQuery 를 처음 접했을 땐 신세계를 경험했다. 쉽고 너무나도 직관적이었으니까. 그러나 시간은 흘러 많은 것들이 변했고, 웹의 시대 또한 새로운 국면을 맞이했다. jQuery 는 이런 시대의 흐름을 타지 못한 것 뿐이다.

그러나 jQuery 가 사장되어야 한다고 주장하는 것은 절대 아니다. 아직도 많은 퍼블리셔나 개발자들은 일부 프로젝트에서 jQuery 를 활발하게 사용하고 있고, 사실 개발 생산성 면에선 훌륭하다고 할 수 있다. 그럼에도 불구하고지만, 프로젝트에서 jQuery 의 사용을 검토하고 있다면 조금 더 면밀히 검토해볼 필요는 있을 것이다.

참고

오늘의 프로그래밍

프로그래밍 지식을 공유하는 공간입니다

Moon

Written by

Moon

Front End Web Developer in S.Korea. Interested in writing about Programmings. All of the posts could be written in English and Korean, which is my mother tongue

오늘의 프로그래밍

프로그래밍 지식을 공유하는 공간입니다

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade