Các phương pháp hay nhất để có ứng dụng web nhanh hơn bằng HTML5

Giới thiệu

Phần lớn HTML5 hướng đến việc cung cấp tính năng hỗ trợ của trình duyệt gốc cho các thành phần và kỹ thuật mà chúng tôi đã đạt được thông qua các thư viện JavaScript cho đến nay. Nếu sử dụng các tính năng này, thì bạn có thể đem lại trải nghiệm nhanh hơn nhiều cho người dùng. Trong hướng dẫn này, tôi sẽ không tóm tắt kết quả nghiên cứu về hiệu suất tuyệt vời mà bạn đã thấy trên trang web Hiệu suất vượt trội của Yahoo, tài liệu về Tốc độ trang của Google và trang web Hãy giúp trang web hoạt động nhanh hơn. Thay vào đó, tôi sẽ tập trung vào việc làm cách nào để HTML5 và CSS3 sử dụng hiện nay có thể giúp ứng dụng web của bạn phản hồi nhanh hơn.

Mẹo 1: Sử dụng bộ nhớ web thay cho cookie

Mặc dù cookie đã được sử dụng để theo dõi dữ liệu người dùng riêng biệt trong nhiều năm, nhưng cookie vẫn có những nhược điểm nghiêm trọng. Lỗi lớn nhất là tất cả dữ liệu cookie của bạn đều được thêm vào mọi tiêu đề của yêu cầu HTTP. Điều này có thể dẫn đến tác động có thể đo lường được đối với thời gian phản hồi, đặc biệt là trong XHR. Vì vậy, phương pháp hay nhất là giảm kích thước cookie. Trong HTML5, chúng ta có thể làm tốt hơn thế: sử dụng sessionStoragelocalStorage thay cho cookie.

Bạn có thể dùng hai đối tượng lưu trữ trên web này để duy trì dữ liệu người dùng ở phía máy khách trong suốt phiên hoặc vô thời hạn. Dữ liệu của họ cũng không được chuyển tới máy chủ thông qua mọi yêu cầu HTTP. Có một API giúp bạn loại bỏ cookie được. Đây là cả hai API, sử dụng cookie làm phương án dự phòng.

// if localStorage is present, use that
if (('localStorage' in window) && window.localStorage !== null) {

  // easy object property API
  localStorage.wishlist = '["Unicorn","Narwhal","Deathbear"]';

} else {

  // without sessionStorage we'll have to use a far-future cookie
  //   with document.cookie's awkward API :(
  var date = new Date();
  date.setTime(date.getTime()+(365*24*60*60*1000));
  var expires = date.toGMTString();
  var cookiestr = 'wishlist=["Unicorn","Narwhal","Deathbear"];'+
                  ' expires='+expires+'; path=/';
  document.cookie = cookiestr;
}

Mẹo 2: Sử dụng chuyển đổi CSS thay vì hoạt ảnh JavaScript

Chuyển đổi CSS cung cấp cho bạn hiệu ứng chuyển đổi trực quan hấp dẫn giữa hai trạng thái. Hầu hết các thuộc tính kiểu đều có thể chuyển đổi, chẳng hạn như điều khiển bóng văn bản, vị trí, nền hoặc màu sắc. Bạn có thể sử dụng các lượt chuyển đổi thành trạng thái bộ chọn giả như :hover hoặc từ biểu mẫu HTML5, :invalid:valid (ví dụ về trạng thái xác thực biểu mẫu). Tuy nhiên, chúng mạnh mẽ hơn nhiều và có thể được kích hoạt khi bạn thêm bất kỳ lớp nào vào một phần tử.

div.box {
  left: 40px;
  -webkit-transition: all 0.3s ease-out;
     -moz-transition: all 0.3s ease-out;
       -o-transition: all 0.3s ease-out;
          transition: all 0.3s ease-out;
}
div.box.totheleft { left: 0px; }
div.box.totheright { left: 80px; }

Bằng cách thêm nút bật/tắt các lớp của tothelefttotheright, bạn có thể di chuyển hộp. So sánh số lượng mã này với số lượng mã của thư viện ảnh động JavaScript. Rõ ràng, số lượng byte được gửi tới trình duyệt sẽ ít hơn nhiều khi sử dụng ảnh động dựa trên CSS. Ngoài ra, với tính năng tăng tốc cấp GPU, quá trình chuyển đổi hình ảnh này sẽ mượt mà nhất có thể.

