Tải javascript không đồng bộ là gì. Chúng tôi đưa ra các yêu cầu cho kịch bản. Tập lệnh có dựa trên DOM được phân tích cú pháp đầy đủ không

Lý do viết bài này là vì đã hơn một lần tôi nhận thấy việc chèn mã nút vào một trang dịch vụ khác nhau(ví dụ: VKontakte, Facebook, Twitter, Odnoklassniki) đã dẫn đến tốc độ tải và hiển thị trang chậm lại đáng kể. Đây là trường hợp sử dụng kết nối javascript bên ngoài của các dịch vụ xã hội này.
Nếu chúng ta sử dụng tĩnh đơn giản nút đồ họa, không có vấn đề gì, bởi vì Đây là mức tối thiểu của đồ họa và tập lệnh được đặt cục bộ (bạn có thể xem ví dụ về cách triển khai tại đây http://pervushin.com/social-button-for-blog.html). Nhưng chúng ta chỉ nhìn thấy các biểu tượng xã hội. dịch vụ, không có số liệu thống kê (có bao nhiêu người “thích” trang của chúng tôi). Những thứ kia. nếu muốn xem số liệu thống kê, chúng ta sẽ phải kết nối các tập lệnh bên ngoài. Và ở đây, điều cần lưu ý là chúng ta đã kết nối bao nhiêu nút trong số này thì trình duyệt buộc phải tải xuống rất nhiều tập lệnh bên ngoài, tức là. Cái này kết nối bổ sung tới các máy chủ bên ngoài.

Để hiển thị điều gì sẽ xảy ra nếu có tập lệnh trong phần trên trang, tôi đề xuất xem xét một số ví dụ thử nghiệm. Tôi sẽ sử dụng FireFox 3.6 và FireBug.

Vì thế:
1) Trang đơn giản nhất với một tệp kiểu, hai tập lệnh và ba hình ảnh:













Và đây là sơ đồ tải cho nó:

Xin lưu ý rằng tất cả hình ảnh chỉ được tải sau khi tệp javascript dài nhất được tải.
Tôi đã cố tình tải dummy_css.css và dummy_js.js khá lâu. Đó chỉ là hai tập tin:

dummy_css.php

html,nội dung(
lề:0;
phần đệm: 0;
}
.img_container(
lề:0 tự động;chiều rộng:500px;
}

dummy_js.php


var param=1;

Vì vậy, bạn có thể thấy rằng tệp js chặn tải tất cả các đồ họa khác.

2) Mọi thứ gần như giống nhau, ngoại trừ dummy_js. js được tải từ máy chủ bên ngoài:

Tình huống tương tự như lần trước:

3) Hãy thử hoán đổi các tệp css và js trong phần đầu (css hiện đứng sau js):







Hãy nhìn vào sơ đồ tải:

Js vẫn chặn tải hình ảnh, bất kể nó được tải từ máy chủ nào.

4) Hãy tăng thời gian tải css lên 4 giây (mã html như trong trường hợp N3):

5) Một trường hợp thú vị khác: css được đặt trước js, nhưng css mất nhiều thời gian hơn để tải















Ở đây css đã chặn việc tải hình ảnh...

6) Di chuyển một js vào trong< body>
















Có thể thấy rằng dummy_ js. js chỉ chặn tải hình ảnh thứ ba, nằm trong mã html sau nó. Nhưng nếu css tải lâu hơn thì nó sẽ chặn tải đồ họa. Không khó để tưởng tượng rằng việc cắm vào các tập lệnh bên ngoài có thể làm chậm quá trình tải và hiển thị trang rất nhiều, đặc biệt nếu máy chủ từ xa Vì lý do nào đó phải mất một thời gian dài để phản hồi.

Đặt các tập lệnh bên ngoài trước

