Web worker trong html5

      82

Introduction

JavaScript là một môi trường đối chọi luồng (single-threaded environment), có thể phát âm dễ dàng và đơn giản là trên một thời điểm cố định chỉ bao gồm một script được triển khai. Trong thời hạn gần đây, vấn đề sử dụng JavaScript vào bài toán thi công những ứng dụng website trở nên thịnh hành rộng lúc nào không còn, những các bước được đưa đa số về phía client. Tính chất đối kháng luồng của JavaScript là một trong những ngăn cản so với vấn đề trên bởi nó có tác dụng hình ảnh hường tương đối bự đến hiệu năng của những áp dụng web. Một ví dụ đơn giản là các ứng dụng website thường xuyên cần truy nã vấn database, tiến hành các chuyển đổi phức tạp trên DOM, xử lý những sự kiện liên quan cho UI cùng request mang lại những API mặt thứ tía - không ít Việc cho 1 thread.

Bạn đang xem: Web worker trong html5

Trong thừa khứ đọng bọn họ thường xuyên áp dụng setInterval , setTimeout, XMLHttpRequest và event handlers để tiến hành quá trình đồng điệu hóa (concurrency). Sử dụng những triông xã bên trên có thể chấp nhận được thực thi code một giải pháp bất đồng hóa, dẫu vậy nó ko trọn vẹn không có nghĩa chúng ta đang tiến hành concurrency một biện pháp không thiếu thốn. Lúc Này WEB API cung ứng một luật pháp xuất sắc hơn nhằm tiến hành multi-threading task một bí quyết công dụng hơn - Web Workers. Web Workers chưa phải là 1 công nghệ new lúc nó Thành lập cùng với HTML5, trọng trách thiết yếu của những Workers là tiến hành những scripts giải pháp xử lý những các bước nặng nề (querying API, complex mathematical computations) sinh sống background cùng bóc tách biệt với những scripts tương quan mang đến UI (thường là Main Thread). Việc này cho phép long-running scripts được thực hiện mà không gây hình họa đào bới trải đời của người dùng.

Trong bài viết này mình đang trình diễn đầy đủ kỹ năng và kiến thức cơ bạn dạng liên quan mang lại Web Workers, cách hoạt động, các use-cases cũng tương tự số đông chú ý Khi áp dụng chế độ này Lúc phát triển.

Web Workers

Definition

Web Worker (xuất xắc Worker) là một trong đối tượng người dùng JavaScript được chế tạo ra bằng bài toán áp dụng Worker constructor (e.g Worker, SharedWorker, AudioWorker) với tsay mê số là tên (mặt đường dẫn) mang lại một JavaScript file. JavaScript file đó cất các lô ghích được khởi chạy phía bên trong thread của worker vừa sản xuất. Script bên phía trong Worker sẽ tiến hành triển khai làm việc background với tách bóc biệt khỏi thread chính của web application.

Trong nội dung bài viết này, chúng ta vẫn đa phần khám phá về Worker (DedicatedWorker). Để ban đầu bọn họ sẽ tạo nên một instance của DedicatedWorker cùng hiển thị nó trong console. Để đơn giản dễ dàng bọn họ giả sử mọi lô ghích bên dưới được thực hiện phía bên trong script tag của một file HTML.

var worker = new Worker("prime.js")console.log(worker)console.log(this)

*

Sau Lúc sẽ log Worker instance cùng context hiện nay bạn cũng có thể thấy một số API cơ bản của Worker nhỏng onerror, onmessage, postMessage và terminate. Những API này sẽ tiến hành đề cùa đến trong phần sau của nội dung bài viết. Chú ý rằng context ngày nay là global context xuất xắc Window. Bây tiếng chúng ta đang sửa đổi file prime.js với thêm 1 dòng alert đơn giản và dễ dàng alert("Hello from the outside!") và reload lại trình chuyên chú. Quan gần kề hiệu quả trong console ta sẽ thấy một error.

*

Chúng ta sử dụng JavaScript tuy vậy tất yêu truy cập được alert function. Nguim nhân làm việc đây là prime.js sẽ tiến hành tiến hành bên phía trong một context không giống với Window. Script bên trong worker được phép truy cập đến những DOM API tuy vậy không phải tất cả các API những truy vấn được phía bên trong Worker. Để đánh giá context bây chừ, chúng ta đã thêm mẫu lệnh dễ dàng và đơn giản sau vào phía bên trong prime.js: console.log(this). Kết trái chiếm được vẫn nlỗi hình mặt dưới:

*

