Tạo các ứng dụng Web di động với HTML 5, Phần 4: Sử dụng các Web Worker để tăng tốc các ứng dụng Web di động của bạn

Thêm JavaScript đa luồng cho HTML 5 để chiến thắng!

Theo truyền thống các ứng dụng Web đã bị mắc kẹt trong một thế giới đơn luồng. Điều này thực sự đã hạn chế các nhà phát triển về những gì họ có thể làm trong mã của họ, vì bất cứ điều gì cũng làm phức tạp thêm các nguy cơ đông cứng giao diện người dùng của ứng dụng. Các Web Worker (Trình làm việc trên nền Web) đã thay đổi tất cả những điều đó bằng cách đem đa luồng đến cho các ứng dụng Web. Điều này đặc biệt có ích với các ứng dụng Web di động do ở đó hầu hết logic ứng dụng nằm ở phía máy khách. Trong bài viết này, bạn sẽ tìm hiểu cách làm việc với các Web Worker và khám phá xem những nhiệm vụ nào thích hợp nhất cho chúng. Bạn sẽ thấy bạn có thể sử dụng các công nghệ HTML 5 như thế nào để nâng cao hiệu quả sử dụng các công nghệ đó.

Michael Galpin, Kiến trúc sư phần mềm, Ludi Labs

Michael Galpin đã phát triển phần mềm Java một cách chuyên nghiệp từ năm 1998. Ông hiện đang làm việc cho eBay. Ông đã có bằng về toán học của Viện Công nghệ California.



29 06 2010 (Xuất bản lần đầu tiên vào ngày 18 11 2011)

29.06.2010: Thêm các liên kết cho Phần 5 của loạt bài này trong các phần Giới thiệu về loạt bài này, Tóm tắt, và Tài nguyên.

Giới thiệu về loạt bài này

HTML 5 là một công nghệ được quảng cáo thổi phồng rất nhiều, nhưng có lý do chính đáng. Nó hứa hẹn sẽ là một điểm bùng phát công nghệ để mang các khả năng ứng dụng của máy tính để bàn đến cho trình duyệt. Do có triển vọng đối với các trình duyệt truyền thống, nên nó thậm chí còn có nhiều tiềm năng hơn cho các trình duyệt di động. Hơn nữa, các trình duyệt di động phổ biến nhất đã chấp nhận và triển khai thực hiện nhiều phần quan trọng của đặc tả HTML 5. Trong loạt bài năm phần này, bạn sẽ xem xét kỹ hơn về một số những công nghệ mới, là một phần của HTML 5 và có thể có tác động rất lớn trong việc phát triển ứng dụng Web di động. Trong mỗi phần, bạn sẽ phát triển một ứng dụng Web di động đang làm việc để giới thiệu một tính năng của HTML 5, có thể được sử dụng trên các trình duyệt Web di động hiện đại giống như các trình duyệt đã thấy trên các thiết bị iPhone và các thiết bị dựa vào-Android.


Bắt đầu

Trong bài viết này, bạn sẽ phát triển các ứng dụng Web bằng các công nghệ Web mới nhất. Hầu hết các mã có ở đây chỉ là HTML, JavaScript và CSS — các công nghệ lõi của nhà phát triển Web bất kỳ. Điều quan trọng nhất mà bạn sẽ cần là các trình duyệt để thử nghiệm các ứng dụng. Hầu hết mã trong bài viết này sẽ chạy trên các trình duyệt mới nhất với một số trường hợp ngoại lệ cần lưu ý. Tất nhiên bạn cũng phải thử nghiệm trên các trình duyệt di động, và bạn sẽ cần có các bản iPhone SDK và Android SKD mới nhất cho các trình duyệt đó. Trong bài viết này đã sử dụng iPhone SDK 3.1.3 và Android SDK 2.1. Ví dụ mẫu của bài viết này cũng sử dụng một máy chủ proxy để truy cập đến dịch vụ ở xa từ trình duyệt. Máy chủ proxy là một servlet của Java™ đơn giản, nhưng có thể dễ dàng thay thế bằng một proxy trong PHP, Ruby, hoặc những thứ khác. Xem phần Tài nguyên để biết các liên kết.


JavaScript đa luồng trên các thiết bị di động

