Categories Lazy load Tối ưu JavaScript

Làm thế nào để trì hoãn tải nhiều file JavaScript cùng một lúc

trì hoãn tải nhiều javascript

Cách để trì hoãn tải nhiều file JavaScript cùng một lúc: Bài viết này sẽ mô tả cách trì hoãn tải ảnh, video, các nút mạng xã hội Twitter / Facebook / G+, và Mã phân tích (Analytics). Sử dụng cùng một phương thức bạn cũng có thể trì hoãn mọi thứ khác.

Trì hoãn tải JavaScript có thể là bước quan trọng để tăng tốc độ website. Tôi đã viết nhiều về trì hoãn tải ảnh, trì hoãn tải video, và cách trì hoãn JavaScript nhưng câu hỏi tôi hay nhận được nhất là:

Làm thế nào tôi có thể trì hoãn nhiều JavaScript chứ không phải chỉ mỗi một cái?

Một ví dụ về điều này là bạn có thể muốn tìm ra cách trì hoãn tải video, nhưng đồng thời cũng muốn trì hoãn tải các mã phân tích và/hoặc các nút mạng xã hội.

Hướng dẫn thực hành để trì hoãn tải nhiều JavaScript

Một trang web thông thường sẽ tải JavaScript từ nhiều nguồn như mã phân tích, nút mạng xã hội, mã của video và widget làm chậm hiển thị nội dung trong màn hình đầu tiên một cách đáng kể. Thường thì điều này sẽ làm tăng nhiều giây để tải trang. Nó không cần phải làm như thế.

Nói chung các đoạn mã JavaScript thường vẫn hay được yêu cầu tải là không cần thiết cho nội dung thuộc màn hình đầu tiên bởi vì nó không có nhiệm vụ gì đối với nội dung được nhìn thấy đầu tiên trên trang.

Một ví dụ điển hình là Google Analytics. Vì các mã phân tích không cần phải tải để hiển thị nội dung thuộc màn hình đầu tiên, tại sao chúng ta lại cho nó tải trước khi người dùng nhìn thấy trang? Một kẻ lén lút phổ biến khác là các nút bấm mạng xã hội. Nếu chúng không hiển thị ở trong màn hình đầu tiên, chẳng có lý do gì bạn làm chậm người dùng sớm nhìn thấy trang chỉ vì phải tải hàng loạt tài nguyên phụ thuộc vào chúng.

Trì hoãn nhiều thứ

Để trì hoãn nhiều thứ cho đến khi nội dung thuộc màn hình đầu tiên tải xong, yêu cầu bạn phải làm hai thứ:

  • Một file JavaScript ngoài được trì hoãn
  • Kết hợp các JavaScript lại với nhau

Đừng cảm thấy sợ hãi khi nghe các bước thực hiện này. Nó không phức tạp như nó có vẻ thế đâu, đặc biệt nếu bạn đã sẵn sàng trì hoãn tải các file JavaScript bên ngoài.

Chúng ta sẽ cùng giải thích chúng từng bước để bắt đầu thực hiện trì hoãn JavaScript.

Làm thế nào trì hoãn được JavaScript

Để trì hoãn hoàn toàn JavaScript khỏi sự kiện tải trang (để làm trang web tải nhanh hơn) chúng ta cần thêm một đoạn mã nhỏ JavaScript ở phía cuối của trang. Tôi sẽ làm một bản tóm tắt nhanh về điều đó trong bài viết này nhưng hướng dẫn sâu hơn thì tôi đã viết ở đây.

Đoạn mã phải được thêm vào trong file HTML ngay trước thẻ đóng <body> (gần vị trí cuối cùng của file HTML). Tôi đánh dấu nó màu đỏ để làm nổi bật tên của file JS bên ngoài:

<script type="text/javascript">
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "defer.js";
document.body.appendChild(element);
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>

Đoạn mã trên làm điều gì?

Đoạn mã này nói rằng cần phải đợi toàn bộ tài liệu tải xong, sau đó mới gọi để tải file ngoài “defer.js

trì hoãn tải javascript

Các hướng dẫn cụ thể

  1. Copy đoạn mã trên
  2. Paste đoạn mã vào trong HTML của bạn ngay trước thẻ đóng body (gần phía chân trang HTML)
  3. Thay “defer.js” bằng tên của file JS ngoài của bạn
  4. Đảm bảo rằng đường dẫn chính xác. Ví dụ: nếu bạn chỉ đưa đường dẫn là “defer.js”, thì file “defer.js” phải cùng thư mục với file HTML.

Okay, sau khi bạn đã thực hiện trì hoãn mọi thứ mà trang bạn tải, hãy xem chúng ta cần thêm điều gì vào file trì hoãn bây giờ.