Điều gì ngay lập tức gợi ý... Tất cả các tập lệnh có tải không quan trọng đối với trang phải được đặt ngay trước thẻ đóng. Nhưng điều này có thể được thực hiện đối với những tập lệnh trong đó tất cả logic là bên trong và không có lệnh gọi bên ngoài nào từ Mã HTML. Nếu từ mã html, một số hàm được gọi từ các tập lệnh chưa được tải thì những tình huống đó phải được xử lý theo cách đặc biệt, bởi vì bạn cần theo dõi quá trình tải xuống.

Nhưng có một vấn đề khác, hãy để tôi giải thích bằng một ví dụ:




$("img").click(function() (
cảnh báo($(this).attr("src"));
});
});






Nếu js trước tải lâu thì click vào ảnh sẽ lâu hết chỗ kịch bản này sẽ không dẫn tới điều gì cả, bởi vì... $(document).ready() sẽ chỉ hoạt động sau khi js được tải đầy đủ. Vì vậy, nếu có một số logic trên các trang liên quan đến việc xử lý sự kiện thì phương pháp này không phù hợp.

Vì vậy, điều cần thiết là một cách để tải tập lệnh mà không bị chặn...

Tạo async.js:



script.src = "dummy_js.js";


và kết nối nó:











$(document).ready(function() (
$("img").click(function() (
cảnh báo($(this).attr("src"));
});
});






Nếu lệnh gọi async.js được đặt trong , chứ không phải trước , thì sơ đồ sẽ trông như thế này:

Nhưng nếu việc đặt async.js vào mã vẫn thuận tiện hơn, thì bạn nên thay đổi một chút nội dung của async.js:

$(document).ready(function() (
var script = document.createElement("script");
script.src = "dummy_js.js";
document.getElementsByTagName("head") .appendChild(script);
}
);

Vì vậy, vấn đề tải không đồng bộ đã được giải quyết nhưng vấn đề đồng bộ hóa việc tải các tập lệnh bên ngoài và mã sử dụng chúng vẫn còn bỏ ngỏ. Hãy xem xét nó trong thực tế, kết nối các nút mạng xã hội.

Với sự gia tăng tốc độ kết nối Internet và sự gia tăng sức mạnh không chỉ của máy tính để bàn mà còn thiêt bị di động Các trang web ngày càng nặng hơn. Số lượng và kích thước của các tệp được kết nối ngày càng tăng: tệp JavaScript, tập tin css, hình ảnh, tiện ích trang web của bên thứ ba, iframe. TRÊN khoảnh khắc này Các chi tiết cụ thể về cách hoạt động của trình duyệt là khi tải tệp js, quá trình hiển thị sẽ bị chặn cho đến khi tập lệnh được thực thi. Trình duyệt hiện đại V. lý lịch sẽ phân tích tài liệu và tải xuống các tập lệnh và kiểu, nhưng việc hiển thị sẽ bị chặn. So sánh thông số mạngcác trình duyệt khác nhau có thể được xem tại browserscope.org. Chúng tôi không thể loại bỏ hoàn toàn việc chặn, nhưng chúng tôi có thể tối ưu hóa các phần máy chủ và máy khách của ứng dụng để việc chặn kết xuất mất ít thời gian nhất.

Giải pháp phía máy chủ:
- Giảm kích thước của tập tin được chuyển
- Sử dụng CDN
- Đặt các tập tin tĩnh trên miền riêng biệt hoặc dưới một miền, do đó làm tăng số lượng kết nối trình duyệt đồng thời.
- Cho phép nén các tập tin được chuyển (gzip)

Giải pháp dành cho phía khách hàng:
- Giảm số lượng yêu cầu.
- Tệp bộ đệm ở phía máy khách bằng cách sử dụng tiêu đề Hết hạn và Etags.
- Sử dụng CDN có sẵn công khai (Google CDN, Yandex CDN). Vì vậy, có khả năng tệp từ CDN công cộng đã được lưu trữ trong bộ đệm của trình duyệt.

Một cách để tối ưu hóa tốc độ tải trang là tải tệp không đồng bộ, điều này không chặn hiển thị.