Mẹo 3: Sử dụng cơ sở dữ liệu phía máy khách thay vì trả về máy chủ

Cơ sở dữ liệu web SQLIndexedDB giới thiệu cơ sở dữ liệu cho phía máy khách. Thay vì đăng dữ liệu lên máy chủ thông qua XMLHttpRequest hoặc gửi biểu mẫu, bạn có thể tận dụng các cơ sở dữ liệu phía máy khách này. Việc giảm yêu cầu HTTP là mục tiêu chính của tất cả các kỹ sư hiệu suất, vì vậy việc sử dụng các yêu cầu này làm kho dữ liệu có thể lưu nhiều chuyến đi qua XHR hoặc biểu mẫu các bài đăng gửi lại máy chủ. Bạn có thể sử dụng localStoragesessionStorage trong một số trường hợp, chẳng hạn như trong việc ghi lại tiến trình gửi biểu mẫu. Chúng tôi nhận thấy rằng tốc độ này nhanh hơn đáng kể so với các API cơ sở dữ liệu phía máy khách. Ví dụ: nếu bạn có thành phần lưới dữ liệu hoặc hộp thư đến với hàng trăm thư, việc lưu trữ dữ liệu cục bộ trong cơ sở dữ liệu sẽ lưu cho bạn các phiên trả về HTTP khi người dùng muốn tìm kiếm, lọc hoặc sắp xếp. Hệ thống có thể lọc danh sách bạn bè hoặc nội dung tự động hoàn thành khi nhập văn bản mỗi khi nhấn phím, giúp mang lại trải nghiệm phản hồi nhanh hơn cho người dùng.

Mẹo 4: Việc cải tiến JavaScript đem lại những lợi thế đáng kể về hiệu suất

Nhiều phương thức bổ sung đã được thêm vào protoype Array trong JavaScript 1.6. Các phương thức này hiện có trên hầu hết các trình duyệt, ngoại trừ IE. Ví dụ:

// Give me a new array of all values multiplied by 10.
[5, 6, 7, 8, 900].map(function(value) { return value * 10; });
// [50, 60, 70, 80, 9000]

// Create links to specs and drop them into #links.
['html5', 'css3', 'webgl'].forEach(function(value) {
  var linksList = document.querySelector('#links');
  var newLink = value.link('http://google.com/search?btnI=1&q=' + value + ' spec');
  linksList.innerHTML +=  newLink;
});


// Return a new array of all mathematical constants under 2.
[3.14, 2.718, 1.618].filter(function(number) {
  return number < 2;
});
// [1.618]


// You can also use these extras on other collections like nodeLists.
[].forEach.call(document.querySelectorAll('section[data-bucket]'), function(elem, i) {
  localStorage['bucket' + i] = elem.getAttribute('data-bucket');
});

Trong hầu hết các trường hợp, việc sử dụng các phương thức gốc này sẽ mang lại tốc độ nhanh hơn đáng kể so với vòng lặp thông thường như: for (var i = 0, len = arr.length; i &lt; len; i++). Quá trình phân tích cú pháp JSON gốc (thông qua JSON.parse()) sẽ thay thế tệp json2.js mà chúng ta đã sử dụng trong một thời gian. JSON gốc nhanh hơn và an toàn hơn nhiều so với việc sử dụng tập lệnh bên ngoài và nó đã có trong IE8, Opera 10.50, Firefox 3.5, Safari 4.0.3 và Chrome. String.trim gốc là một ví dụ điển hình khác về việc không chỉ nhanh hơn các mã JS tương đương mà còn có khả năng chính xác hơn. Không có bổ sung JavaScript nào trong số này là HTML5 về mặt kỹ thuật, nhưng chúng nằm trong phạm vi các công nghệ mới ra mắt gần đây.

Mẹo 5: Sử dụng tệp kê khai bộ nhớ đệm cho các trang web đang hoạt động, chứ không chỉ cho ứng dụng ngoại tuyến