Lập trình đa luồng hoặc đồng thời không có gì mới đối với hầu hết các nhà phát triển. Bằng cách này hay cách khác, nó được hỗ trợ bằng các ngôn ngữ lập trình hiện đại nhất. Tuy nhiên, JavaScript không phải là một trong các ngôn ngữ hỗ trợ lập trình đồng thời. Tác giả của lập trình đồng thời đã nghĩ rằng nó quá khó hiểu và không cần thiết cho một ngôn ngữ như JavaScript được thiết kế để thực hiện các nhiệm vụ đơn giản trên các trang Web. Tuy nhiên, do các trang Web đã phát triển thành các ứng dụng Web, nên mức độ phức tạp của các nhiệm vụ được thực hiện với JavaScript đã phát triển để đặt JavaScript ngang bằng với bất kỳ ngôn ngữ nào khác. Đồng thời, các nhà phát triển làm bằng các ngôn ngữ khác có hỗ trợ lập trình đồng thời thường đã trải qua và đã vật lộn với sự phức tạp rất cao đi kèm với các nguyên hàm đồng thời như các luồng và các đối tượng nhân kernel (mutex). Thực tế, gần đây, một số các ngôn ngữ mới như Scala, Clojure, và F # đã phát triển, tất cả đều hứa hẹn làm đơn giản hóa sự đồng thời.

Các từ viết tắt thông dụng

  • Ajax: JavaScript không đồng bộ + XML
  • API: Giao diện lập trình ứng dụng
  • CSS: Bảng định kiểu xếp chồng
  • DOM: Mô hình đối tượng tài liệu
  • HTML: Ngôn ngữ đánh dấu siêu văn bản
  • REST: Chuyển trạng thái biểu diễn
  • SDK: Bộ công cụ cho nhà phát triển phần mềm
  • UI: Giao diện người dùng
  • URL: Trình định vị tài nguyên thống nhất
  • W3C: Hiệp hội mạng toàn cầu
  • XML:Ngôn ngữ đánh dấu mở rộng

Đặc tả Web Worker (Trình làm việc trên nền Web) không chỉ thêm tính đồng thời cho JavaScript và các trình duyệt Web; nó còn thực hiện việc này một cách thông minh để truyền sự tự tin cho các nhà phát triển chứ không cung cấp cho họ một công cụ gây ra các rắc rối. Ví dụ, các nhà phát triển ứng dụng máy tính để bàn đã sử dụng đa luồng trong nhiều năm để cho các ứng dụng của họ truy cập tài nguyên Vào/Ra (I/O) mà không làm đông cứng hoạt động của giao diện người dùng trong lúc chúng chờ tài nguyên này. Tuy nhiên, các ứng dụng như vậy thường phải chịu thiệt hại khi các luồng này thay đổi tài nguyên chia sẻ (bao gồm giao diện người dùng) dẫn đến các ứng dụng đông cứng hoặc có lỗi. Với các Web Worker, điều này không thể xảy ra. Luồng được sinh ra không có quyền truy cập đến tài nguyên giống như luồng của giao diện người dùng chính. Trong thực tế, mã trong luồng được sinh ra thậm chí không thể nằm trong cùng một tệp như mã được thực hiện bởi luồng của giao diện người dùng chính.

Bạn thậm chí phải cung cấp tệp bên ngoài như là một phần của hàm tạo, như trong Liệt kê 1.

Quá trình này sử dụng ba thứ sau:

  1. JavaScript cho trang Web (tôi sẽ gọi nó là kịch bản lệnh trang) đã thực hiện trên luồng chính.
  2. Đối tượng Worker là đối tượng JavaScript mà bạn sử dụng để thực hiện chức năng Web Worker.
  3. Kịch bản lệnh sẽ được thực hiện trên luồng mới được sinh ra. Tôi sẽ gọi nó là kịch bản lệnh Worker.

Hãy bắt đầu bằng cách xem xét kịch bản lệnh trang trong Liệt kê 1.

Liệt kê 1. Sử dụng một Web Worker trong kịch bản lệnh trang
var worker = new Worker("worker.js");
worker.onmessage = function(message){
    // do stuff
};
worker.postMessage(someDataToDoStuffWith);