Tập lệnh tải không đồng bộ JavaScript:

(function() ( var s = document.createElement("script"); s.type = "text/javascript"; s.async = true; s.src = " URL tệp"; document.getElementsByTagName("head").appendChild(script); ))();

Nếu cần thực thi JavaScript sau khi tải toàn bộ trang, bao gồm nội dung, hình ảnh, tệp kiểu và tập lệnh bên ngoài thì sự kiện onload cần phải được thêm vào trình tải.

Nếu (window.addEventListener) ( window.addEventListener("load", async_load, false); ) khác nếu (window.attachEvent) ( window.attachEvent("onload", async_load); )

Tập lệnh tải không đồng bộ JavaScript có tính đến sự kiện tải (function() ( function async_load())( var s = document.createElement("script"); s.type = "text/javascript"; s.async = true; s .src = "URL tệp";document.getElementsByTagName("head").appendChild(script); ) if (window.addEventListener) ( window.addEventListener("load", async_load, false); ) else if (window.attachEvent ) ( window .attachEvent("onload", async_load); ) ))();

Nhưng đây là trường hợp cá biệt khi cần tải xuống một tệp duy nhất. Thông thường trong thực tế nhiều tập tin được kết nối.

Tập lệnh tải không đồng bộ nhiều tệp JavaScript plug-in (function() ( function async_load())( [ "URL_file_1.js", "URL_file_2.js", "URL_file_3.js" ].forEach(function(src) ( var s = document.createElement ("script"); s.type = "text/javascript"; s.async = true; s.src = src; document.getElementsByTagName("head").appendChild(script); )); ) if (window. addEventListener) ( window.addEventListener("load", async_load, false); ) else if (window.attachEvent) ( window.attachEvent("onload", async_load); ) ))();

Nhưng có một điểm trừ trong cách triển khai này - các tập lệnh sẽ được tải theo thứ tự ngẫu nhiên và theo đó, chúng sẽ được thực thi ngẫu nhiên theo thời gian. Tập lệnh tải không đồng bộ này lý tưởng nếu Thực thi JavaScript các tệp không phụ thuộc vào nhau và không phụ thuộc vào DOM. Nếu không, việc sử dụng nó có thể dẫn đến lỗi trên trang hoặc kết quả thực thi không mong muốn. Để thực hiện tuần tự nhưng tải xuống không đồng bộ, bạn cần chỉ định async=false, khi đó các tệp sẽ được tải xuống theo thứ tự ngẫu nhiên nhưng được thực hiện lần lượt.

HTML5. Tải không đồng bộ JavaScript

Tiêu chuẩn HTML 5 hỗ trợ tải JavaScript không đồng bộ. Điều này có thể được thực hiện bằng cách thêm từ khóa không đồng bộ hoặc trì hoãn. Ví dụ:

Một tập lệnh được kết nối với thuộc tính defer sẽ được thực thi mà không làm xáo trộn thứ tự thực thi so với các tập lệnh khác và việc thực thi tập lệnh đó sẽ xảy ra sau khi trang được tải và phân tích cú pháp đầy đủ, nhưng trước khi DOMContentLoaded được gọi.

Một tập lệnh được kết nối với thuộc tính async sẽ được thực thi càng sớm càng tốt sau khi được tải đầy đủ, nhưng nó không đợi tài liệu được phân tích cú pháp trước khi tải đối tượng cửa sổ. Các trình duyệt không đảm bảo rằng các tập lệnh sẽ được thực thi theo đúng thứ tự mà chúng được kết nối.

Thư viện để tải JavaScript không đồng bộ

RequireJS là một mô-đun tải JavaScript. Được tối ưu hóa cho các trình duyệt nhưng có thể sử dụng được trong các môi trường khác như Node, Rhino.

Require(["script"], function(script) ( console.log("bắt đầu sau khi tải script.js"); ));

extsrc.js là một thư viện chạy các tập lệnh sẽ được thực thi sau khi trang được tải và hiển thị cho người dùng. Hoạt động chính xác với document.write.