Đặt đoạn mã nào vào tệp tin bên ngoài

Hãy bắt đầu với một tệp phổ biến là Google Analytics. Nếu bạn muốn trì hoãn Google Analytics, bạn phải đưa đoạn mã Google Analytics vào trong một file bên ngoài mà chúng ta gọi là “defer.js”. Dưới đây là một ví dụ về code mẫu…

(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXX-1', 'example.com');
ga('send', 'pageview');

Chắc chắn là đoạn mã analytic của bạn sẽ khác, nhưng điểm mấu chốt là bạn chỉ cần copy và paste đoạn mã vào trong “defer.js” và lưu nó lại mà thôi, rất đơn giản phải không.

Lần kế tiếp khi bạn tải hoặc làm mới trang, bạn sẽ để ý thấy rằng bạn đã trì hoãn tải Google Analytics để nó ra khỏi thời gian tải trang, làm cho trang của bạn tải nhanh hơn một chút. Điều này nghĩa là khi nội dung trang web của bạn tải, và ngay sau khi nó tải xong thì mới đến lượt đoạn mã Google Analytics tải xuống và như vậy bạn có cả đoạn mã phân tích nhưng vẫn làm người duyệt web vui vẻ khi có website tải nhanh hơn.

Điều đó thật tuyệt vời nhưng điểm mấu chốt của bài viết này là làm thế nào để trì hoãn nhiều thứ, chứ không phải một thứ. Chúng ta sẽ cùng thảo luận điều đó.

Trì hoãn nhiều JavaScript

Chúng ta vừa biết cách trì hoãn Google Analytics, nhưng chúng ta cũng muốn trì hoãn nút bấm của Google plus. Giờ thì sao?

Cái mà chúng ta phải làm được gọi là kết hợp (gộp) JavaScript hoặc được gọi vui là “copy và paste”.

Hãy xem file defer.js của chúng ta. Nó hiện chỉ có mã Google Analytics ở trong đó và trông giống thế này…

(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXX-1', 'example.com');
ga('send', 'pageview');

Giờ chúng ta muốn trì hoãn tải nút Google hoặc badge. Chúng ta sẽ copy và paste đoạn mã G+ vào trong file để làm nó trông giống như thế này…

//Google plus button / badge
(function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/platform.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })();
//Google analytics code
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXX-1', 'example.com');
ga('send', 'pageview');

Giờ chúng ta đã kết hợp các đoạn mã JavaScript. Nó thực sự chỉ là copy và paste mà thôi 🙂 Bây giờ tôi sẽ liệt kê ra một số mã script mà bạn có thể thêm vào file defer.js

Các đoạn mã này có thể được sử dụng bằng cách copy và paste vào trong file defer.js. Nếu bạn muốn sử dụng một trong số chúng hoặc tất cả chúng hoặc một số kết hợp nào đó, bạn chỉ cần copy và paste cái mà bạn muốn vào, nhấn enter để có khoảng trống, sau đó copy và paste cái khác.

Trì hoãn tải nút Google plus và badges

Đoạn mã này sẽ hoạt động cho bất cứ nút nào hoặc badge nào của Google plus…

(function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/platform.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })();

Lưu ý: Khi bạn nhận mã cho Google plus cho badge hoặc nút bấm, nó sẽ nói điều gì đó giống như thế này  “<!– Place this tag in your head or just before your close body tag. Đặt thẻ này vào trong thẻ head hoặc đơn giản chỉ cần đặt trước thẻ đóng body>” và <!– Place this tag where you want the share button to render. Đặt thẻ này ở vị trí mà bạn muốn nút chia sẻ được hiển thị/render –>”.

Khi bạn sử dụng đoạn mã trên để trì hoãn, bạn thực chất đang thay thế một phần của đoạn mã đang nói “<!– Place this tag in your head or just before your close body tag. Đặt thẻ này vào trong thẻ head hoặc đơn giản chỉ cần đặt trước thẻ đóng body –>”.  Bạn sẽ phải loại bỏ phần mã đấy của đoạn code ở trong trang vì file defer.js đã có rồi (hoặc nếu không, nó sẽ được tải lần nữa – và tốc độ web của bạn chẳng được cải thiện tí nào, nếu không muốn nói là sẽ bị chậm đi).

Trì hoãn tải các nút bấm Twitter

Trì hoãn tải các nút Twitter, rất giống nút Google plus yêu cầu đặt một phần đoạn mã vào trong fiel defer.js của chúng ta.

!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');

Lưu ý: Khi bạn vào Twitter và nhận đoạn mã nút bấm nó sẽ trông giống thế này…