Trong Liệt kê 1, bạn có thể thấy ba bước cơ bản trong việc sử dụng các Web Worker. Trước tiên, bạn tạo một đối tượng Worker và chuyển cho nó địa chỉ URL của kịch bản lệnh sẽ được thực hiện trong luồng mới. Tất cả mã mà Worker sẽ thực hiện phải được chứa trong kịch bản lệnh Worker có địa chỉ URL của nó được chuyển vào như là hàm tạo của Worker. URL của kịch bản lệnh Worker này bị hạn chế bởi chính sách đầu tiên giống như của trình duyệt — nó phải đến từ cùng một miền đã tải trang đã tải kịch bản lệnh trang đang tạo Worker này.

Bước tiếp theo bạn làm là chỉ định một hàm của trình xử lý gọi lại bằng cách sử dụng hàm onmessage. Hàm gọi lại sẽ được gọi ra sau khi kịch bản lệnh Worker thực hiện. message (thông báo) là dữ liệu được trả về từ kịch bản lệnh Worker và bạn có thể làm bất cứ điều gì bạn muốn với thông báo đó. Hàm gọi lại được thực hiện trên luồng chính, vì vậy nó có quyền truy cập vào DOM. Kịch bản lệnh Worker chạy trong một luồng khác và không có quyền truy cập vào DOM, do đó bạn cần gửi dữ liệu từ kịch bản lệnh Worker trở lại luồng chính ở đó bạn có thể sửa đổi DOM một cách an toàn để cập nhật giao diện người dùng của ứng dụng của bạn. Đây là tính năng quan trọng của thiết kế không chia sẻ gì của các Web Worker.

Dòng cuối cùng của Liệt kê 1 cho thấy Worker được khởi tạo như thế nào — bằng cách gọi hàm postMessage của nó. Ở đây bạn chuyển một thông báo (một lần nữa, đây chỉ là dữ liệu) cho Worker. Tất nhiên, postMessage là một hàm không đồng bộ; bạn gọi nó và nó ngay lập tức trả về.

Bây giờ, hãy xem xét kịch bản lệnh Worker. Mã trong Liệt kê 2 là các nội dung của tệp ker.js từ Liệt kê 1.

Liệt kê2. Một kịch bản lệnh Worker
importScripts("utils.js");
var workerState = {};
onmessage = function(message){
     workerState = message.data;
      // do stuff with the message
    postMessage({responseXml: this.responseText});
}

Bạn có thể thấy rằng kịch bản lệnh Worker có hàm onmessage riêng của mình. Hàm này được gọi ra khi bạn gọi postMessage từ luồng chính. Dữ liệu mà bạn chuyển từ trang kịch bản lệnh được chuyển tới hàm postMessage trong đối tượng message. Bạn truy cập dữ liệu bằng cách lấy ra đặc tính data của đối tượng message. Khi bạn hoàn thành xử lý dữ liệu này trong kịch bản lệnh Worker, bạn gọi ra hàm postMessage để gửi dữ liệu trở lại luồng chính. Dữ liệu đó cũng có sẵn cho luồng chính bằng cách truy cập đặc tính dữ liệu của thông báo mà nó nhận được.

Cho đến nay bạn đã thấy những ngữ nghĩa tuy đơn giản, nhưng mạnh mẽ của các Web Worker. Tiếp theo, bạn sẽ thấy cách áp dụng Web Worker này để tăng tốc các ứng dụng Web di động. Trước khi làm điều đó, cần nói về việc hỗ trợ thiết bị. Cuối cùng, các Web Worker này là những ứng dụng Web di động và việc bàn đến các sự khác biệt về các khả năng giữa các trình duyệt là cần thiết để phát triển ứng dụng Web di động.

Hỗ trợ thiết bị

Bắt đầu từ Android 2.0, trình duyệt Android đã có hỗ trợ đầy đủ đặc tả Web Worker của HTML 5. Tại thời điểm viết bài này, hầu hết các thiết bị Android mới, bao gồm cả Motorola Droid rất phổ biến, đang gắn với Android 2.1. Ngoài ra, tính năng này được hỗ trợ hoàn toàn trong trình duyệt Mozilla Fennec có sẵn trên các thiết bị Nokia đang chạy hệ điều hành Maemo của nó, và trên các thiết bị Windows Mobile. Bị bỏ sót đáng chú ý ở đây là iPhone. iPhone OS phiên bản 3.1.3 và 3.2 (các phiên bản của hệ điều hành chạy trên iPad) vẫn chưa hỗ trợ các Web Worker. Tuy nhiên, tính năng này đã được hỗ trợ trên Safari, do đó sẽ chỉ còn là vấn đề thời gian trước khi nó xuất hiện trên trình duyệt Mobile Safari chạy trên iPhone. Dựa vào ưu thế của iPhone (đặc biệt là ở Mỹ), tốt nhất là không tin vào các Web Worker đang có và chỉ sử dụng chúng để tăng cường các ứng dụng Web di động của bạn khi bạn thấy có sự hiện diện của chúng. Với suy nghĩ này, hãy xem xét xem bạn có thể sử dụng các Web Worker như thế nào để làm cho các ứng dụng Web di động trở nên nhanh hơn.