yepnope.js - cho phép tải các tệp JavaScript và CSS không đồng bộ.

Yepnope([ "script.js", "style.css"]);

Cách dễ dàng để tải xuống Tập lệnh JavaScript

Hóa ra trong thực tế, việc tải các tập lệnh JavaScript trên nhiều trình duyệt tối ưu mà không chặn hiển thị là rất khó và đôi khi là không thể. Hầu hết cách tối ưuđược thêm vào cuối tài liệu trước khi đóng thẻ cơ thể. Do những hạn chế các trình duyệt khác nhau và chính HTML, tùy chọn tải không chặn hiển thị như vậy có thể được coi là đơn giản nhất.

Lưu ý: Dưới đây là bản dịch một bài viết của Steve Souders (tác giả của những lời khuyên nổi tiếng của Yahoo! về hiệu suất của máy khách) “Coupling async scripts”. Steve phân tích hành vi tải của tệp JavaScript và đề xuất một số cách để vượt qua thuộc tính chặn của chúng. Những bình luận của tôi dưới đây được in nghiêng.

Phần lớn công việc của tôi là ở Gần đâyđược dành cho việc tải các tập lệnh bên ngoài không đồng bộ. Nếu các tập lệnh được tải theo thứ tự thông thường (), thì chúng sẽ chặn việc tải tất cả các thành phần trang khác ( V. phiên bản mới nhấtĐây không phải là trường hợp của Firefox và Safari, nhưng Chúng ta đang nói về, về cơ bản, khoảng 70% người dùng IE) và chặn hiển thị toàn bộ phần của trang nằm bên dưới lệnh gọi tới các tập lệnh trong mã HTML. Điều này có thể được nhìn thấy trên trang thử nghiệm, chúng tôi đặt các tập lệnh bên dưới ví dụ, sử dụng sáng tạo năng động các đối tượng sau khi sự kiện kết hợp window.onload được kích hoạt) ngăn chặn hành vi này của trình duyệt, giúp tăng tốc độ tải trang.

Vấn đề duy nhất khi tải tập lệnh không đồng bộ là sự tương tác của chúng với nội bộ ( nội tuyến) tập lệnh trang ( cũng như với các tập lệnh bên ngoài khác), sử dụng các biến được xác định trong tập lệnh bên ngoài. Nếu một tập lệnh bên ngoài được tải không đồng bộ mà không có bất kỳ kiến ​​thức nào về mã nội bộ của trang HTML thì rất có thể ( và nó sẽ xảy ra trong hầu hết các trường hợp) khi một số biến không được xác định tại thời điểm sử dụng chúng. Vì vậy, cần đảm bảo rằng các tập lệnh bên ngoài được tải không đồng bộ và các tập lệnh trang bên trong được liên kết: các tập lệnh bên trong không được thực thi cho đến khi tập lệnh không đồng bộ sẽ không tải hoàn toàn.

Có một số ( tiêu chuẩn) cách kết nối các tập lệnh được tải không đồng bộ với mã JavaScript khác:

  • tải cửa sổ. Việc thực thi mã JavaScript nội bộ có thể được gắn với sự kiện tải cửa sổ. Nó rất dễ sử dụng nhưng một số tập lệnh có thể được thực thi sớm hơn.
  • onreadystatechange trong tập lệnh. Mã nội bộ có thể được liên kết với các sự kiện onreadystatechange và/hoặc onload. (Cần phải sử dụng cả hai tùy chọn để bao quát mọi thứ trình duyệt phổ biến.) Trong trường hợp này sẽ có nhiều mã hơn, nó sẽ phức tạp hơn, nhưng sẽ có sự đảm bảo rằng nó sẽ được thực thi ngay sau khi tải các tệp bên ngoài tương ứng.
  • Cuộc gọi tích hợp. Các tập lệnh bên ngoài có thể được sửa đổi để bao gồm lệnh gọi đến một đoạn mã nhỏ ở cuối. Đoạn mã này sẽ gọi hàm tương ứng từ mã nội bộ. Điều này thật tuyệt nếu các tập lệnh bên ngoài và bên trong được phát triển bởi cùng một nhóm. Nhưng trong trường hợp sử dụng sự phát triển của bên thứ ba, điều này sẽ không mang lại tất cả sự linh hoạt cần thiết để liên kết các tập lệnh bên ngoài với mã nội bộ.

