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ợ trình duyệt gốc cho các thành phần và kỹ thuật mà chúng ta đã đạt được thông qua các thư viện JavaScript cho đến nay. Việc sử dụng các tính năng này (nếu có) có thể mang 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 nghiên cứu hiệu suất xuất sắc mà bạn đã thấy trên trang web Hiệu suất vượt trội của Yahoo hoặc tài liệu về Tốc độ trang và trang web Hãy làm cho web nhanh hơn của Google. Thay vào đó, tôi sẽ tập trung vào cách sử dụng HTML5 và CSS3 ngày nay để giúp ứng dụng web của bạn trở nên thích ứng hơn.

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

Mặc dù cookie đã được dùng để theo dõi dữ liệu người dùng riêng biệt trong nhiều năm, nhưng cookie cũng có những hạn chế 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 đề yêu cầu HTTP. Điều này có thể ảnh hưởng đáng kể đến thời gian phản hồi, đặc biệt là trong các 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 vì cookie.

Bạn có thể dùng hai đối tượng bộ nhớ web này để lưu giữ 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 đến máy chủ qua mọi yêu cầu HTTP. Họ có một API sẽ giúp bạn loại bỏ cookie. Dưới đâ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 hiệu ứng chuyển đổi CSS thay vì ảnh động JavaScript

Hiệu ứng chuyển đổi CSS mang đến cho bạn hiệu ứng chuyển đổi hình ảnh hấp dẫn giữa hai trạng thái. Bạn có thể chuyển đổi hầu hết các thuộc tính kiểu, chẳng hạn như thao tác với 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 hiệu ứng chuyển đổi vào trạng thái bộ chọn giả như :hover hoặc từ các 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, các lớp này 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 thao tác bật/tắt các lớp tothelefttotheright, bạn có thể di chuyển hộp xung quanh. So sánh lượng mã này với lượng mã của một thư viện ảnh động JavaScript. Rõ ràng là số byte được gửi đến trình duyệt í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, các hiệu ứng chuyển đổi hình ảnh này sẽ diễn ra 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ì các lượt truy cập máy chủ

Cơ sở dữ liệu SQL webIndexedDB giới thiệu cơ sở dữ liệu cho phía máy khách. Thay vì sử dụng mẫu phổ biến là đă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 các yêu cầu HTTP là mục tiêu chính của tất 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ể tiết kiệm nhiều lượt truy cập thông qua XHR hoặc bài đăng biểu mẫu trở lại máy chủ. localStoragesessionStorage có thể được sử dụng trong một số trường hợp, chẳng hạn như ghi lại tiến trình gửi biểu mẫu và được thấy là 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ó một thành phần lưới dữ liệu hoặc hộp thư đến có hàng trăm thư, thì việc lưu trữ dữ liệu cục bộ trong cơ sở dữ liệu sẽ giúp bạn tiết kiệm được các lượt truy cập HTTP khi người dùng muốn tìm kiếm, lọc hoặc sắp xếp. Danh sách bạn bè hoặc tính năng tự động hoàn thành văn bản nhập có thể được lọc theo từng thao tác nhấn phím, mang lại trải nghiệm người dùng thích ứng hơn nhiều.

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

Nhiều phương thức bổ sung đã được thêm vào nguyên mẫu Mảng trong JavaScript 1.6. Các tính năng này hiện có trong 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 for thông thường như: for (var i = 0, len = arr.length; i &lt; len; i++). Tính năng 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 đã quen dùng trong một thời gian. JSON gốc nhanh và an toàn hơn nhiều so với việc sử dụng tập lệnh bên ngoài. JSON gốc đã 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 không chỉ nhanh hơn các mã tương đương JS viết tay dài mà còn có thể chính xác hơn. Về mặt kỹ thuật, không có phần bổ sung JavaScript nào trong số này là HTML5, nhưng chúng thuộc phạm vi của các công nghệ sắp ra mắt gần đây.

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

Hai năm trước, WordPress đã sử dụng Google Gears để thêm một tính năng có tên là WordPress Turbo. Về cơ bản, tính năng này lưu nhiều tài nguyên được sử dụng trong bảng điều khiển quản trị vào bộ nhớ đệm cục bộ, giúp tăng tốc truy cập tệp vào các tài nguyên đó. Chúng ta có thể tái hiện hành vi đó bằng applicationCache của HTML5 và cache.manifest. Bộ nhớ đệm ứng dụng có một lợi thế nhỏ 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, trình duyệt có thể tối ưu hoá tài nguyên đó rất nhiều, thậm chí có thể lưu trước các tài nguyên đó trước khi bạn sử dụng. Hãy xem cấu trúc cơ bản của trang web là một 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 ứng dụng, bạn có thể coi HTML là một loạt các mẫu thuần tuý, lưu mã đánh dấu vào bộ nhớ đệm thông 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 cách hoạt động của ứng dụng tin tức gốc trên iPhone hoặc Android.

