[JS]Document.ready 의 대안

jQuery를 사용할 때, DOM이 로드된 후 처리를 위해 아래와 같은 구문을 많이 사용해왔습니다.

1
2
3
4
5
6
7
8
9
$(function(){

});

// or

$(document).ready(function(){

});

이와 같은 동작을 jQuery 없이 사용 할 수 없을까 찾아 보았는데,

1
2
3
document.addEventListener('DOMContentLoaded', () => {

})

위와 같이 작성하면 됩니다.

DOMContentLoaded는 최초로 HTML 문서가 완전히 로드 및 파싱 되었을때 발생되므로,

모든 리소스(이미지, 스크립트, 스타일 시트 등)가 로드 된 후 발생하는 load 이벤트 보다는 먼저 호출됩니다.

그렇다면 왜 DOMContentLoaded 이벤트 리스너 대신 $(document).ready()를 사용했을까 알아 보았는데,

CAN-I-USE-DOMContentLoaded를 확인하였더니, IE8까지는 지원을 하지 않았습니다.

물론 jQuery가 아닌 대안들도 있었겠지만, 브라우저 호환성을 위해 jQuery를 써오던 입장에서는 간단하게 사용할 수 있던 방안이었으리라고 봅니다.

참고자료

[JS]jQuery 두번째 파라미터가 뭐지?

jQuery로 작성된 코드를 보는데, $("selectorA", "selectorB") 와 같은 코드가 있었습니다.

당연히 기존에 자주 접하던 $("selectorA, selectorB") 와 같은 코드인줄 알았으나, 예상과 다르게 동작하여 문서를 확인해 보았습니다.

jQuery 문서에 따르면, A DOM Element, Document, or jQuery to use as context 가 기재되어있다.

해당 영역에는 DOM element가 올 수 있는데 Selector Context를 확인해보면

selector context is implemented with the .find() method, so $( “span”, this ) is equivalent to $( this ).find( “span” ).

이와 같이 말하고 있습니다.

jQuery .find() vs. context selector 해당 링크에서 퍼포먼스 확인을 해보면
아래 이미지와 같이 context selector를 사용 하는 것 보다, 아주 조금이나마 더 빠릅니다.

[JS]Object literal 보다 JSON.parse()가 더 빠르다

서론


웹에서 몇 kb 크기의 객체를 초기에 렌더링 하는것은 생각보다 많습니다.

이 javascript 객체가 로드될때까지 클라이언트는 빈 화면을 보게 될 수 있습니다.

이러한 문제를 해결하기 위해, 서버사이드 렌더링을 활용 하는 방법도 있겠지만
다른 방법은 없을까요?

Chrome Dev Summit에서는 객체를 JSON으로 직렬화 하고, 문자열 리터럴로 변환해 Javscript 객체에 전달하는 것이 성능 향상에 도움이 된다고 이야기합니다.

무슨 소리일까?


아래의 두 코드는 동일한 객체를 생성하지만,
Javascript 엔진의 경우, JSON 예제를 스캔하고, 파싱만 하기 때문에 빠르다고합니다.

Javascript 파서에게 해당 코드는 여러개의 객체 리터럴을 받는 코드이냐, 많은 양의 데이터가 담긴 문자열 단일 리터럴이냐로 구분됩니다.

해당 예제에서의 객체의 값은 숫자이지만, 자기 자신의 속성과 값을 가진 Object 또는 배열이거나, 더 많은 값을 가진 무엇이든 될 수 있기 때문입니다.

이렇기 때문에 자바스크립트 파서는 단지 올바르게 토큰화 하기위해 JSON.parse에 비해 더 많이 동작 해야 합니다.

또 다른 이유로는 자바스크립트 객체 리터럴은 그 값이 객체문자열이라는것을 미리 알지 못하기때문입니다.

JSON.parse로 파싱할때에는 간단하게 중괄호 이후에 Object로 시작할지, 아니면 잘못된 JSON 형식인지라는 두가지 옵션에만 중점을 둡니다.

반면 객체 리터럴은 위의 이미지와 같이 Javscript Object는 중괄호 뒤의 값이 무엇인지를 아직까지는 알 수 없고

이렇게 되었을때는 첫번째 라인에 선언된 x의 값을 바인딩 한 객체 리터럴을 생성하는것을 알 수 있다.

하지만 이와 같이 선언 되었을 경우 두번째 라인의 코드에서 첫번째 라인의 x는 전혀 참조되지않습니다.

이와 같이, 이러한 문맥 의존 문법으로 인해, Javascript 엔진에서의 파싱이 까다롭습니다.

문자열을 JSON 파싱하는것은 이러한 문제가 없어, 구문 분석이 훨씬 간단해져서 빠를 수 있는것 입니다.

실제로 얼마나 빠른건데?