Trong bài viết này, tôi đồng thời (không có ý định chơi chữ!) đề cập đến hai vấn đề: cách các tập lệnh không đồng bộ tăng tốc độ tải trang và cách bạn có thể kết hợp các tập lệnh không đồng bộ và tập lệnh nội bộ bằng cách sử dụng phiên bản sửa đổi của trình tải từ John Resig ( bởi jQuery) là mẫu thẻ tập lệnh kép. Một minh họa cho điều này là công việc sắp xếp kết quả UA Profiler gần đây của tôi. Tôi đã làm điều đó bằng cách sử dụng tập lệnh sắp xếp của Stuart Langridge. Trong khoảng 5 phút tôi đã có thể thêm đoạn script của anh ấy vào một trang để sắp xếp bảng kết quả. Chỉ cần thêm một chút thời gian, tôi đã có thể làm cho tập lệnh này tải không đồng bộ và tăng tốc độ tải trang lên hơn 30% bằng cách sử dụng kỹ thuật ghép tập lệnh không đồng bộ.

Cuộc gọi tập lệnh thông thường

Ban đầu tôi đã thêm tập lệnh sắp xếp của Stuart Langridge vào trang UA Profiler theo cách thông thường(thông qua ), điều này có thể được nhìn thấy trong biến thể có lệnh gọi tập lệnh thông thường. Sơ đồ tải được thể hiện trong hình. 1.

Cơm. 1. Sơ đồ nạp script trong trường hợp thông thường.

Mặc dù việc sắp xếp dữ liệu trong bảng có hiệu quả nhưng nó không làm tôi vui hơn vì tốc độ tải trang bị chậm lại. Trong bộ lễ phục. 1 cho thấy rõ cách phiên bản tập lệnh của tôi (có tên là Sorttable-async.js) chặn tất cả các yêu cầu HTTP khác trên trang (cụ thể là mũi tên-right-20x9.gif), điều này làm chậm quá trình tải trang. Tất cả các biểu đồ tải được thực hiện bằng Fireorms 1.3 beta. Trong phiên bản Firebug này, dòng màu đỏ hiển thị sự kiện tải. (Và đường màu xanh tương ứng với sự kiện domcontentloaded.) Đối với phiên bản có lệnh gọi tập lệnh thông thường, sự kiện onload sẽ kích hoạt ở tốc độ 487 mili giây.

Tập lệnh Sorttable-async.js không cần thiết để hiển thị trang ban đầu: các cột chỉ có thể được sắp xếp sau khi các cột đó đã được hiển thị. Tình huống này (các tập lệnh bên ngoài không được sử dụng để hiển thị trang ban đầu) là ứng cử viên số 1 cho việc triển khai tải không đồng bộ. Tùy chọn tải tập lệnh không đồng bộ kết nối tập lệnh này bằng các phương thức DOM để tạo thẻ tập lệnh mới:

var script = document.createElement("script"); script.src = "sorttable-async.js"; script.text = "sorttable.init()"; // điều này sẽ được giải thích trong phần tiếp theo document.getElementsByTagName("head").appendChild(script);

Sơ đồ tải HTTP để tải tập lệnh không đồng bộ được hiển thị trong Hình. 2. Điều đáng chú ý là cách tiếp cận không đồng bộ ngăn chặn hành vi chặn: Sorttable-async.js và Arrow-right-20x9.gif được tải song song. Điều này làm giảm thời gian tải tổng thể xuống còn 429 ms.

Cơm. 2. Sơ đồ nạp script trong trường hợp không đồng bộ