Hai năm trước, WordPress đã sử dụng Google Bánh răng để thêm một tính năng có tên là Wordpress Turbo. Về cơ bản, giải pháp này đã lưu vào bộ nhớ đệm nhiều tài nguyên được dùng trong bảng điều khiển quản trị cục bộ, tăng tốc độ truy cập tệp vào những tài nguyên đó. Chúng ta có thể sao chép hành vi đó bằng applicationCache của HTML5 và cache.manifest. Bộ nhớ đệm của ứng dụng có một chút lợi thế so với việc đặt tiêu đề Expires; vì bạn tạo một tệp khai báo cho biết các tài nguyên tĩnh có thể lưu vào bộ nhớ đệm, nên các trình duyệt có thể tối ưu hoá phần lớn những việc đó, thậm chí có thể lưu trước chúng vào bộ nhớ đệm trước khi bạn sử dụng. Xem cấu trúc cơ bản của trang web làm mẫu. Bạn có dữ liệu có thể thay đổi nhưng HTML xung quanh dữ liệu đó thường vẫn khá nhất quán. Với bộ nhớ đệm của ứng dụng, bạn có thể coi HTML của mình là một loạt mẫu thuần tuý, lưu mã đánh dấu vào bộ nhớ đệm qua cache.manifest, sau đó phân phối JSON qua mạng để cập nhật nội dung. Mô hình này rất giống với mô hình của một ứng dụng tin tức gốc trên iPhone hoặc Android.

Mẹo 6: Bật chế độ tăng tốc phần cứng để nâng cao trải nghiệm hình ảnh

Trong các trình duyệt hàng đầu, nhiều thao tác trực quan có thể tận dụng tính năng tăng tốc ở cấp GPU, giúp các thao tác hình ảnh có tính linh động cao hoạt động mượt mà hơn nhiều. Tính năng tăng tốc phần cứng đã được công bố cho Firefox MinefieldIE9, đồng thời Safari đã thêm tính năng tăng tốc ở cấp độ phần cứng trong phiên bản 5. (Ứng dụng này đã có trong Mobile Safari sớm hơn nhiều.) Chromium vừa bổ sung các tính năng biến đổi 3D và tăng tốc phần cứng cho Windows, cùng với hai nền tảng khác sẽ sớm ra mắt.

Tính năng tăng tốc GPU chỉ hoạt động trong một tập hợp các điều kiện khá hạn chế, nhưng biến đổi 3D và độ mờ động là những cách phổ biến nhất để làm hỏng công tắc. Một cách để bật chế độ này hơi kiểu cách nhưng không phô trương là:

.hwaccel {  -webkit-transform: translateZ(0); }

Tuy nhiên, không có gì đảm bảo. :) Với tính năng tăng tốc phần cứng được hỗ trợ và bật, tính năng dịch động, xoay, chia tỷ lệ và độ mờ chắc chắn sẽ mượt mà hơn khi kết hợp GPU. Các lớp này sẽ có lợi là được xử lý trực tiếp trên GPU và không yêu cầu vẽ lại nội dung của lớp. Tuy nhiên, mọi thuộc tính ảnh hưởng đến bố cục của trang vẫn sẽ tương đối chậm.

Mẹo 7: Đối với các thao tác tiêu tốn nhiều CPU, Web Worker phân phối

Web Workers có hai lợi ích đáng kể: 1) Chúng có tốc độ nhanh. 2) Trong khi họ thực hiện các tác vụ của bạn, trình duyệt vẫn phản hồi. Hãy tìm hiểu Bản trình bày trang trình bày HTML5 dành cho worker trong thực tế. Bạn có thể sử dụng Web Workers:

  • Định dạng văn bản của một tài liệu dài
  • Làm nổi bật cú pháp
  • Xử lý hình ảnh
  • Tổng hợp hình ảnh
  • Xử lý mảng lớn

Mẹo 8: Các loại dữ liệu nhập và thuộc tính của Biểu mẫu HTML5