Để ý rằng context bây chừ đã được biến đổi thành DedicatedWorkerGlobalScope ráng do Window (giả dụ áp dụng SharedWorker context đang là SharedWorkerGlobalScope). Bên vào context của các Worker chúng ta cũng có thể triển khai những súc tích JavaScript thường thì. Tuy nhiên chúng ta quan trọng tiến hành những thao tác bên trên DOM một phương pháp trực tiếp, tương tự như tất yêu truy cập mang lại một trong những method và property của window object. Ngoài mọi giới hạn trên, bọn họ vẫn rất có thể truy vấn mang đến không ít API quan trọng đặc biệt như:

Communication Between Threads

Worker script sẽ tiến hành tiến hành bởi một background thread tách bóc biệt và chạy song song với thread thiết yếu. Trong những trường phù hợp bọn họ đề xuất truyền dữ liệu tự các background worker mang lại main thread nhằm giải pháp xử lý với ngược lại. Nói bí quyết khác, họ yêu cầu coordinate (điều phối) quan hệ giữa các thread với nhau.

Nếu bạn đã từng thao tác làm việc với Concurrency vào Java, hoàn toàn có thể các bạn đã nghe đến nhì quan niệm hơi cơ phiên bản là Producer và Consumer. lúc lập trình với thread nhị các bước chúng ta hay nên làm chính là synchronizecoordinate các thread. Trong Java câu hỏi kia sẽ được tiến hành bằng phương pháp sử dụng Semaphores (một số phương pháp rõ ràng đó là áp dụng wait-notify hoặc wait-notifyAll). Trong quan hệ Producer/Consumer, vấn đề coordinating sẽ giúp đỡ mang đến bài toán truy vấn cốt truyện resources trnghỉ ngơi bắt buộc đúng mực.

Quay trở về cùng với Worker, phép tắc coordinate thân các worker cùng main thread đang là message-passing sử dụng sự kiện Mã Sản Phẩm. Main thread rất có thể gửi đọc tin cho các Worker thông qua postMessage. postMessage sẽ nhận tđắm say số đầu vào là một trong những string hoặc một JSON object. Main thread với Worker vẫn nhận đọc tin bằng câu hỏi lắng tai message sự kiện, với truy vấn tài liệu trải qua event.data.