Mẫu tập lệnh kép của John Resig

Cho phép bạn tăng tốc độ tải trang, nhưng trong trường hợp này vẫn còn chỗ cần cải thiện. Theo mặc định, tập lệnh sắp xếp sẽ tự gọi chính nó bằng cách đính kèm Sorttable.init() vào trình xử lý sự kiện onload của tập lệnh. Một số cải tiến hiệu suất ( và giảm mã) có thể đạt được bằng cách gọi Sorttable.init() bên trong thẻ script để gọi nó ngay sau khi tải tập lệnh bên ngoài (được kết nối qua src). Trong trường hợp này, tôi đang sử dụng một hàm duy nhất làm "API", nhưng tôi đoán trường hợp này minh họa một mẫu có thể mở rộng tối đa cho phép bạn sử dụng mô-đun bên ngoài không có bất kỳ giả định nào về nó sử dụng thêm (tình huống kinh điển về việc sử dụng logic JavaScript từ các nhà phát triển bên ngoài).

Tôi đã mô tả ba phương pháp để kết nối mã nội bộ với việc tải các tập lệnh bên ngoài không đồng bộ: tải cửa sổ, onreadystatechange cho tập lệnh và một trình xử lý được tích hợp trong tập lệnh. Thay vào đó, tôi sử dụng kỹ thuật của John Resig - mẫu thẻ script kép. John mô tả cách liên kết các tập lệnh nội bộ với việc tải tập tin bên ngoài theo cách sau:

jQuery("p").addClass("đẹp");

Trong trường hợp này, mã bên trong chỉ kích hoạt sau khi tải ( và khởi tạo) tập lệnh bên ngoài đã kết thúc. Cách tiếp cận liên kết tập lệnh này có một số lợi thế rõ ràng:

  • đơn giản hơn: một thẻ script thay vì hai
  • minh bạch hơn: kết nối giữa mã bên trong và mã bên ngoài rõ ràng hơn
  • an toàn hơn: nếu tập lệnh bên ngoài không tải, mã bên trong sẽ không được thực thi, điều này sẽ ngăn các lỗi liên quan đến biến không xác định xuất hiện

Đây là một mẫu tuyệt vời để tải các tập lệnh bên ngoài một cách không đồng bộ. Tuy nhiên, để sử dụng nó, chúng ta sẽ phải thay đổi cả mã bên trong và tệp bên ngoài. Đối với mã nội bộ, tôi phải thêm dòng thứ ba đã được đề cập ở trên, dòng này hiển thị thuộc tính script.text. Để hoàn tất quá trình lắp ghép, bạn cần thêm Sorttable-async.js vào cuối:

var scripts = document.getElementsByTagName("script"); var cntr = scripts.length; while (cntr) ( var curScript = scripts; if (-1 != curScript.src.indexOf("sorttable-async.js")) ( eval(curScript.innerHTML); break; ) cntr--; )

Mã này đi qua tất cả các tập lệnh trên trang, tìm thấy khối bắt buộc, nó sẽ tự tải (trong trường hợp này là tập lệnh có src chứa Sorttable-async.js). Sau đó, nó thực thi mã được thêm vào tập lệnh (trong trường hợp này là Sorttable.init()) và do đó gọi chính nó. (Lưu ý nhỏ: mặc dù khi tải tập lệnh, văn bản trong tập lệnh đã được thêm bằng cách sử dụng thuộc tính văn bản, nó được truy cập bằng thuộc tính InnerHTML. Điều này là cần thiết để đảm bảo khả năng tương thích giữa nhiều trình duyệt.) Bằng cách sử dụng tính năng tối ưu hóa này, chúng tôi có thể tải tệp tập lệnh bên ngoài mà không chặn việc tải các tài nguyên khác và thực thi mã nội bộ được liên kết với tập lệnh này càng nhanh càng tốt.