Cải thiện hiệu năng với các Worker

Web Worker hỗ trợ trên các trình duyệt điện thoại thông minh tốt và đang dần cải thiện. Điều này không đề cập đến vấn đề: Khi nào bạn muốn sử dụng các Worker trong các ứng dụng Web di động? Câu trả lời rất đơn giản: bất cứ khi nào bạn cần phải làm điều gì đó mất thời gian dài. Một số ví dụ về Worker cho thấy các Worker đang được sử dụng để thực hiện các tính toán toán học mạnh, giống như đang tính số pi có mười ngàn chữ số. Điều hầu như không xảy ra là bạn luôn cần thực hiện một tính toán như vậy trên bất kỳ ứng dụng Web nào, lại càng không có trên một ứng dụng Web di động. Tuy nhiên, việc lấy ra dữ liệu từ tài nguyên ở xa là khá phổ biến, và đó là trọng tâm của ví dụ trong bài viết này.

Trong ví dụ này, bạn sẽ lấy ra một danh sách về Các giao dịch thay đổi mỗi ngày (Daily Deals) từ eBay. Danh sách các giao dịch có chứa thông tin ngắn gọn về mỗi thỏa thuận. Có thể thu được thông tin chi tiết hơn bằng cách sử dụng Shopping API (API mua sắm) của eBay. Bạn sẽ sử dụng các Web Worker để nạp trước thông tin bổ sung này trong khi người dùng duyệt danh sách các giao dịch để chọn một giao dịch cần quan tâm. Để truy cập vào tất cả các dữ liệu eBay này từ ứng dụng Web của bạn, bạn sẽ cần phải giải quyết chính sách gốc giống như của trình duyệt bằng cách sử dụng một proxy chung. Một Java servlet đơn giản được sử dụng cho proxy này. Nó có chứa mã cho bài viết này, nhưng nó không được hiển thị ở đây. Để thay thế, chúng ta hãy tập trung vào mã làm việc với các Web Worker. Liệt kê 3 cho thấy trang HTML cơ bản cho ứng dụng giao dịch.

Liệt kê 3. HTML của ứng dụng giao dịch
<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta name = "viewport" content = "width = device-width">
    <title>Worker Deals</title>
    <script type="text/javascript" src="common.js"></script>
  </head>
  <body onload="loadDeals()">
    <h1>Deals</h1>
    <ol id="deals">
    </ol>
    <h2>More Deals</h2>
    <ul id="moreDeals">
    </ul>
  </body>
</html>

Như bạn có thể thấy, đây là một đoạn mã HTML rất đơn giản; nó chỉ là một shell (trình bao). Bạn lấy ra dữ liệu và tạo giao diện người dùng bằng cách sử dụng JavaScript. Đây là thiết kế tối ưu cho các ứng dụng Web di động, vì nó cho phép tất cả mã và đánh dấu tĩnh được lưu trữ trong bộ nhớ truy cập nhanh trên thiết bị, và người dùng chỉ chờ dữ liệu từ máy chủ. Lưu ý rằng, trong Liệt kê 3, một khi phần thân đã được tải, bạn gọi hàm loadDeals ở nơi bạn tải dữ liệu ban đầu cho ứng dụng trong Liệt kê 4.

