[HTML5] Web Workers (웹 워커)

Posted in 모바일/HTML5 // Posted at 2010.08.05 17:36

HTML 5 의 많은 기능 중 웹 페이지가 단순 문서 표현을 넘어 응용프로그램과 같이 동작할 수 있도록
하는 주요한 기능 중 하나가 바로 Web Workders 이다

요즘 웬만한 응용프로그램들은 멀티 프로세스, 멀티 쓰레드를 구현하고 있다
웹 페이지도 이러한 멀티 쓰레드 구현이 가능하게 된 것이다

그간 웹 페이지는 단일 쓰레드 모드에서 수행될 수 밖에 없었다
만일 값을 반환하기까지 작업이 오래 걸리는 스크립트를 수행한다면 다른 UI 작업을
스크립트 작업이 종료될 때 까지 대기해야만 했다

그러나 HTML 5 에는 Web Worker 라는 스펙을 추가 했으며 브라우저에서는 이 스펙을 기반으로
멀티 쓰레드 구동이 가능하도록 브라우저를 설계하기에 이르렀다


롱~타임(Long~ Time) 작업은 워커에게 맡기기

이제 스크립트 작업이 오래 걸린다고 해서 페이지를 멈추고 기다릴 필요가 없어졌다
웹 워커는 자바스크립트 코드를 UI 쓰레드와는 별도인 백그라운드에서 수행될 수 있도록 하는 표준적인 방법을 제공하기 때문에 웹 페이지를 가로막지 않고 스크립트를 돌릴 수 있게 되었다

다음과 같은 롱~타임 스크립트 작업에 웹워커는 안성맞춤 일 것이다
- 매우 복잡한 수학적 계산 작업
- 원격지에 있는 리소스에 대한 액세스 작업(또는 로컬 스토로지를 액세스 하는 경우)
- 백그라운드에서 조용히(?) 오랜시간 작업해야 하는 경우
- UI 쓰레드에 방해 없이 지속적으로 수행해야 하는 작업 등

사실 웹 워커 만의 지침은 없다. 일반적인 응용프로그램의 백그라운드 작업을 연상하면 된다


브라우저가 Web Worker 를 지원하나요?
HTML 5 가 아직 산업 표준이 완료된 것이 아니기에 브라우저별로 지원 여부가 상이할 수 있다
그리고 브라우저 버전별로도 지원 유/무가 다르기도 하다

따라서 웹 페이지에 웹 워커를 동작시키기 전에, 현재 페이지를 랜더링 하고 있는 브라우저가
웹 워커를 지원하는지 체크하는 것이 필수이다 (이것은 하위 호환성을 위해서도 중요하다)

브라우저의 웹 워커 지원 유/무 체크는 매우 간단한 방법으로 할 수 있다
전역 윈도우 객체의 워커(Worker) 속성을 살펴보면 된다. 아래는 샘플 코드이다

if(!!window.Worker){
      alert("이 브라우저는 웹 워커를 지원합니다")
}
else{
      alert("이 브라우저는 웹 워커를 지원하지 않습니다")
 }


Web Workers 개념도
웹 워커는 HTML 페이지에서 Worker 라는 객체를 통해 실행된다
HTML 페이지에 Worker 객체를 생성하기 위해서는 워커의 작업을 정의한 자바스크립트파일(.js)
을 Worker 객체 생성 시 전달해 줘야 한다
ex) var worker = new Worker("worker.js")

이후 롱~타임 작업은 .js 파일에 정의된 스크립트로 수행되며,
HTML 페이지와는 서로 데이터를 주고 받을 수 있는 매커니즘이 제공되는 것이다

양쪽 모두 상대에게 데이터를 송신할 때는 postMessage 라는 메서드를 이용하며
데이터를 수신할 때는 onmessage 이벤트를 통해 전달 받는다

아래 그림은 기본적인 (단일) 워커와 HTML 페이지 간 데이터 송/수신 개념도 이다