Cũng cần lưu ý rằng kỹ thuật được mô tả chỉ có thể thay thế cho việc sửa đổi trực tiếp tập lệnh bên ngoài. Nếu không thể sửa đổi như vậy, chúng tôi chỉ có thể sử dụng cài đặt kiểm tra tải trong một khoảng thời gian:

var _on_ready_execution = setInterval(function() ( if (typeof urchinTracker === function) ( urchinTracker(); clearInterval(_on_ready_execution); ) ), 10);

Cách tiếp cận này đã được mô tả trong cuốn sách “Ép xung trang web của bạn”, tuy nhiên, nó đòi hỏi phải tải thêm bộ xử lý cho kiểm tra liên tục tập lệnh được yêu cầu đã sẵn sàng và không hoạt động nếu tệp bên ngoài không có sẵn: quá trình kiểm tra tiếp tục chạy.

Tuy nhiên, trong trường hợp kiểm tra theo khoảng thời gian, chúng ta hoàn toàn không cần sửa đổi tệp bên ngoài, nhưng trong trường hợp sử dụng kép thẻ script thì điều này đơn giản là cần thiết. Việc kiểm tra khoảng thời gian có thể được cải thiện nếu sau một thời gian trôi qua (ví dụ: 5-10 giây), bạn khởi động lại quá trình tải xuống tệp bên ngoài (thay đổi thẻ tập lệnh gốc bằng tham số GET duy nhất) và sau vài lần khởi động lại không thành công, hãy dừng lại tải xuống hoàn toàn (có thể với một số thì có thông báo lỗi).

Tải chậm

Thời gian tải tổng thể có thể được giảm hơn nữa bằng cách sử dụng " lười tải» script (tải nó một cách linh hoạt như một phần của trình xử lý sự kiện onload). Một ví dụ về hành vi này nằm trên trang có

Bây giờ tôi sẽ kể cho bạn nghe về một cách thú vị, điều này sẽ giúp bạn tăng tốc trang web WordPress của mình bằng cách tải các tập lệnh song song.

Nó dùng để làm gì?

Mọi thứ đều rất đơn giản. Một trang web hiện đại là một tập hợp của nhiều loại tập lệnh, thẻ, đoạn mã, kiểu, phông chữ và mọi thứ khác. Như bạn hiểu, càng có nhiều “quà tặng” thì trang web của bạn sẽ tải càng lâu. Đối với JavaScript, đó lại là một vấn đề khác. Bạn đã bao giờ nhận thấy tình trạng lộn xộn như vậy khi trang dường như đã được tải nhưng tab lại hiển thị rằng trang vẫn đang tải? Điều này xảy ra khi một tập lệnh cụ thể chưa được tải đến cuối. Sẽ không sao đâu, đôi khi trang hoàn toàn không hoạt động cho đến khi tập lệnh tương tự, dường như không quan trọng lắm được tải. Và người dùng của bạn có thể không đủ kiên nhẫn.

Khái niệm này hoàn toàn trái ngược với tải đồng bộ, đó là một tập lệnh thông thường như:

Cuộc gọi không đồng bộ kịch bản trông như thế này:

Giờ đây, tập lệnh sẽ không buộc người dùng của bạn phải đợi tải đầy đủ, mọi thứ sẽ diễn ra song song.

Làm thế nào để tự động hóa quá trình?

Rõ ràng là nếu bạn kết nối các tập lệnh theo cách thủ công và không có nhiều tập lệnh, thì bạn có thể thực hiện việc này theo cách thủ công, chỉ bằng cách thêm thuộc tính thích hợp vào mã cuộc gọi. Nhưng làm thế nào bạn có thể tự động hóa việc này nếu, chẳng hạn, bạn có WordPress với một loạt các tập lệnh, ngoài ra, còn được gọi tự động?

Tìm tệp tin.php quen thuộc của chủ đề của bạn và chèn đoạn mã sau vào đó (ví dụ: ở cuối):