Liệt kê 4. Hàm loadDeals
var deals = [];
var sections = [];
var dealDetails = {};
var dealsUrl = "http://deals.ebay.com/feeds/xml";
function loadDeals(){
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function(){
        if (this.readyState == 4 && this.status == 200){
               var i = 0;
               var j = 0;
               var dealsXml = this.responseXML.firstChild;
               var childNode = {};
               for (i=0; i< dealsXml.childNodes.length;i++){
                   childNode = dealsXml.childNodes.item(i);
                   switch(childNode.localName){
                   case 'Item': 
                       deals.push(parseDeal(childNode));
                       break;
                   case "MoreDeals":
                       for (j=0;j<childNode.childNodes.length;j++){
                           var sectionXml= childNode.childNodes.item(j);
                           if (sectionXml && sectionXml.hasChildNodes()){
                               sections.push(parseSection(sectionXml));
                           }
                       }
                       break;    
                   default:
                       break;
                   }
               }
               deals.forEach(function(deal){
                   var entry = createDealUi(deal);
                   $("deals").appendChild(entry);
               });
               loadDetails(deals);
               sections.forEach(function(section){
                   var ui = createSectionUi(section);
                   $("moreDeals").appendChild(ui);
                   loadDetails(section.deals);
               });
        }
    };
    xhr.open("GET", "proxy?url=" + escape(dealsUrl));
    xhr.send(null);
}

Liệt kê 4 cho thấy hàm loadDeals, và các biến chung được sử dụng trong ứng dụng. Bạn sử dụng một mảng các giao dịch cộng với một mảng các phần. Đây là các nhóm bổ sung của các giao dịch có liên quan (ví dụ, Deals under $10 - các giao dịch dưới 10 Đô la). Ngoài ra còn có một bản đồ gọi là dealDetails có các khóa của nó sẽ là các Item ID (mà bạn sẽ nhận được từ dữ liệu các giao dịch), và các giá trị của nó là thông tin chi tiết hơn thu được từ Shopping API của eBay.

Việc đầu tiên bạn làm là thực hiện một cuộc gọi Ajax tới một proxy, để lần lượt gọi Daily Deals REST API của eBay. Cuộc gọi này cung cấp cho bạn danh sách các giao dịch như là một tài liệu XML. Bạn phân tích cú pháp tài liệu bằng hàm onreadystatechange của đối tượng XMLHttpRequest được sử dụng để thực hiện cuộc gọi Ajax. Bạn sử dụng hai hàm khác, parseDealparseSection, để phân tích cú pháp các nút XML trong đối tượng JavaScript dễ sử dụng hơn. Bạn có thể tìm thấy các hàm này trong ví dụ mã có thể tải về (xem Tải về), nhưng chúng chỉ là các hàm phân tích cú pháp XML tẻ nhạt vì vậy tôi đã không bao gồm chúng ở đây. Cuối cùng, sau khi phân tích cú pháp XML, bạn sử dụng hai hàm nữa, createDealUicreateSectionUi, để sửa đổi DOM. Khi bạn đã làm xong, giao diện người dùng trông giống như Hình 1.

Hình 1. Giao diện người dùng của Mobile Deals
Ảnh chụp màn hình của giao diện người dùng của Mobile Deals với các giao dịch mẫu, có một nút Show Details cho mỗi giao dịch

Nếu bạn quay trở lại Liệt kê 4, lưu ý rằng sau khi tải các giao dịch chính, bạn gọi hàm loadDetails cho mỗi một trong số các phần của các giao dịch. Trong hàm này, bạn tải các chi tiết bổ sung cho từng giao dịch bằng cách sử dụng Shopping API của eBay — nhưng chỉ khi trình duyệt này hỗ trợ các Web Worker. Liệt kê 5 cho thấy hàm loadDetails.

Liệt kê 5. Tìm nạp trước các thông tin chi tiết về các giao dịch
function loadDetails(items){
    if (!!window.Worker){
        items.forEach(function(item){
            var xmlStr = null;
            if (window.localStorage){
                xmlStr = localStorage.getItem(item.itemId);
            }
            if (xmlStr){
                var itemDetails = parseFromXml(xmlStr);
                dealDetails[itemDetails.id] = itemDetails;
            } else {
                var worker = new Worker("details.js");
                worker.onmessage = function(message){
                    var responseXmlStr =message.data.responseXml;
                    var itemDetails=parseFromXml(responseXmlStr);
                    if (window.localStorage){
                        localStorage.setItem(
                                        itemDetails.id, responseXmlStr);
                    }
                    dealDetails[itemDetails.id] = itemDetails;
                };
                    worker.postMessage(item.itemId);
            }
        });
    }
}