캐시가 없는 콜드로드 상태에서 8MB에 가까운 페이로드를 기준으로 파싱하였을때,
v8과 크롬에서 JSON.parse()가 1.7배정도 빠르다고 한다.

이는 다른 자바스크립트 엔진이나 브라우저에서도 적용된다고한다.

리덕스앱에 이와 같은 적용을 한 사례에서는 Time To Interactive(TTI)가 18% 개선되었고, Lighthouse 성능 점수가 8포인트 증가하였습니다.

이러한 작업을 직접 수동으로 하는것 대신 툴을 이용하는것을 추천합니다.
코드 베이스에 JSON 모듈을 사용할 경우, webpack에서는 JSON.parse()기능을 이미 적용 시켰습니다.

다른 코드들은 babel 플러그인를 이용해 변환 할 수 있습니다.

맺음말


페이스북 페이지에서

Faster apps with JSON.parse

해당 문구를 보자마자

“엥?? JSON.parse()는 느리지 않나??” 라는 생각만을 가지고 관심을 가지며 영상을 보면서 정리한 내용이라 제가 잘못 이해한 부분이 있을 수 있습니다.

잘못된 부분이 있으면 코멘트 부탁 드리겠습니다.

출처


Faster apps with JSON.parse (Chrome Dev Summit 2019)

[JS]jQuery 없이 Selectbox에서 여러개 선택된 option의 값 추출하기

DOM을 다룰때 jQuery를 사용하면 매우 편리합니다.

물론 크로스 브라우저 이슈로도 제이쿼리를 많이 사용합니다.

하지만 DOM을 핸들링하기 위해서만 jQuery를 쓴다면, 편리함은 챙기겠지만 낭비 아닐까싶습니다.

저는 위와 같은 생각으로,

주로 DOM 핸들링에는 jQuery 의존성을 줄이고자 순수 자바스크립트를 사용하려 노력하고 있습니다.

또한, document.querySelectordocument.querySelectorAll 를 이용한다면,

jQuery에서 사용하던 복잡한 DOM Selector도 쉽게 사용할 수 있습니다.

1
2
3
4
5
6
<select id="user" name="user[]" multiple="multiple">
<option>선택option>
<option value="foo">Foooption>
<option value="bar">Baroption>
<option value="baz">Bazoption>
select>

위와 같은 Multiple SelectBox에서 여러개가 선택되었을 경우 값을 어떻게 가져올까요?

jQuery를 사용하면 $("#user").val()으로 짧고 간결하게 가져올 수 있습니다.

선택된 값이 없을 경우 null이 리턴되고, 선택된 값이 있으면 배열 안에 value 값이 담깁니다.

그렇다면 순수 자바스크립트로는 어떻게 표현할까요?

1
2
3
Array.from(document.querySelector("#user").selectedOptions, (item)=> {
return item.value;
});

document.querySelector("#user").selectedOptions를 사용하면 ID 값이 user인 DOM을 찾아 selected 된 옵션을 리턴하여줍니다.

해당 값에서 value 값만 뽑고싶다면 위와 같이 처리할 수 있습니다.

위와 같이 처리하면 jQuery를 사용할때와 다른점은 선택된 옵션이 없을 경우에는 []를 리턴하여 줍니다.

[JS]Knex와 Webpack을 같이 쓰면서 발생한 오류 처리

1
2
ERROR in './node_modules/knex/lib/dialects/mssql/index.js'
Module not found: Error : Can't resolve 'mssql/lib/base'

프로젝트에 웹팩을 도입하여 사용중, knex 라이브러리를 넣고 나서

웹팩으로 빌드시 해당 에러가 나와서 빌드에 실패 했습니다.

[VueJS]vue.js에서 이벤트 버스 사용하기

MPA(Multi Page Application)에서 Vue를 적용 시키던중

부모-자식간의 관계가 아닌 컴포넌트 간의 동작에 따른 데이터 변화와 이벤트 처리가 필요해졌습니다.

[JS] ES5와 ES6 뭐가 다를까?

ES5와 ES6를 비교 할겸
ES6를 사용할때 자주 쓰이는 부분만 정리해보았습니다.

[Node.js]Express.js로 NodeJS 시작하기

express 제너레이터 설치

1
npm install express-generator

ejs 템플릿을 이용하여 myapp 디렉토리에 생성

1
express myapp --view=ejs

myapp 디렉토리로 이동하여 npm install(패키지 설치)

1
$ cd myapp & npm install

서버 실행

1
$ npm start

POST전송시 필요한 body-parser와 express-session 설치

1
$ npm install body-parser express-session

기존에는 NodeJS에서 POST 요청 데이터를 추출 할 수 있도록 하기 위하여 bodyParser를 설치해야 했는데 express-generator에 추가 되었다

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×