// hàm javascript không đồng bộ wcs_defer_javascripts ($url) ( if (FALSE === strpos($url, ".js")) return $url; if (strpos($url, "jquery.js")) return $url; return "$url" async="async"; ) add_filter("clean_url", "wcs_defer_javascripts", 11, 1);

Phần kết luận

Tôi có thể thêm gì vào kết luận? Tập lệnh này có thể không phù hợp với tất cả mọi người, vì ai biết bạn đã kết nối tập lệnh nào, vì vậy hãy cài đặt và thử nghiệm. Không thể có nhược điểm nào đối với tập lệnh như vậy, ngoại trừ có lẽ không tương thích với một trang web cụ thể do tính chất cụ thể của nó. Đây là một bước nhỏ khác hướng tới việc tối ưu hóa lớn cho trang web của bạn.

Tính không đồng bộ trong javascript là một quy tắc theo đó các khối mã JS được trình duyệt xử lý song song với việc tải DOM - tức là. cấu trúc trang web hoặc sau khi DOM được tải.

Mã JS, như bạn biết, được đặt giữa các tệp . Trong trường hợp này, mã có thể được chứa cả trong HEAD của tài liệu và trong BODY - trong bất kỳ phần nào của tài liệu. JavaScript cũng có thể được tải từ các tên miền khác.

Thông thường JS được đặt ở cuối trang một cách chính xác vì lý do nó cần thời gian nhất định- tải trang bị treo - DOM không thể tải vì nó đang chờ tập lệnh javascript hoàn tất thực thi.

Nếu tập lệnh được viết có lỗi hoặc được tải từ máy chủ bên ngoài nhưng không khả dụng thì trang sẽ không bao giờ tải. Nếu mã JS được tối ưu hóa kém và mất nhiều thời gian để thực thi, trang sẽ tải đến điểm tập lệnh được kết nối - sau đó quá trình tải sẽ dừng cho đến khi tập lệnh hoàn tất. Điều này có thể được người truy cập trang web nhận thấy, đặc biệt nếu anh ta đang sử dụng kết nối Internet chậm.

Thông thường, khách truy cập vào một trang web có trang đã ngừng tải giữa chừng sẽ rời đi mà không đợi tập lệnh hoạt động xong. Do đó, sự chậm trễ là điều không mong muốn.

Để khắc phục tình trạng này, tùy chọn không đồng bộ được cung cấp, cho phép bạn tải JS không đồng bộ. Cấu trúc tài liệu khi sử dụng tài liệu và tất cả các thành phần trang sẽ không đợi tập lệnh thực thi hoàn tất.

Tập lệnh được khởi tạo, trang sẽ tiếp tục tải ngay cả khi tập lệnh chưa hoàn thành công việc của nó. Một số chức năng của trang có thể không hoạt động chính xác (nếu có lỗi trong javascript) nhưng nhìn chung trang sẽ tải và khách truy cập trang web có thể thao tác với nó.

Điều đáng chú ý là async không được một số phiên bản hỗ trợ trình duyệt web IE, nhưng vì có rất ít người dùng sử dụng nó nên bạn nên bỏ qua điều này và sử dụng tính năng không đồng bộ trong javascript.

Một giải pháp thay thế cho async có thể là defer. sử dụng thuộc tính này tập lệnh sẽ chỉ được thực thi sau khi DOM được tải. Lệnh này được hỗ trợ bởi tất cả các trình duyệt; điểm đặc biệt của nó là nó xử lý các tập lệnh JS theo thứ tự chúng được kết nối.

Đây có thể là cả điểm cộng và điểm trừ. Nếu thứ tự thực thi các tập lệnh là quan trọng, thì trì hoãn là giải pháp tốt nhất. async có thể bị vô hiệu hóa một cách cưỡng bức: script.async=false;

Nhược điểm là nếu một tập lệnh được kết nối từ tài nguyên bên ngoài không thể truy cập được thì các tập lệnh còn lại sẽ không được xử lý. Họ sẽ chờ đợi điều này cho dù nhìn chung nó quan trọng đến thế nào.