Thứ Tư, ngày 03 tháng 3 năm 2010

Bí ẩn sau vụ load không đồng bộ của Google Analytics

VnTim™  ^-^ Tính năng load không đồng bộ của Google Analytics. Đây là tính năng khá hữu ích và được mong chờ, vì nó khiến cho script của Analytics được tải độc lập (song song) với việc tải trang, nghĩa là sẽ không ảnh hưởng tới việc load các thành phần khác của trang, và phần nào sẽ làm tăng tốc tải trang lên.

Có vẻ như tính năng load không đồng bộ này cũng khá hot, nên DISQUS (nền tảng comment cho blog, website mà Hỗn tạp Blog đang dùng) cũng bắt chước theo (tính năng này không được DISQUS thông báo trực tiếp hoặc tự động tích hợp vào phần cài đặt mà nó chỉ được đưa ra trong khu vực Help của họ, người dùng phải tự cài đặt bằng tay).

Nhưng mà thực sự thì tính năng này hoạt động thế nào? Có thực sự là nó mỹ miều như được miêu tả hay không? Bài viết này sẽ cùng xem qua 1 chút.

Phân tích code của Google Analytics


Trước tiên, lấy ví dụ của Google Analytics để làm cơ sở phân tích, nó có dạng sau:

01<script type="text/javascript">
02  var _gaq = _gaq || [];
03  _gaq.push(['_setAccount', 'UA-XXXXX-X']);
04  _gaq.push(['_trackPageview']);
05 
06  (function() {
07    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
08    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
09    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
10  })();
11</script>

Loại bỏ phần khai báo các tham số ở đầu, chúng ta coi phần hàm được thực thi. Hàm này có nhiệm vụ như sau:

- tạo ra 1 thẻ mới trong web (thẻ script)
- gán cho nó các thuộc tính type='text/javascript', async=true
- gán thuộc tính src dựa theo protocol của website, cụ thể là nếu website có protocol https thì lấy src=https://ssl.google-analytics.com/ga.js, còn nếu website có protocol http (loại website thông thường) thì lấy src=http://www.google-analytics.com/ga.js
- sau đó thì gắn script vào thẻ head. Trong trường hợp thất bại thì gắn vào thẻ body

Từ đó ta thấy thực tế thì script mà GA dùng vẫn là cái cũ (có nghĩa vẫn là 2 script http://www.google-analytics.com/ga.js hoặc https://ssl.google-analytics.com/ga.js). Có điều, họ sửa đổi cách gắn nó vào website. Một kiểu bình cũ rượu mới!

Thuộc tính async và chức năng của nó


Liệu có phải gắn lên thẻ head thì nó được load không đồng bộ? Không phải. Một script bình thường gắn vào thẻ head cũng sẽ được thực thi ngay lập tức. Mấu chốt của việc load không đồng bộ trong việc gắn theo kiểu mới này là Google bổ sung thuộc tính async cho thẻ script.

Để hiểu về thuộc tính async này, chúng ta coi qua đoạn trích dưới đây lấy từ website W3Schools:

The async attribute is "true": The script will be executed asynchrously with the rest of the page, so the script will be executed while the page continues the parsing.

The async attribute is "false", but the defer attribute is "true": The script will be executed when the page is finished with the parsing.

Both the async attribute and the defer attribute is "false": The script will be executed immediately, and the page will wait for the script to finish before continuing the parsing.

Có thể hiểu như sau:
- Nếu thuộc tính async có giá trị true thì script sẽ được thực thi không đồng bộ (song song) với việc load website
- Nếu thuộc tính async có giá trị false nhưng thuộc tính defer có giá trị true thì script sẽ được thực thi ngay sau khi website được load xong (dùng thuật ngữ parse thì đúng hơn)
- Nếu cả 2 thuộc tính asyncdefer đều false thì script sẽ thực thi ngay lập tức

(nếu 1 thuộc tính nào đó không được khai báo giá trị, thì mặc định sẽ là false)

Ở đây có "lòi ra" thêm thuộc tính defer nữa, nó có tác dụng kết hợp với thuộc tính async mà tạo ra các cách load 1 script như đã trình bày.

Thuộc tính async này chỉ có trong HTML5. Vì vậy không phải tất cả các trình duyệt đều hỗ trợ. Riêng đối với Firefox, theo trang web của Mozilla thì nó được hỗ trợ từ nhân Gecko 1.9.2 trở lên (tương ứng với Firefox 3.6). Hiện tại tôi cũng chưa tìm được danh sách các browser cùng các phiên bản tương ứng có hỗ trợ thuộc tính này, nếu ai biết, vui lòng comment giùm.

Trở lại với code của GA, ta thấy họ đã lợi dụng tính năng mới của HTML5, thêm thuộc tính async để load script của họ không đồng bộ với việc tải website. Điều đó cho thấy tính năng này cũng chỉ hoạt động trên phạm vi giới hạn nhỏ trong những trình duyệt hỗ trợ HTML5 mà thôi. Còn đối với các trình duyệt khác, nó lập tức được thực thi, không khác gì phiên bản cũ (có điều còn tồi tệ hơn vì nó được "khuyến khích" đặt ở đầu trang nên sẽ ảnh hưởng không nhỏ tới việc đợi chờ nó tải xong).

Cách làm 1 script load không đồng bộ


Nếu bạn đã hiểu cách load 1 script không đồng bộ thì bạn hoàn toàn có thể tự biến script của mình hoạt động như vậy, bắt chước theo cách mà Google đã làm. Ở đây giả sử bạn có script có đường dẫn là http://domain.com/script.js, thông thường, bạn load nó như sau:

1<script type="text/javascript" src="http://domain.com/script.js"></script>

Để load nó không đồng bộ, chỉ cần sửa 1 chút nhỏ thành như sau:

1<script type="text/javascript">
2  (function() {
3    var s = document.createElement('script');
4    s.type = 'text/javascript';
5    s.async = true;
6    s.src = 'http://domain.com/script.js';
7    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(s);
8  })();
9</script>

Đấy là cách bắt chước theo Google, nhưng có 1 cách làm đơn giản hơn rất nhiều, đó là khai báo trực tiếp thuộc tính async trong thẻ script:

1<script type="text/javascript" async="true" src="http://domain.com/script.js"></script>

Kết luận: Việc GA nâng cấp code của mình bằng cách sử dụng thuộc tính mới trong HTML5 cho thấy tính tiện dụng và hữu ích của nó. Tuy hiện tại chỉ có 1 số phiên bản của các trình duyệt hỗ trợ, nhưng trong tương lai không xa nó chắc chắn sẽ được dùng rộng rãi. Bài viết này hy vọng đem lại cho các bạn 1 cái nhìn đầy đủ hơn về 1 trong những tính năng của HTML5. Mong rằng sẽ nhận được các ý kiến đóng góp của các bạn.

VnTim™ Theo hontapblog

0 Comments:

Đăng nhận xét

» VnTim™ cảm ơn bạn đã đọc bài viết.
» Nếu có thắc mắc hay góp ý, bạn hãy để lại một nhận xét.
» Nếu thấy bài viết hay hãy chia sẻ với những người quanh bạn.
» Bạn có thể sử dụng một số thẻ HTML như <b>, <i>,<a>.
» Vui lòng đăng những nhận xét lịch sự và gõ tiếng Việt có dấu nếu có thể.
» Rất cảm ơn những comment thiện ý.

 

VnTim™ Trái Tim Việt Nam Copyright © 2010 VnTim™ Trái Tim Việt Nam