Web Workers 브라우저 지원 현황
현재 IE를 제외한 대부분의 웹브라우저에서 웹 워커를 지원하고 있다
아래 표는 http://caniuse.com/ 에서 제공하는 브라우저(버전)별 웹 워커 지원 표이다
(데스크탑 용 브라우저 기준이다)

MS IE 9 가 unknown 이라고 되어 있지만 아마 지원하게 될 것이다.
MS 가 HTML 5 지원을 강력히 표명하고 있기 때문이다






위 표는 데스크탑 버전의 브라우저 지원 현황이다
모바일 환경은 이와 좀 다를 수 있는데 대표적인 예로 사파리를 들 수 있다

사파리의 경우 데스크탑 사파리는 Web Workers 를 지원하는데 반해,
아이폰 사파리는 Web Workers 를 현재까지 지원하지 않고 있다

아이폰에 내장된 사파리의 경우 대부분의 HTML5를 지원하지만,
유독 Web Worker 는 아직 지원하지 않고 있는 것이 의아하다

현재 모바일 웹 구축 시 제일 먼저 고려되는 플랫폼이 아이폰 환경인데 말이지...


Web Workers 데모 만들어 보기
지금까지 웹 워커에 대한 개념적 내용을 살펴 보았다
그럼 이제 웹 워커를 이용한 매우 기본적인 데모 코드를 작성해 보도록 하자

웹 워커의 장점을 알려면 웹 워커를 사용하지 않을 때의 단점을 알아보고
그 단점을 웹 워커로 해결하는 식의 접근이 이해하기 보다 수월할 수 있다
따라서 먼저 웹 워커 없이 시간이 오래 걸리는 스크립트 코드를 돌려 보자

시나리오를 단순하게 하기 위해,
샘플에서는 특별히 오래 걸리는 특정 작업을 구현하기 보다는 간단하게,
주어진 시간동안 반복(loop)문을 돌리는 것으로 대신하겠다.
일종의 대기(sleep) 시간이며 다음과 같이 스크립트 함수를 작성하도록 한다

- 시간이 오래 걸리는 작업(일종의 sleep 기능)
function sleep(milliSeconds){  
    var startTime = new Date().getTime(); 
    while (new Date().getTime() < startTime + milliSeconds);
}

이제 이 코드를 HTML 페이지에 삽입하여 실행해 보도록 하자

- HTML 페이지
아래와 같이 HTML 과 스크립트를 작성한다. 대략 10초 동안 대기(sleep) 시킨다
그리고 텍스트 상자는 대기시간동안 글 작성이 가능한지 보기 위해 삽입하였다
<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript">
      function sleep(milliSeconds){ 
        var startTime = new Date().getTime(); 
        while (new Date().getTime() < startTime + milliSeconds); 
      }      
      function callNotWorker(){
        sleep(10000); //10초 동안 대기 시킨다
      }    
          
    </script>
  </head>
  <body>
    <button onclick="callNotWorker()">워커없이 호출</button>   
    <br>   
    <input type="text">
  </body>
</html>

- 실행 화면
HTML 파일을 웹 브라우저(데스크 탑 사파리)에서 실행하면 약 10초 이 후 완료 메시지가 나타난다
그런데 문제는 대기 시간 10초 동안 브라우저에서 다른 작업을 할 수 없다는 것이다
브라우저를 움직일 수도 없고 텍스트 상자에 글을 입력할 수도 없는 듯 마치 꽁꽁 얼어버린 듯 하다
10초 후 메시지가 나타난 이후부터 다른 작업을 할 수 있게 되는 것이다


이것이 바로 단일 쓰레드(UI 쓰레드) 환경의 특징이다
스크립트에서 시간이 오래 걸리는 작업을 하는 동안 다른 일을 할 수가 없는 것이다

웹 워커는 이런 형태의 작업을 멀티 쓰레드 환경처럼 동작하도록 만들어 준다
즉 시간이 오래 걸리는 작업은 백그라운드에서 실행되기 때문에 UI 쓰레드는 다른 일을
동시에 할 수 있는 것이다. 그럼 웹 워커를 사용하는 버전을 수정해 보도록 하자

