HTML5 Web Workers là gì

04:00 ngày 11-09-2017

Một Web Worker là một chương trình JavaScript chạy trong background. Vì vậy, Web Worker sẽ không làm treo web khi chạy, nó sẽ không tác động đến hiệu suất của Website

Khi thực thi một đoạn JavaScript trong trang HTML. Website sẽ không phản hồi người dùng cho đến khi đoạn Script được thực thi xong. Điều này ảnh hưởng đến trải nghiệm người dùng nếu đoạn JavaScript thực thi khá lâu.
WebWorker sẽ chạy trong background, không bị tác động bởi các đoạn mã khác, không ảnh hưởng tới hiệu suất Website. Người dùng có thể scroll, click, hay làm bất cứ điều gì trong khi WebWorker chạy.


Bây giờ chúng ta hãy thử làm demo để thấy sự khác biệt giữa việc sử dụng WebWorker và không dùng WebWorker. 

Trước tiên hãy copy đoạn mã bên dưới vào file test.html

 <!DOCTYPE html>
<html>
<body>

<p>Status: <output id="result"></output></p>
<button onclick="timedCount()">Start No Worker</button>

<script>
function timedCount() {
    var now = new Date().getTime();
    var sleepDuration = 2000;
    while(new Date().getTime() < now + sleepDuration){ } 
    document.getElementById("result").innerHTML = "end";
}

</script>

</body>
</html> 

Với đoạn mã trên, khi timedCount được gọi, chúng ta sẽ khoảng sleep 2s. Điều này sẽ làm đơ trình duyệt khi chúng ta bấm button để gọi hàm này.


Bây giờ hãy sử dụng hàm này với WebWorker.
Trước tiên copy đoạn mã sau vào file worker.js

function timedCount() {
    var now = new Date().getTime();
    var sleepDuration = 2000;
    while(new Date().getTime() < now + sleepDuration){  } 
    postMessage("end");
}
timedCount(); 

Và đoạn mã bên dưới vào test2.html

<!DOCTYPE html>
<html>
<body>
<p>Status: <output id="result"></output></p>
<button onclick="startWorker()">Start Worker</button>
<script>
var w;
function startWorker() {
    if(typeof(Worker) !== "undefined") {
        if(typeof(w) == "undefined") {
            w = new Worker("worker.js");
        }
        w.onmessage = function(event) {
            document.getElementById("result").innerHTML = event.data;
            stopWorker();
        };
    } else {
        document.getElementById("result").innerHTML = "Sorry! No Web Worker support.";
    }
}
function stopWorker() {
    w.terminate();
    w = undefined;
}
</script>
</body>
</html> 

Hãy đặt hai file ở cùng thư mục và chạy test2.html. Click lên button, khoảng 2s sau "end" xuất hiện. Trong khoảng thời gian chờ, chúng ta hoàn toàn có thể thao tác trên Website mà không có bất kỳ trở ngại nào. Bởi vì, WebWorker đang thực thi trong background và không tác động đến Website của chúng ta.


Giờ chúng ta hãy xem xét một số thành phần quan trọng của WebWorker: 
new Worker("worker.js"): Khi khởi tạo một WebWorker, chúng ta cần chỉ định file JavaScript chưa nội dung cần thực thi.
terminate(): WebWorker còn tồn tại cho đến khi hàm này được gọi.
postMessage(data): truyền message từ WebWorker. Khi postMessage được gọi, sự kiện onmessage sẽ được thực thi.
onmessage: sự kiện này được thực thi khi WebWorker truyền message (thông qua lời gọi của postMessage). Dữ liệu từ WebWorker được lưu trữ trong event.data
Chúng ta có thể sử dụng postMessage và onmessage để truyền và nhận dữ liệu giữa HTML page và WebWorker.


Dưới đây là ví dụ về việc truyền nhận data giữa HTML và WebWorker

File worker.js

onmessage = function(event) {
    postMessage(event.data + 2);
};

File test3.html

<!DOCTYPE html>
<html>
<body>
<p><output id="result"></output></p>
<p>Count: <output id="count"></output></p>
<button onclick="startWorker()">Start Worker</button>
<button onclick="countWorker()">Count Worker</button>
<button onclick="stopWorker()">Stop Worker</button>
<script>
var w;
var count = 0;
function startWorker() {
    if(typeof(Worker) !== "undefined") {
        if(typeof(w) == "undefined") {
            w = new Worker("worker.js");        
            w.onmessage = function(event) {
                count = event.data;
                document.getElementById("count").innerHTML = count;
            };
        }
    } else {
        document.getElementById("result").innerHTML = "Sorry! No Web Worker support.";
    }
}
function stopWorker() {
    w.terminate();
    w = undefined;
}
function countWorker() {
    // start if needed
    if(typeof(w) == "undefined"){
        startWorker();
    }
    
    if(typeof(w) != "undefined"){
        w.postMessage(count);
    }
}
</script>
</body>
</html> 

 Mỗi khi chúng ta click button Counter, giá trị hiện tại sẽ được truyền đến WebWorker. WebWorker sẽ + 2 và truyền ngược lại HTML để hiển thị lên UI.


Chú ý rằng, chúng ta có thể chạy demo trực tiếp từ file trên trình duyệt FireFox, nhưng đối với Chrome, chúng ta cần web server để chạy.

 

Phản Hồi

Viết Phản Hồi

Chuyên Mục

Phản Hồi Mới