<a href="https://twitter.com/share" class="twitter-share-button" data-via="yummyman">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>

Chúng tôi trì hoãn phần mã code có thẻ script bao quanh nó, điều đó có nghĩa là bạn phải không có phần mã thẻ này bất cứ đâu trên trang, hoặc nếu không bạn sẽ tải javascript đến hai lần liền.

Trì hoãn tải các nút Facebook

Trì hoãn tải nút Facebook, cũng giống như Google plus / Twitter yêu cầu thay thế đoạn code sau vào trong file defer.js.

(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.0";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));

Lưu ý: Khi bạn vào Facebook và lấy đoạn mã cho nút bấm, nó trông giống như thế này…

<div id="fb-root"></div>
<script>(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.0"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));</script>
<div class="fb-like" data-href="https://varvy.com/" data-layout="button_count" data-action="like" data-show-faces="false" data-share="false"></div>

Chúng tôi trì hoãn tải phần mã code mà có các thẻ script bao quanh nó, điều đó có nghĩa là bạn phải không có phần này với thẻ script bất kỳ đâu trên trang, hoặc bạn sẽ phải tải JavaScript hai lần liền. Bạn cũng không cần phần “<div id=”fb-root”></div>” khi bạn sử dụng phương thức này.

Trì hoãn tải ảnh

Việc trì hoãn tải ảnh đã được giải thích kỹ trong bài viết này. Đây là đoạn mã được lấy từ trang đó.

var imgDefer = document.getElementsByTagName('img'); for (var i=0; i<imgDefer.length; i++) { if(imgDefer[i].getAttribute('data-src')) { imgDefer[i].setAttribute('src',imgDefer[i].getAttribute('data-src')); } }

Lưu ý: đoạn mã này sẽ trì hoãn bất kỳ ảnh nào có thuộc tính “data-src” ở bên trong, và nó đã được giải thích kỹ trong bài viết tương ứng về trì hoãn tải ảnh tôi đã dẫn link ở trên.

Trì hoãn tải video

Về vấn đề trì hoãn tải video từ Youtube, Vimeo, vân vân, tôi đã giải thích kỹ trong bài viết này. Đây là đoạn mã được lấy từ trang đó.

var vidDefer = document.getElementsByTagName('iframe');
for (var i=0; i<vidDefer.length; i++) {
if(vidDefer[i].getAttribute('data-src')) {
vidDefer[i].setAttribute('src',vidDefer[i].getAttribute('data-src'));
}}

Lưu ý: đoạn mã này sẽ trì hoãn bất kỳ video nào có “data-src” ở bên trong và đã được giải thích trong bài viết trì hoãn video mà tôi có dẫn link ở trên.

Trì hoãn tải Google Analytics

Để trì hoãn Analytics, thêm đoạn mã mà Google cung cấp vào defer.js, ví dụ…

(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXX-1', 'example.com');
ga('send', 'pageview');

Lưu ý: Tôi có xu hướng giữ đoạn mã analytics ở vị trí cuối cùng trong file.

Các vấn đề có thể bạn gặp phải

Mỗi phương pháp trên đều hoạt động. Nếu một trong số chúng không hoạt động với bạn, hãy đảm bảo rằng bạn đã đọc kỹ các lưu ý trong mỗi phần.

Các ví dụ trên đều không có bất kỳ sự phụ thuộc nào (điều này nghĩa là chúng không cần dựa vào các file khác để làm việc).

Tuy nhiên một số đoạn mã JavaScript có thể là dạng phụ thuộc, vì thế nếu bạn cố gắng trì hoãn những thứ khác các ví dụ ở trên, bạn phải để ý những file phụ thuộc mà bạn có.

Một ví dụ điển hình là jQuery. Bạn có thể có JavaScript sử dụng jQuery hoặc một số thư viện khác, nếu đúng thực là bạn có, bạn có thể tiếp tục sử dụng phương thức này nhưng bạn cần đảm bảo rằng thứ tự của các đoạn mã tải xuống phải chính xác. Nếu bạn có file JavaScript sử dụng jQuery, cần đảm bảo là jQuery được tải trước tiên.

Trì hoãn jQuery

Trì hoãn jQuery thực sự có thể làm được, nhưng tôi không khuyến khích bạn làm điều đó. Nếu bạn muốn trì hoãn jQuery, chỉ cần copy và paste nó lên vị trí đầu tiên trong file defer.js, nhưng kích cỡ của nó sẽ thực sự lớn, và nói chung thường thì tôi không làm như vậy.

(Dịch từ bài viết: Defer multiple javascripts – Tác giả: Patrick Sexton – Website: Varvy)

Comments are closed.

Back to Top