var worker = new Worker("foo.js")worker.postMessage("Hello from main thread")worker.addEventListener("message", function (e) console.log(e.data) // Hello from worker, false)// foo.jsself.addEventListener("message". function (e) console.log(e.data) // Hello from main thread self.postMessage("Hello from worker"), false)// another way khổng lồ listen for the ventself.onmessage = function (e) ...Trong context của một Worker, this cùng self phần đông chỉ mang đến global scope - WorkerGlobalScope

Lưu ý rằng dữ liệu truyền thân Main Thread cùng các Worker sẽ tiến hành sao chép (copied) chứ không cần được share (shared). Giả sử tài liệu truyền rằng trường đoản cú Main Thread với Worker là một trong những JSON object cất name property, property này sẽ truy cập được nghỉ ngơi cả Main Thread cùng Worker tuy vậy cực hiếm vẫn là không giống nhau. Trên thực tế, tài liệu sẽ được serialized trước khi được gửi đến cho các Worker và dữ liệu kia sẽ được de-serialized sau đó. Dữ liệu không được share đề xuất sẽ tạo nên ra một phiên bản sao sau mỗi lần được truyền rằng. Đó cũng chính là nguyên do tại vì sao bọn họ đề xuất để ý khi dùng Worker vị nó tương đối tốn tài nguim của khối hệ thống. Trong phần tiếp sau của bài viết, chúng ta sẽ đề cùa đến một phương pháp để giải quyết và xử lý sự việc này.

Transferrable objects

Hầu hết những trình duyệt hiện giờ đầy đủ cài đặt structured cloning algorithm có thể chấp nhận được họ thực hiện những phong cách tài liệu phức hợp hơn đến Worker, ví dụ như: Blob, File, FileList, ArrayBuffer, Map, với JSON objects. Mục đích của structured cloning algorithm là làm cho quá trình sao chép các object phức tạp trở đề nghị công dụng rộng. Tuy nhiên đề nghị hãy nhớ là, tài liệu vẫn sẽ tiến hành copied trong những lần Hotline postMessage. Giả sử chúng ta đề nghị gửi một tệp tin khoảng 100MB giữa Worker và Main Thread, vấn đề này sẽ gây tốn tương đối nhiều tài nguyên ổn khối hệ thống.

Các thứ hạng tài liệu bên trên hỗ trợ các chắt lọc mềm mỏng rộng Lúc định dạng dữ liệu tương truyền, tuy nhiên quá trình copy rất có thể kéo dãn nếu tài liệu gồm kích thước quá lớn. Transferrable objects là một trong những phương pháp để khắc phục sự việc này. Lúc sử dụng transferrable objects dữ liệu vẫn chỉ biến đổi context cùng không xẩy ra copy lại. Hiểu một giải pháp dễ dàng, nó y hệt như pass-by-reference (nắm vì pass-by-value) vào ngữ điệu C.

ArrayBuffer hay hay sử dụng vào câu hỏi thương lượng tài liệu giữa Worker với Main Thread. Sử dụng ArrayBuffer chúng ta có thể truyền binary data ví dụ như ảnh, âm thanh hao hiệu quả hơn, nuốm do áp dụng base64 encoding như trước.

Syntax đến postMessage vẫn nlỗi sau:

worker.postMessage(message, );Trong kết cấu bên trên, message đã là tài liệu được gửi cho Worker, nó không độc nhất vô nhị thiết phải là 1 ArrayBuffer, nó là tài liệu nhưng bạn cũng có thể kéo ra sử dụng e.data. Tđê mê số vật dụng nhị đã là những transferrable objects mà bọn họ ao ước gửi quyền sở hữu. Lý bởi vì họ nói đưa quyển tải (ownership) là vì transferrable object sau thời điểm được gửi trường đoản cú Main Thread sang Worker thì chỉ rất có thể thực hiện được mặt Worker cùng ngược chở lại.

Các bạn có thể tìm hiều một ví dụ cụ thể về việc thực hiện Transferrable objects đến Web Worker trên đây

Dedicated Worker

Trong phần này của nội dung bài viết, bọn họ đang tìm hiểu cách áp dụng DedicatedWorker. Về SharedWorker những chúng ta có thể search hiều thêm tại đây

Trước Khi tò mò biện pháp áp dụng, bọn họ bắt buộc chú ý rằng Dedicated Worker đã chỉ được sử dụng vì chưng 1 script tuyệt nhất, không giống cùng với Shared Worker lúc nó có thể được áp dụng do nhiều script khác biệt (cùng domain name cùng với Worker). Tuy nhiên bây chừ DedicatedWorker phổ biến hơn tương đối nhiều đối với SharedWorker và một trình xem xét nhỏng Safari cùng Internet Explorer ko cung cấp SharedWorker trong bất kể phiên phiên bản làm sao tính mang đến thời điểm nội dung bài viết này.

Xem thêm: Thuật Ngữ Yaoi Là Gì ? Cùng Tìm Hiểu Về Yaoi, Bl Và Shounen Ai Là Gì

Worker Detection

Trước lúc sử dụng Worker bọn họ đề xuất kiểm soát coi trình xem xét ngày nay tất cả cung cấp Worker hay không. Do Worker constructor function được truy vấn trải qua window object, bạn cũng có thể khám nghiệm như sau:

if (window.Worker) var worker = new Worker("foo.js")// Using Modernizrif (Modernizr.webworkers) var worker = new Worker("bar.js")Create New WorkerViệc tạo new một Dedicated Worker instance là tương đối đơn giản và dễ dàng, bọn họ chỉ cần sử dụng Worker() constructor function cùng với tđê mê số đầu vào là URI mang đến script sẽ được triển khai bên trong worker thread:

if (window.Worker) var worker = new Worker("./math/prime.js")Exchange MessagesTrong phần trước khi đề cập đến message-passing trong Worker, họ đã đi được qua 1 ví dụ đơn giản minch họa quá trình trao đổi dữ liệu giữa Main Thread cùng Worker. Sau Khi đã tất cả một instance của Worker, nhằm khởi hễ Worker đó họ đang thực hiện postMessage function. Lưu ý, trong ngôi trường vừa lòng không tồn tại dữ liệu được truyền rằng, bọn họ nên pass một empty string nlỗi argument trước tiên mang lại postMessage. Lý bởi vì là bài toán thiết đặt function bên trên giữa các trình duyệt là không hoàn toàn giống như nhau. Một số trình cẩn thận như Firefox sẽ báo lỗi Khi chúng ta không truyền tham mê số mang đến postMessage

worker.postMessage("")worker.postMessage("Hello World!")worker.postMessage( name: "Foo Bar", age: 100000 )Sau lúc đã kick off Worker, họ đã thực hiện Event Model để điều đình tài liệu. Cách thường được sử dụng là lắng tai message event rứa vày sử dụng onmessage property. Chúng ta đã đi qua một ví dụ nữa, tuy vậy cố vị thảo luận string chúng ta sẽ sử dụng object mang lại dữ liệu.

// index.htmlbutton onclick="greeting()">Greeting/button>button onclick="stop()">Stop Worker/button>output id="result">/output>script> if (window.Worker) var worker = new Worker("worker.js") worker.addEventListener("message", function (e) document.getElementById("result").textContent = e.data , false) function greeting() worker.postMessage( "name": "Anonymous", "age": 25 ) function stop() worker.terminate() /script>// worker.jsself.addEventListener("message", function (e) var data = e.data var mesage = "Hello! I am " + data.name + "I am " + data.age + " years old" self.postMessage(message), false)Trong ví dụ bên trên Main Thread sẽ gửi mang đến Worker một object cất thông tin về một bạn nào kia. Nhiệm vụ của Worker đã là tạo nên một câu trình làng về fan đó là trả lại đến Main Thread. Main Thread sẽ lắng nghe message event với in câu xin chào kia sử dụng output HTML tag. Để dừng worker chúng ta thực hiện terminate function. Chúng ta cũng thực hiện một bối cảnh dễ dàng cùng với hai button cho hai bài toán là hiển thị câu chào cùng ngừng worker.

Terminate Worker

Để ngừng một worker chúng ta gồm hai cách sau (chúng ta cũng có thể ngắt liên kết tự Main Thread hoặc từ mặt Worker):

Sử dụng terminate function bên trên Worker instance.Sử dụng cthảm bại bên trong Worker script.

// Terminate worker using workerworker.terminate()// Terminate worker inside worker scriptself.close()Hande ErrorsTrong gần như ví dụ bên trên bọn họ chưa đề cùa tới Việc xử trí những error có thể xảy ra. Tương tự quy trình dìm và xử lý dữ liệu, chúng ta sẽ lắng nghe error sự kiện và handle những error trong callback:

worker.addEventListener("error", function (e) console.log(e) // Handle the error, false)Event object trả về tiến hành ErrorEvent interface, và hỗ trợ cho bọn họ tương đối nhiều công bố hữu ích:

lineno: Vị trí của dòng code gây ra lỗi.filename: tên của tệp tin nhưng mà lỗi xảy ra.message: miêu tả cụ thể về lỗi đang xảy ra.Import Scripts

Bên trong một Worker, bạn có thể thực hiện this.importScripts(urls) để import các thư viện cùng dependency cần thiết đến worker script.

this.importScripts("foo.js")this.importScripts("foo.js", "bar.js", "fizz.js")Lưu ý rằng họ quan trọng import một vài thư viện nlỗi jQuery bên trong worker script bằng cách này. Trong phần đầu của nội dung bài viết bọn họ từng đề cùa đến vấn đề cấp thiết truy vấn toàn bộ những API phía bên trong window object (vày một trong những sự việc về bảo mật), giả dụ thực hiện this.importScripts("jquery.js") sẽ có được lỗi xảy ra.

Subworkers

Một Worker hoàn toàn có thể đựng nhiều Worker bé (Subworker) khác nhau, chất nhận được bọn họ chia bé dại hơn nữa một task bên trong một Worker. Lúc sử dụng Subworker họ cần chú ý một trong những sự việc sau:

Subworkers buộc phải được lưu trữ thuộc origin so với Worker gốc.URI trong Subworkers đã là đường truyền tương đối đối với địa điểm của Worker gốc.

Hầu hết các trình để mắt số đông hỗ trợ một process riêng biệt cho từng Worker. Trước Khi sử dụng thêm một Worker chúng ta đề xuất quyên tâm cho tài nguim hiện tại của hệ thống. Nguim nhân là dữ liệu truyền đi thân phương pháp Worker sẽ tiến hành sao chép chứ không hề tầm thường một mối cung cấp, sử dụng vô số Worker sẽ không mang đến hiểu trái với làm cho ảnh hưởng cho performance của ứng dụng.

Limitations

Worker là 1 trong những chính sách hơi hữu dụng, tuy nhiên nó cũng có thể có một số hạn chế nhất mực, vào phần này họ vẫn đề cùa tới một số trong những vấn đề gặp gỡ bắt buộc khi thực hiện Worker.

Same Origin

Tất cả những Worker script phải được served từ bỏ cùng một domain name nlỗi script nhưng nghỉ ngơi kia Worker được khởi tạo ra. Điều này cũng vận dụng cho cả các loại protocol sẽ sử dụng.

Limited Access

Logic phía bên trong Worker sẽ là tách biết đối với Main Thread, cho nên vì vậy Worker rất có thể sẽ không truy cập được cho một trong những DOM APIs (như sẽ kể tới trong phần đầu của bài xích viết). Một phương pháp để thực hiện các việc tương quan đến Main Thread là gửi message cho nó từ bỏ Worker trải qua postMessage.

Restricted Local Access

Worker sẽ không còn hoạt động ví như web page được VPS trực tiếp từ bỏ filesystem. Chúng ta cần có một server nếu còn muốn thực hiện Worker.

Conclusion

Trong bài viết này mình bao gồm trình diễn một cách tương đối cơ bạn dạng về Web Worker (triệu tập đa phần vào Dedicated Workers): có mang, cách chuyển động, biện pháp truyền cài đặt tài liệu, cũng giống như gần như giảm bớt là lưu ý Lúc áp dụng Web Worker. Mong rằng bài viết để giúp ích được một phần như thế nào kia đến chúng ta vào quá trình về sau.