Khi nào JS được load trong HTML

Việc đặt một đoạn script JS trong HTML chắc hẳn đã quá quen thuộc với các bạn web developer, nhưng các bạn đã nắm hết được khi nào JS được chạy và khi nào JS chạy xong trong đoạn code HTML của bạn? Hôm nay tôi sẽ đi phân tích những cách load JS trong đoạn code HTML của bạn. Thông thường sẽ có 3 cách load source JS: load trước khi DOMContentLoaded, sau khi DOMContentLoaded và load song song với DOMContentLoaded.

The Events

DOMContentLoaded là sự kiện được triggered khi DOM(Document Object Model) được sẵn sàng. Điều này có nghĩa là API tương tác với content, style và structure của page sẵn sàng nhận request từ code của bạn. Điêu này có nghĩa là text, html, css đã sẵn sàng nhưng nó cũng không hoàn toàn đơn giản vậy. Phụ thuộc vào bản HTML version, browser version, và stylesheets tag có liên quan đến các scripts tags, có thể CSS chưa load hoàn toàn khi các sự kiện khác được kích hoạt. May mắn rằng chúng ta có cách an tòan và hiệu quả để đảm bảo rằng CSS được load trước tiên. Đơn giản đó là đặt stylesheets lên header và các external javascripts vào footer. Cách tiếp cận này buộc javscripts phải load sau khi các external stylesheets và các HTML body được load. Đơn giản là nếu bạn đặt javascripts vào footer, DOM của bạn sẽ load tất cả content, structure, style trước khi DOMContentLoaded được kích hoạt.

Loading javascript

Trước hết ta đặt vào body một loạt các vị trí mà Javascript có thể load để có thể so sánh với trình tự load của DOMContentLoaded:

<!DOCTYPE html>
<body>
  <script src="jquery.min.js"></script> 
  <script src="external.js"></script>      // console.log("external.js Loaded and Executed");
  <script type='text/javascript'>
      $.getScript('ajax.js');                     //console.log("ajax.js Loaded and Executed");
      $(document).ready(function(){
        console.log('DOMContent Loaded');
        $('head').append('<script src="dom.js"></script>');    //console.log("dom.js Loaded and Executed");
        $.getScript('dom_ajax.js');               // console.log("dom_ajax.js Loaded and Executed");
      });
      $(window).load(function(){
        console.log('Page Loaded (OnLoad)');
        $.getScript('page_ajax.js');            // console.log("page_ajax.js Loaded and Executed");
      });
  </script>
</body>

Kết quả log ra:

external.js Loaded and Executed
DOMContent Loaded
dom.js Loaded and Executed
Page Loaded (OnLoad)
ajax.js Loaded and Executed
dom_ajax.js Loaded and Executed
page_ajax.js Loaded and Executed

Từ kết quả log ra ta có thể bước đầu nhận định:

  • External javascript (external.js) được loaded trước khi DOMContentLoaded.
  • External javascript được inserted vào HTML trong khi DOMContentLoaded callback (dom.js) được loaded trước OnLoad.
  • AJAX requests không làm delay DOMContentLoaded or OnLoad, bất kể chúng được khởi tạo khi nào (ajax.js, dom_ajax.js and page_ajax.js).

Trước khi DOMContentLoaded

Đầu tiên cần nhớ rằng cả javascripts inline và external javascripts đều được loaded và thực thi ngay lập tức bất kể DOM ready hay là đang trong quá trình loaded. Điều này có vẻ hiển nhiên, nhưng chúng ta cần phải execute đoạn code này trước khi DOMContentLoaded để có thể móc được vào event. Chúng ta không nên thao tác với DOM trong đoạn javascript của mình lúc này, bởi vì DOM chưa được load xong. Bạn nên thiết lập callbacks và thoát ra để phần còn lại của page được load nhanh chóng.

Sau khi DOMContentLoaded

Các đoạn scripts (dom.js) được thực thi khi DOM sẵn sàng được thao tác. Nơi bạn có thể đặt bất kỳ đoạn code nào thao tác với DOM, và đoạn javascript sẽ được thực thi trước khi page được hiển thị. Đây là điều tốt và thời điểm thích hợp, bởi các yếu tố style và DOM sẽ không bị dịch chuyển hay nhảy lung tung khi người dùng đã nhìn thấy page được loaded.

Trước khi OnLoad

Các đoạn scripts (ajax và bất kỳ đoạn JS nào được gọi callback bằng window.load) được thực hiện sau khi page đã load xong và user đã có thể xem được toàn bộ document. Đây là nơi tuyệt vời để đặt các đoạn script dài mà không làm thay đổi trực quan của trang. Ví dụ như các thư viện báo cáo, analysist.

Điều khiển việc load javascript

Load theo cách mặc định

Ở trên ta đã nói về cách thức load của JS một cách mặc định khi được đặt vào từng đoạn HTML của page như đã đề cập ở trên.

Điều khiển với deferasync

  • Dùng async:
<script src="demo_async.js" async></script>

Khi có async, đoạn script sẽ chạy không đồng bộ khi nó(async) xuất hiện.

  • Dùng defer:
<script src="demo_defer.js" defer></script>

Đoạn script sẽ không chạy cho đến khi sau khi page được loaded xong.

Một số chú ý:

  • async, defer có giá trị dạng Boolean.
  • async là điểm mới của HTML5 so với HTML 4.1
  • async được support trên Chrome, Safari, Opera, Firefox (>=3.6), IE (>=10.0)
  • defer được support trên Chrome, Safari, Opera(>=15.0), Firefox(>=3.6), IE(>=10.0)

Kết luận

Trên đây là một số tổng kết nhỏ của tôi về việc load Javascript trong thẻ HTML, mong được các bạn đóng góp thêm. 😃

All Rights Reserved