본문 바로가기
웹 프로그래밍

[JavaScript] - 코드 블로킹 (Code Blocking) 방지

by CHML 2016. 9. 4.
1. 코드 블로킹 (Cdoe blocking)

코드 블로킹은 어떠한 코드가 실행됨에 따라 해당 코드의 실행 때문에 다른 코드를 실행할 수 없는 현상을 말한다. 아래와 같이 자바스크립트로 작성된 [코드 1]이 있다.


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
<!DOCTYPE html>
 
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <div id="result"></div>
    <button onclick="func();">start</button>
    
    <script type="text/javascript">
        function func() {
            document.getElementById('result').innerText = test1();
            document.body.style.backgroundColor = '#008299';
        }
 
        function test1() {
            var num = 0;
 
            for (var i = 0; i < 1000000000; i++) {
                num++;
            }
 
            return num;
        }
    </script>
</body>
</html>
cs

[코드 1] 블로킹 코드


[코드 1]을 실행하면, test1() 메소드의 코드를 모두 실행되고 id가 result인 div에 결과값을 출력할 때까지 body 요소의 배경색을 변경하지 않는다. 즉, test1() 메소드의 코드에 의해 body 요소의 배경색을 변경하는 코드가 블로킹 되었다. 아래의 [실행 결과 1]은 [코드 1]을 실행하였을 때와 [코드 1]을 실행하여 블로킹을 방지했을 경우의 실행 결과를 보여준다.


[실행 결과 1] 블로킹 코드와 블로킹 방지 코드의 실행 결과


[실행 결과 1]에서 블로킹 코드는 result가 div 요소에 출력될 때까지 body의 배경색이 변경하지 않는 반면에 블로킹 방지 코드는 test1() 메소드를 호출하고, 바로 body의 배경색을 변경한다.

[코드 1]과 같은 경우, test1() 메소드의 연산과 div 요소의 배경색을 변경하는 두 작업 사이에는 어떠한 의존성도 존재하지 않는다. 따라서, test1() 메소드의 실행이 모두 완료될 때까지 div 요소의 배경색을 변경하는 코드를 블로킹할 필요가 없다. 오히려 이러한 코드 블로킹 현상은 웹 어플리케이션의 로딩을 느리게 만드는 요인이 된다. 웹 페이지의 로딩 시간 증가는 시스템 이용자의 관점에서 볼 때 바람직한 현상이 아니기 때문에 웹 페이지 또는 웹 어플리케이션을 개발할 때 반드시 피해야 한다.


2. 블로킹 방지 코드

아래의 [코드 2]는 [코드 1]에서 발생하였던 코드 블로킹 현상을 방지하기 위한 블로킹 방지 코드이다. [코드 1]과 다르게 func() 메소드에서 test1() 메소드를 바로 호출하는 것이 아니라, nonBlock() 메소드를 통해 test1() 메소드를 호출하고 있다. [코드 1]과 [코드 2]의 실행 결과는 완전히 같지만, 실행 과정에는 많은 차이가 있다.


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
<!DOCTYPE html>
 
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <div id="result"></div>
    <button onclick="func();">start</button>
    
    <script type="text/javascript">
        function func() {
            nonBlock(function (result) {
                document.getElementById('result').innerText = result;
            })
            document.body.style.backgroundColor = '#008299';
        }
 
        function nonBlock(callback) {
            setTimeout(function () {
                callback(test1());
            }, 0);
        }
 
        function test1() {
            var num = 0;
 
            for (var i = 0; i < 1000000000; i++) {
                num++;
            }
 
            return num;
        }
    </script>
</body>
</html>
cs

[코드 2] 블로킹 방지 코드


자바스크립트에서는 어떠한 작업을 지연하는 기능을 구현하기 위해 setTimeout()이라는 메소드를 제공한다. [코드 2]에서는 setTimeout() 메소드에 지연 시간을 0으로 입력하여, test1() 메소드가 즉시 시작되도록 작성되어 있다. 그러나 setTimeout과 같은 타이머 이벤트는 비동기 이벤트의 경우처럼 일반적으로 이벤트 큐에 추가되기 때문에 setTimeout() 메소드의 코드는 비동기적으로 실행된다. 타이머 이벤트의 특성을 이용하여 코드를 비동기적으로 실행하기 때문에 [코드 2]는 블로킹을 방지할 수 있다.