Trong loadDetails, trước tiên bạn kiểm tra hàm Worker trong phạm vi chung (đối tượng window). Nếu không có hàm này ở đó, thì bạn hoàn toàn không làm gì cả. Nếu có hàm này ở đó, thì trước tiên bạn kiểm tra localStorage cho XML với các thông tin chi tiết của giao dịch này. Đây là một chiến lược lưu trữ cục bộ trong bộ nhớ truy cập nhanh phổ biến cho các ứng dụng Web di động, và được mô tả chi tiết trong Phần 2 của loạt bài này (xem Tài nguyên để biết một liên kết).

Nếu đã tìm thấy XML này ở đó, thì bạn phân tích cú pháp nó bằng hàm parseFromXml và thêm các chi tiết vào đối tượng dealDetails. Nếu không tìm thấy XML này ở đó, thì sinh ra một Web Worker và gửi cho nó Item ID của giao dịch bằng cách sử dụng postMessage. Một khi Worker đó lấy ra dữ liệu và gửi trở lại luồng chính, bạn phân tích cú pháp XML, thêm kết quả này vào dealDetails, và lưu trữ XML trong localStorage. Liệt kê 6 cho thấy kịch bản lệnh Worker, details.js.

Liệt kê 6. Kịch bản lệnh Worker của các chi tiết giao dịch
importScripts("common.js");
onmessage = function(message){
    var itemId = message.data;
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function(){
        if (this.readyState == 4 && this.status == 200){
            postMessage({responseXml: this.responseText});
        }
    };
    var urlStr = generateUrl(itemId);
    xhr.open("GET", "proxy?url=" + escape(urlStr));
    xhr.send(null);
}

Kịch bản lệnh Worker khá đơn giản. Bạn sử dụng Ajax để gọi proxy, rồi proxy này lần lượt gọi Shopping API của eBay. Một khi bạn nhận được XML từ proxy, bạn gửi nó trở lại luồng chính bằng cách sử dụng một đối tượng JavaScript chính xác. Lưu ý rằng, ngay cả khi bạn có thể sử dụng XMLHttpRequest từ một Worker, mọi thứ sẽ trả về đặc tính responseText của nó, không bao giờ trả về đặc tính responseXml của nó. Đó là do không có trình phân tích cú pháp JavaScript DOM nào trong phạm vi bên trong kịch bản lệnh Worker. Lưu ý rằng hàm generateUrl bắt nguồn từ tệp common.js (trong Liệt kê 7). Bạn đã nhập khẩu common.js bằng hàm importScripts.

Liệt kê 7. Kịch bản lệnh được nhập khẩu bằng Worker
function generateUrl(itemId){
    var appId = "YOUR APP ID GOES HERE";
    return "http://open.api.ebay.com/shopping?callname=GetSingleItem&"+
        "responseencoding=XML&appid=" + appId + "&siteid=0&version=665"
            +"&ItemID=" + itemId;
}

Bây giờ bạn đã thấy cách đặt các chi tiết giao dịch (đối với các trình duyệt có hỗ trợ các Web Worker), hãy quay lại Hình 1 để tìm hiểu cách sử dụng giao diện này trong ứng dụng. Lưu ý rằng mỗi giao dịch có một nút Show Details (Hiển thị các chi tiết) ở bên cạnh. Nhấn chuột vào nút này để sửa đổi giao diện người dùng như trong Hình 2.

Hình 2. Các chi tiết giao dịch được hiển thị
ảnh chụp màn hình của các thông tin chi tiết của giao dịch có mô tả mặt hàng, các hành ảnh và giá cả của hai túi sách Golla (MP3, điện thọai di động, và camera)

Giao diện người dùng này được hiển thị khi bạn gọi hàm showDetails. Liệt kê 8 cho thấy hàm này.

Liệt kê 8. Hàm showDetails
function showDetails(id){
    var el = $(id);
    if (el.style.display == "block"){
        el.style.display = "none";
    } else {
        el.style.display = "block";
        if (!el.innerHTML){
            var details = dealDetails[id];
            if (details){
                var ui = createDetailUi(details);
                el.appendChild(ui);
            } else {
                var itemId = id;
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function(){
                    if (this.readyState == 4 && 
                                      this.status == 200){
                        var itemDetails = 
                                        parseFromXml(this.responseText);
                        if (window.localStorage){
                            localStorage.setItem(
                                              itemDetails.id, 
                                              this.responseText);
                        }
                        dealDetails[id] = itemDetails;
                        var ui = createDetailUi(itemDetails);
                        el.appendChild(ui);
                    }
                };
                var urlStr = generateUrl(id);
                xhr.open("GET", "proxy?url=" + escape(urlStr));
                xhr.send(null);                        
            }
        }
    }
}

