상위 스코프의 변수 참조에 있어서의 성능에 대해 알아보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <html> <body> <div id="divMouseover">Mouse over Highlight</div> <div id="divFloatingContent">Floating Content</div> <script> (function () { var divMouseover = document.getElementById("divMouseover"), divFloatingContent = document.getElementById("divFloatingContent"); divMouseover.onmouseover = function () { var xhr = new XMLHttpRequest(); divMouseover.style.backgroundColor = "#FF0000"; divMouseover.style.color = "white"; divMouseover.style.fontSize = "12px"; xhr.open("GET", "http://[server]"); xhr.onload = function () { divFloatingContent.innerHTML = xhr.responseText; divFloatingContent.style.display = "block"; }; xhr.send(); }; divMouseover.onmouseout = function () { divMouseover.style.backgroundColor = "#FFFFFF"; divMouseover.style.color = "black"; divMouseover.style.fontSize = "10px"; divFloatingContent.style.display = "none"; }; }()); </script> </body> </html> | cs |
이 코드는 div태그위에 마우스를 올려 놓으면 ajax를 이용하여 색이 바뀌는 코드인데 실행에 전혀 문제가 없다. 사실 내용을 볼게 아니라 스코프와 변수 위치에 초점을 맞춰서 보자. 스크립트 초장에 div태그 2개를 가져와서 변수에 박았다. 이 두개의 변수는 상위 스코프에 정의되어 있어서 문제 없이 참조가 가능하다. 그런데 만약 스코프가 복잡해지고, 변수가 많아지면 이렇게 상위 스코프에 있는 것을 단순히 가져오는 작업이 변수를 새로 만드는 것보다 메모리를 더 소비하기도 한다.
상위스코프에서 변수를 찾는 단계는 표준문서에서 다음과 같이 정의한다.
8.1.2.1GetIdentifierReference ( lex, name, strict )
The abstract operation GetIdentifierReference is called with a
- If lex is the value
null , then- Return a value of type
Reference whose base value component isundefined , whose referenced name component is name, and whose strict reference flag is strict.
- Return a value of type
- Let envRec be lex's
EnvironmentRecord . - Let exists be ? envRec.HasBinding(name).
- If exists is
true , then- Return a value of type
Reference whose base value component is envRec, whose referenced name component is name, and whose strict reference flag is strict.
- Return a value of type
- Else,
- Let outer be the value of lex's outer environment reference.
- Return ?
GetIdentifierReference (outer, name, strict).
쉽게 말해서 변수가 상위 스코프에 있을 때 자바스크립트는 내부적으로 변수의 환경 탐색을 재귀적으로 시행한다. 그러므로 상위 스코프에 있는 변수를 탐색하는 것은
컴퓨터 자원을 소모한다.
결국 최대한 변수를 하위스코프쪽으로 내리는 방법을 취하는 것이 성능에 좋은 영향을 미친다는 것이다.
위의 코드를 바꿔보면
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <html> <body> <div id="divMouseover">Mouse over Highlight</div> <div id="divFloatingContent">Floating Content</div> <script> (function () { var divMouseover = document.getElementById("divMouseover"), divFloatingContent = document.getElementById("divFloatingContent"); divMouseover.onmouseover = function () { var xhr = new XMLHttpRequest(), localDivMouseover = divMouseover; localDivMouseover.style.backgroundColor = "#FF0000"; localDivMouseover.style.color = "white"; localDivMouseover.style.fontSize = "12px"; xhr.open("GET", "http://myserver.com/floating_contents"); xhr.onload = function () { var localDivFloatingContent = divFloatingContent; localDivFloatingContent.innerHTML = xhr.responseText; // #1 localDivFloatingContent.style.display = "block"; }; xhr.send(); }; divMouseover.onmouseout = function () { var localDivMouseover = divMouseover; localDivMouseover.style.backgroundColor = "#FFFFFF"; localDivMouseover.style.color = "black"; localDivMouseover.style.fontSize = "10px"; divFloatingContent.style.display = "none"; }; }()); </script> </body> </html> | cs |
아까와의 차이는 상위 스코프의 변수를 그대로 다 쓰지 않았다는 것이다. 즉, line 20에서 한 번 가져온 후 (로컬변수가 됨) 이 로컬 변수를 돌려서 쓰고 있는 형태로 변경되었다. 이 말고 더 복잡한 코드에서 더 효과를 발휘하겠다. 더욱이 좋은 점은 변수가 몇개 없더라도 의외로 큰 비율로 효과가 나타난다. 하물며 복잡한 코드에서는 말할 것도 없다. 이러한 측면을 고려해서 개발한다면 훨씬 더 좋은 성능을 발휘할 수 있겠다.
이러한 스코프와 마찬가지로 변수의 속성을 한단계씩 들어갈 때마다 자원을 소모한다. 이처럼 변수의 속성에 접근하는 경우를 최적화 하는 법을 살펴보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <html> <body> <div id="divMouseover">Mouse over Highlight</div> <div id="divFloatingContent">Floating Content</div> <script> (function () { var divMouseover = document.getElementById("divMouseover"), divFloatingContent = document.getElementById("divFloatingContent"); divMouseover.onmouseover = function () { var xhr = new XMLHttpRequest(), divMouseoverStyle = divMouseover.style; divMouseoverStyle.backgroundColor = "#FF0000"; divMouseoverStyle.color = "white"; divMouseoverStyle.fontSize = "12px"; xhr.open("GET", "http://myserver.com/floating_contents"); xhr.onload = function () { var localDivFloatingContent = divFloatingContent; localDivFloatingContent.innerHTML = xhr.responseText; // #1 localDivFloatingContent.style.display = "block"; }; xhr.send(); }; divMouseover.onmouseout = function () { var divMouseoverStyle = divMouseover.style; divMouseoverStyle.backgroundColor = "#FFFFFF"; divMouseoverStyle.color = "black"; divMouseoverStyle.fontSize = "10px"; divFloatingContent.style.display = "none"; }; }()); </script> </body> </html> | cs |
이전처럼 스타일속성에 여러번 접근하는 것이 아니라 초기에 저렇게 한 번 스타일자체를 변수에 넣어서 할당해 놓으면 위의 표준에서 설명한 것처럼 재귀적으로 탐색하는 과정을 생략할 수 있어 성능을 조금 더 개선할 수 있다.
자바스크립트는 이처럼 변수의 할당과 접근이 자유롭다. 그래서 개발자가 더 변수를 유연하게 사용하여 성능을 최적화 할 수 있다.
결론) 상위 스코프에 있는 변수나 속성값을 여러번 접근하는 경우 로컬 변수에 할당해서 사용하면 좋다.
'프로그래밍 > ' 카테고리의 다른 글
[JavaScript] 자바스크립트 코딩 스타일 규칙 정리 (0) | 2017.12.02 |
---|---|
자바스크립트 프로토타입 (0) | 2017.03.08 |
javascript 글로벌 변수에 대해서 (0) | 2017.02.05 |
자바스크립트의 1급객체와 클로저 개념 (0) | 2017.02.01 |
javascript scope (자바스크립트 스코프에 대해) (0) | 2017.01.31 |