- 워커 정의하기(JS 파일에 정의한다)
시간이 오래 걸리는 스크립트 코드 즉 백그라운드 환경에서 실행되어야 하는 스크립트는
별도의 자바스크립트파일(worker.js) 로 작성한다

//메세지 수신하여 시간이 오래 걸리는 작업을 처리한다
onmessage = function(event){
  var receiveData = event.data;
  sleep(10000); 
    
  //워커를 호출한 곳으로 결과 메시지를 전송한다
  var sendData = receiveData + "OK~ I'm Worker"
  postMessage(sendData)
}

function sleep(milliSeconds){ 
  var startTime = new Date().getTime(); // get the current time  
  while (new Date().getTime() < startTime + milliSeconds); // hog cpu
}

- HTML 페이지
이제 이 워커(파일)을 이용하는 HTML 페이지를 아래와 같이 작성한다
앞서 정의한 worker.js 파일을 기반으로 Worker 객체를 생성하고 postMessage 메서드를 통해
워커로 메시지를 전달한다. 또한 onmessage 이벤트를 정의하여 워커로 부터 전달되는 메시지를
받을 수 있도록 한다. 그리고 워커의 작업을 중지시키려면 terminate 메서드를 호출하면 된다

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript">             
      var worker;     
      function callWorker(){     
        if(!!window.Worker){ //브라우저가 웹 워커를 지원하는지 검사한다   
           
          if(worker) worker.terminate();      //워커가 이미 존재하면 종료시킨다                    
          worker = new Worker("worker.js");  //새로운 워커(객체)를 생성한다      
                      
          worker.onmessage = function(event){ //워커로부터 전달되는 메시지를 받는다
            alert(event.data);
          };
                           
          worker.postMessage("워커야! 깨어나라!"); //워커에게 메시지를 전달한다       
        }
        else{
          alert("현재 브라우저는 웹 워커를 지원하지 않습니다")
        }
      }
               
      function stopWorker(){
        if(worker){
          worker.terminate();
          alert("워커 작업이 중지되었습니다");
        }
      }
    </script>
  </head>
  <body>
    <button onclick="callWorker()">웹워커 호출</button>
    <button onclick="stopWorker()">웹워커 중지</button>   
    <br>   
    <input type="text">
  </body>
</html>

- 실행 화면
HTML 파일을 웹 브라우저(데스크 탑 사파리)에서 실행하면 10초 후에 메시지가 나타난다
또한 워커를 사용했기 때문에 브라우저가 얼어 버리는 일은 없다
즉 10초라는 대기 시간 동안에도 브라우저를 움직이거나 텍스트 상자에 글을 입력할 수 있게 되는 것이다



결과적으로 두 작업이 동시에 처리되는 병렬작업이 가능하게 되는 것이다
이러한 병렬처리는 응용프로그램의 중요한 요구사항이며 이제 워커 덕분에
웹 페이지에서도 이러한 응용 환경 구현이 가능하게 된 것이다

마지막으로 아래 사이트에서 웹워커 관련 데모를 추가로 확인해 보자
http://html5demos.com/worker

'모바일 > HTML5' 카테고리의 다른 글

[HTML5] 드래그 앤 드롭 (Drag & Drop)  (3) 2010.08.10
[HTML5] Geolocation  (1) 2010.08.09
[HTML5] Web Workers (웹 워커)  (1) 2010.08.05
HTML5 Demo, A Look At HTML5 and its Canvas Tag  (0) 2010.07.29
[HTML5] HTML5 개요와 기술적 특징  (4) 2010.07.21
HTML5 책, HTML5 & API 입문  (2) 2010.07.09
  1. 웹워커

    안녕하세요~ㅎㅎ
    웹워커를 제가 해봤는데요,,,
    멈추는 것은 되는데 10초를 기다려도 끝나지가 않네요...
    다른 코드도 마찬가지구요
    오류가 뜨면 말하라고 해놓고
    웹 워커 호출을 하면 계속 오류만 뜬다고 발생하는데 어떻게 해야할까요?ㅎㅎ

submit