Người ta chuyển cho bạn ID của giao dịch sẽ được hiển thị và bạn đặt ID vào hàm này để xem xem giao dịch có được hiển thị hay không. Khi lần đầu tiên được gọi, hàm này sẽ kiểm tra xem các thông tin chi tiết đã được lưu trữ trong bản đồ dealDetails chưa. Nếu trình duyệt hỗ trợ các Web Worker, thì các thông tin chi tiết này đã được lưu trữ ở đó và giao diện người dùng của nó được tạo ra và được thêm vào DOM. Nếu các thông tin chi tiết vẫn chưa được tải, hoặc nếu trình duyệt không hỗ trợ các Worker, thì bạn thực hiện một cuộc gọi Ajax để tải dữ liệu này. Đây là cách ứng dụng có thể làm việc tốt như nhau cho dù các Worker có mặt hay không. Điều này có nghĩa rằng, nếu các Worker được hỗ trợ, thì dữ liệu đã được tải và giao diện người dùng sẽ đáp ứng ngay lập tức. Nếu không có các Worker nào, giao diện người dùng vẫn tải, nhưng phải mất một vài giây.


Tóm tắt

Các Web Worker nghe như là một công nghệ mới lạ đối với các nhà phát triển Web. Nhưng, như bạn đã thấy trong bài viết này, chúng có những ứng dụng rất thiết thực. Điều này đặc biệt đúng cho các ứng dụng Web di động. Các Worker có thể được sử dụng để tìm nạp trước dữ liệu hoặc thực hiện các phép toán xảy ra trước (AOT) khác để cung cấp một giao diện người dùng sống động hơn nhiều. Điều này có thể đặc biệt đúng với các ứng dụng Web di động cần tải dữ liệu qua một mạng chậm tiềm ẩn. Hãy kết hợp điều này với các chiến lược lưu trữ trong bộ nhớ truy cập nhanh, và những người dùng của bạn sẽ bị ngạc nhiên bởi sự sống động của ứng dụng của bạn.


Tải về

Mô tảTênKích thước
Article source codeWorkers.zip8KB

Tài nguyên

Học tập

Lấy sản phẩm và công nghệ

Thảo luận

Bình luận

developerWorks: Đăng nhập

Các trường được đánh dấu hoa thị là bắt buộc (*).


Bạn cần một ID của IBM?
Bạn quên định danh?


Bạn quên mật khẩu?
Đổi mật khẩu

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Ở lần bạn đăng nhập đầu tiên vào trang developerWorks, một hồ sơ cá nhân của bạn được tạo ra. Thông tin trong bản hồ sơ này (tên bạn, nước/vùng lãnh thổ, và tên cơ quan) sẽ được trưng ra cho mọi người và sẽ đi cùng các nội dung mà bạn đăng, trừ khi bạn chọn việc ẩn tên cơ quan của bạn. Bạn có thể cập nhật tài khoản trên trang IBM bất cứ khi nào.

Thông tin gửi đi được đảm bảo an toàn.

Chọn tên hiển thị của bạn



Lần đầu tiên bạn đăng nhập vào trang developerWorks, một bản trích ngang được tạo ra cho bạn, bạn cần phải chọn một tên để hiển thị. Tên hiển thị của bạn sẽ đi kèm theo các nội dung mà bạn đăng tải trên developerWorks.

Tên hiển thị cần có từ 3 đến 30 ký tự. Tên xuất hiện của bạn phải là duy nhất trên trang Cộng đồng developerWorks và vì lí do an ninh nó không phải là địa chỉ email của bạn.

Các trường được đánh dấu hoa thị là bắt buộc (*).

(Tên hiển thị cần có từ 3 đến 30 ký tự)

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Thông tin gửi đi được đảm bảo an toàn.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=70
Zone=Nguồn mở
ArticleID=775546
ArticleTitle=Tạo các ứng dụng Web di động với HTML 5, Phần 4: Sử dụng các Web Worker để tăng tốc các ứng dụng Web di động của bạn
publish-date=06292010