Mẹo 6: Bật tính năng 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 hình ảnh 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 diễn ra mượt mà hơn. 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. (Tính năng này đã có trong Safari dành cho thiết bị di động từ lâu.) Chromium vừa thêm các phép biến đổi 3D và tính năng tăng tốc phần cứng cho Windows, hai nền tảng còn lại sẽ sớm được hỗ trợ.

Tính năng tăng tốc GPU chỉ hoạt động trong một số điều kiện khá hạn chế, nhưng các phép biến đổi 3D và độ mờ ảnh động là những cách phổ biến nhất để kích hoạt nút chuyển. Một cách hơi hack nhưng không gây khó chịu để bật tính năng này là:

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

Tuy nhiên, không có gì đảm bảo. :) Khi tính năng tăng tốc phần cứng được hỗ trợ và bật, hiệu ứng dịch, xoay, điều chỉnh tỷ lệ và độ mờ của ảnh động chắc chắn sẽ mượt mà hơn nhờ tính năng kết hợp GPU. Chúng sẽ có lợi ích là được xử lý trực tiếp trên GPU và không yêu cầu vẽ lại nội dung 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 nặng về CPU, Trình chạy web sẽ phân phối

Worker có hai lợi ích đáng kể: 1) Chúng nhanh. 2) Trong khi các tác vụ này đang diễn ra, trình duyệt vẫn phản hồi. Hãy xem Bản trình bày HTML5 về Worker đang hoạt động. Một số trường hợp có thể sử dụng Worker trên web:

  • Định dạng văn bản của 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ý các mảng lớn

Mẹo 8: Thuộc tính và loại dữ liệu đầu vào của Biểu mẫu HTML5

HTML5 giới thiệu một nhóm loại dữ liệu đầu vào mới, nâng cấp nhóm text, passwordfile để bao gồm search, tel, url, email, datetime, date, month, week, time, datetime-local, number, rangecolor. Các trình duyệt hỗ trợ các tính năng này khác nhau, trong đó Opera triển khai nhiều tính năng nhấ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ư trình chọn ngày hoặc bộ chọn màu). 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 những thao tác phổ biến này. Ngoài các loại, một số tính năng hữu ích đã được thêm vào các trường nhập thông thường. placeholder đầu vào cung cấp văn bản mặc định sẽ xoá khi bạn nhấp vào các văn bản đó và autofocus đặt tiêu điểm con trỏ khi 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 được đưa vào 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 để kiểm thử dữ liệu đầu vào; với 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 bản nâng cấp lớn không chỉ về khả năng đọc nguồn mà còn giúp giảm đáng kể lượng JavaScript cần thiết. Xin nhắc lại, bạn có thể sử dụng tính 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ó tính năng hỗ trợ gốc cho các tính năng hiện có. Việc sử dụng các tiện ích gốc tại đây có nghĩa là bạn không cần gửi javascript và css nặng để kéo các tiện ích này, giúp 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. Để thử một số tính năng nâng cao đầu vào này, hãy xem Bản trình bày về HTML5.

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

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

  • Chuyển màu tuyến tính và chuyển màu xuyên tâm
  • Border-radius cho góc bo tròn
  • Box-shadow cho bóng đổ và hiệu ứng phát sáng
  • RGBA cho độ mờ alpha
  • Biến đổi để xoay
  • Mặt nạ CSS

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

Mẹo 10: Sử dụng WebSocket để phân phối nhanh hơn với băng thông thấp hơn so với XHR

WebSockets được thiết kế để đáp ứng sự phổ biến ngày càng tăng của Comet. Hiện tại, việc sử dụng WebSockets thực sự có nhiều ưu điểm hơn so với mô hình Comet qua XHR.

WebSocket có khung rất nhẹ, do đó băng thông mà nó tiêu thụ thường nhẹ hơn so với XHR. Một số báo cáo cho thấy số byte được gửi qua mạng giảm 35%. Ngoài ra, khi số lượng lớn hơn, sự khác biệt về hiệu suất khi phân phối thông báo sẽ rõ ràng hơn; XHR đã được ghi lại trong thử nghiệm này với thời gian tổng hợp dài hơn WebSockets 3500%. 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 hơn 3 đến 5 lần so với qua 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.

Tài nguyên khác

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