HTML5 giới thiệu một tập hợp các loại đầu vào mới, nâng cấp tập hợp text, passwordfile của chúng tôi để bao gồm search, tel, url, email, datetime, date, month, week, time, datetime-local, number, rangecolor. Trình duyệt hỗ trợ cho những thay đổi này khác nhau, với Opera triển khai hầu hết tại thời điểm này. Với tính năng phát hiện tính năng, bạn có thể xác định xem trình duyệt có hỗ trợ gốc hay không (và sẽ cung cấp giao diện người dùng như công cụ chọn ngày hoặc công cụ chọn màu) và nếu không, bạn có thể tiếp tục sử dụng các tiện ích JS để thực hiện các tác vụ phổ biến này. Ngoài các loại, chúng tôi đã thêm một số tính năng hữu ích vào các trường nhập dữ liệu thông thường. Dữ liệu đầu vào placeholder cung cấp văn bản mặc định sẽ bị xoá khi bạn nhấp vào chúng và autofocus tập trung con nháy vào việc tải trang để bạn có thể tương tác ngay với trường đó. Xác thực dữ liệu đầu vào là một tính năng khác trong HTML5. Việc thêm thuộc tính required có nghĩa là trình duyệt sẽ không cho phép gửi biểu mẫu cho đến khi bạn điền vào trường đó. Ngoài ra, thuộc tính pattern cho phép bạn chỉ định một biểu thức chính quy tuỳ chỉnh cho dữ liệu đầu vào cần kiểm tra; trong đó các giá trị không hợp lệ sẽ chặn việc gửi biểu mẫu. Cú pháp khai báo này là một nâng cấp lớn không chỉ về khả năng đọc nguồn mà còn giảm đáng kể JavaScript cần thiết. Xin nhắc lại, bạn có thể sử dụng chức năng phát hiện tính năng để phân phát giải pháp dự phòng nếu không có hỗ trợ gốc cho các giải pháp này. Sử dụng các tiện ích gốc ở đây có nghĩa là bạn không cần phải gửi nhiều javascript và css cần thiết để kéo các tiện ích này ra, tăng tốc độ tải trang và có thể cải thiện khả năng phản hồi của tiện ích. Để dùng thử một số tính năng nâng cao cho dữ liệu đầu vào này, hãy xem bản trình bày HTML5.

Mẹo 9: Sử dụng hiệu ứng CSS3 thay vì yêu cầu các hình ảnh lớn

CSS3 cung cấp nhiều khả năng tạo kiểu mới thay thế cho việc sử dụng hình ảnh để thể hiện thiết kế hình ảnh một cách chính xác. Việc thay thế hình ảnh 2k bằng 100 byte CSS là một chiến thắng lớn, chưa kể bạn đã xóa một yêu cầu HTTP khác. Bạn có thể tìm hiểu một số thuộc tính sau:

  • Chuyển màu tuyến tính và dạng hình tròn
  • Bán kính đường viền cho các góc bo tròn
  • Bóng đổ cho bóng đổ và toả sáng
  • RGBA cho độ mờ alpha
  • Biến đổi để xoay
  • Mặt nạ CSS

Ví dụ: có thể tạo các nút trau chuốt rất đẹp thông qua hiệu ứng chuyển màusao chép nhiều hiệu ứng khác không có hình ảnh. Khả năng hỗ trợ trình duyệt cho hầu hết các trình duyệt này là rất chắc chắn, và bạn có thể sử dụng một thư viện như Modernizr để phát hiện các trình duyệt không hỗ trợ các tính năng nhằm sử dụng hình ảnh trong trường hợp dự phòng.

Mẹo 10: WebSockets để phân phối nhanh hơn với băng thông ít hơn XHR

WebSockets được thiết kế để đáp ứng sự phổ biến ngày càng tăng của Comet. Thực sự có nhiều lợi thế khi sử dụng WebSockets ngay bây giờ, thay vì sử dụng mô hình comet so với mô hình XHR.

WebSocket có khung hình rất nhẹ nên băng thông mà giao diện này tiêu thụ thường ít hơn so với XHR. Một số báo cáo cho thấy số byte được gửi qua đường dây giảm 35%. Ngoài ra, với khối lượng lớn hơn, sự khác biệt về hiệu suất khi gửi tin nhắn càng rõ ràng; XHR đã được ghi lại trong bài kiểm thử này với thời gian tổng hợp lâu hơn 3500% so với WebSockets. Cuối cùng, Ericcson Labs xem xét hiệu suất của WebSocket và nhận thấy thời gian ping qua HTTP lớn gấp 3 đến 5 lần so với WebSocket do các yêu cầu xử lý lớn hơn. Họ kết luận rằng giao thức WebSocket rõ ràng phù hợp hơn với các ứng dụng theo thời gian thực.

Nguồn thông tin khác

Để đưa ra các đề xuất về hoạt động đo lường và hiệu suất, bạn nên sử dụng các tiện ích Tốc độ trangYSlow của Firefox. Ngoài ra, Speed Tracer dành cho ChromeDynaTrace Ajax dành cho IE cung cấp cấp độ chi tiết hơn về việc ghi nhật ký phân tích.