Tải và thực hiện trình tự của một trang web?


244

Tôi đã thực hiện một số dự án dựa trên web, nhưng tôi không nghĩ quá nhiều về trình tự tải và thực thi của một trang web thông thường. Nhưng bây giờ tôi cần biết chi tiết. Thật khó để tìm câu trả lời từ Google hoặc SO, vì vậy tôi đã tạo ra câu hỏi này.

Một trang mẫu là như thế này:

<html>
 <head>
  <script src="jquery.js" type="text/javascript"></script>
  <script src="abc.js" type="text/javascript">
  </script>
  <link rel="stylesheets" type="text/css" href="abc.css"></link>
  <style>h2{font-wight:bold;}</style>
  <script>
  $(document).ready(function(){
     $("#img").attr("src", "kkk.png");
  });
 </script>
 </head>
 <body>
    <img id="img" src="abc.jpg" style="width:400px;height:300px;"/>
    <script src="kkk.js" type="text/javascript"></script>
 </body>
</html>

Vì vậy, đây là những câu hỏi của tôi:

  1. Làm thế nào để trang này tải?
  2. Trình tự tải là gì?
  3. Khi nào mã JS được thực thi? (nội tuyến và bên ngoài)
  4. Khi nào CSS được thực thi (áp dụng)?
  5. Khi nào $ (tài liệu). Đã được thực thi?
  6. Abc.jpg sẽ được tải xuống? Hay nó chỉ tải về kkk.png?

Tôi có cách hiểu như sau:

  1. Trình duyệt tải html (DOM) lúc đầu.
  2. Trình duyệt bắt đầu tải các tài nguyên bên ngoài từ trên xuống dưới, từng dòng một.
  3. Nếu a <script>được đáp ứng, quá trình tải sẽ bị chặn và đợi cho đến khi tệp JS được tải và thực thi rồi tiếp tục.
  4. Các tài nguyên khác (CSS / hình ảnh) được tải song song và được thực thi nếu cần (như CSS).

Hoặc là như thế này:

Trình duyệt phân tích cú pháp html (DOM) và lấy các tài nguyên bên ngoài trong một cấu trúc dạng mảng hoặc giống như ngăn xếp. Sau khi html được tải, trình duyệt bắt đầu tải song song các tài nguyên bên ngoài trong cấu trúc và thực thi cho đến khi tất cả các tài nguyên được tải. Sau đó, DOM sẽ được thay đổi tương ứng với các hành vi của người dùng tùy thuộc vào JS.

Bất cứ ai cũng có thể đưa ra lời giải thích chi tiết về những gì xảy ra khi bạn nhận được phản hồi của trang html? Điều này có khác nhau trong các trình duyệt khác nhau? Bất kỳ tài liệu tham khảo về câu hỏi này?

Cảm ơn.

BIÊN TẬP:

Tôi đã làm một thí nghiệm trong Firefox với Fireorms. Và nó hiển thị như hình ảnh sau đây: văn bản thay thế


11
Steve Souder đã thực hiện rất nhiều công việc trong lĩnh vực này. Google cho steve + súp + hiệu suất cao + và có một cái nhìn.
anddoutoi

3
Tôi không có nghĩa là điều chỉnh hiệu suất. Tôi muốn biết chi tiết.
Zhu Tao

2
Bằng cách đọc tác phẩm của anh ấy, sự hiểu biết của tôi về cách "nó" hoạt động chi tiết tăng gấp 10 lần nên nó vẫn là một nhận xét hợp lệ. Tôi không được bản quyền cho phép trích dẫn toàn bộ cuốn sách của mình ở đây vì vậy tôi vẫn đề nghị bạn xem tác phẩm của mình.
anddoutoi

3
Một mô tả tuyệt vời về thứ tự xảy ra ở đây
Gerrat

Câu trả lời:


277

Theo mẫu của bạn,

<html>
 <head>
  <script src="jquery.js" type="text/javascript"></script>
  <script src="abc.js" type="text/javascript">
  </script>
  <link rel="stylesheets" type="text/css" href="abc.css"></link>
  <style>h2{font-wight:bold;}</style>
  <script>
  $(document).ready(function(){
     $("#img").attr("src", "kkk.png");
  });
 </script>
 </head>
 <body>
    <img id="img" src="abc.jpg" style="width:400px;height:300px;"/>
    <script src="kkk.js" type="text/javascript"></script>
 </body>
</html>

đại khái là dòng thực thi là như sau:

  1. Tài liệu HTML được tải xuống
  2. Việc phân tích cú pháp tài liệu HTML bắt đầu
  3. Phân tích cú pháp HTML <script src="jquery.js" ...
  4. jquery.js được tải xuống và phân tích cú pháp
  5. Phân tích cú pháp HTML <script src="abc.js" ...
  6. abc.js được tải xuống, phân tích cú pháp và chạy
  7. Phân tích cú pháp HTML <link href="abc.css" ...
  8. abc.css được tải xuống và phân tích cú pháp
  9. Phân tích cú pháp HTML <style>...</style>
  10. Các quy tắc CSS nội bộ được phân tích cú pháp và xác định
  11. Phân tích cú pháp HTML <script>...</script>
  12. Javascript nội bộ được phân tích cú pháp và chạy
  13. Phân tích cú pháp HTML <img src="abc.jpg" ...
  14. abc.jpg được tải xuống và hiển thị
  15. Phân tích cú pháp HTML <script src="kkk.js" ...
  16. kkk.js được tải xuống, phân tích cú pháp và chạy
  17. Phân tích cú pháp tài liệu HTML kết thúc

Lưu ý rằng việc tải xuống có thể không đồng bộ và không chặn do các hành vi của trình duyệt. Ví dụ: trong Firefox có cài đặt này giới hạn số lượng yêu cầu đồng thời trên mỗi tên miền.

Cũng tùy thuộc vào việc thành phần đã được lưu trữ hay chưa, thành phần có thể không được yêu cầu lại trong yêu cầu trong tương lai gần. Nếu thành phần đã được lưu trữ, thành phần sẽ được tải từ bộ đệm thay vì URL thực tế.

Khi quá trình phân tích cú pháp kết thúc và tài liệu đã sẵn sàng và được tải, các sự kiện onloadsẽ được kích hoạt. Vì vậy, khi onloadbị sa thải, $("#img").attr("src","kkk.png");được chạy. Vì thế:

  1. Tài liệu đã sẵn sàng, tải được bắn.
  2. Lượt truy cập Javascript $("#img").attr("src", "kkk.png");
  3. kkk.png được tải xuống và tải vào #img

Sự $(document).ready()kiện này thực sự là sự kiện được kích hoạt khi tất cả các thành phần trang được tải và sẵn sàng. Đọc thêm về nó: http://docs.jquery.com/Tutorials:Int Giới thiệu_$ (tài liệu). Đã ()

Chỉnh sửa - Phần này chi tiết hơn về phần song song hoặc không:

Theo mặc định và theo hiểu biết hiện tại của tôi, trình duyệt thường chạy mỗi trang theo 3 cách: trình phân tích cú pháp HTML, Javascript / DOM và CSS.

Trình phân tích cú pháp HTML chịu trách nhiệm phân tích và giải thích ngôn ngữ đánh dấu và do đó phải có thể thực hiện cuộc gọi đến 2 thành phần khác.

Ví dụ: khi trình phân tích cú pháp đi qua dòng này:

<a href="#" onclick="alert('test');return false;" style="font-weight:bold">a hypertext link</a>

Trình phân tích cú pháp sẽ thực hiện 3 cuộc gọi, hai cuộc gọi đến Javascript và một cuộc gọi đến CSS. Đầu tiên, trình phân tích cú pháp sẽ tạo thành phần này và đăng ký nó trong không gian tên DOM, cùng với tất cả các thuộc tính liên quan đến phần tử này. Thứ hai, trình phân tích cú pháp sẽ gọi để liên kết sự kiện onclick với phần tử cụ thể này. Cuối cùng, nó sẽ thực hiện một cuộc gọi khác đến luồng CSS để áp dụng kiểu CSS cho thành phần cụ thể này.

Việc thực hiện là từ trên xuống và luồng đơn. Javascript có thể trông đa luồng, nhưng thực tế là Javascript là một luồng đơn. Đây là lý do tại sao khi tải tệp javascript bên ngoài, việc phân tích cú pháp của trang HTML chính bị treo.

Tuy nhiên, các tệp CSS có thể được tải xuống đồng thời vì các quy tắc CSS luôn được áp dụng - có nghĩa là các phần tử luôn được sơn lại với các quy tắc CSS mới nhất được xác định - do đó làm cho nó bỏ chặn.

Một phần tử sẽ chỉ khả dụng trong DOM sau khi được phân tích cú pháp. Do đó, khi làm việc với một phần tử cụ thể, tập lệnh luôn được đặt sau hoặc trong sự kiện tải cửa sổ.

Tập lệnh như thế này sẽ gây ra lỗi (trên jQuery):

<script type="text/javascript">/* <![CDATA[ */
  alert($("#mydiv").html());
/* ]]> */</script>
<div id="mydiv">Hello World</div>

Bởi vì khi tập lệnh được phân tích cú pháp, #mydivphần tử vẫn không được xác định. Thay vào đó, nó sẽ hoạt động:

<div id="mydiv">Hello World</div>
<script type="text/javascript">/* <![CDATA[ */
  alert($("#mydiv").html());
/* ]]> */</script>

HOẶC LÀ

<script type="text/javascript">/* <![CDATA[ */
  $(window).ready(function(){
                    alert($("#mydiv").html());
                  });
/* ]]> */</script>
<div id="mydiv">Hello World</div>

4
cảm ơn. Nhưng bạn đã đề cập tải xuống có thể không đồng bộ và không chặn do các hành vi của trình duyệt , vậy loại thành phần nào có thể được tải xuống trong asyn (lấy FF làm ví dụ)? <script>sẽ chặn các thành phần khác, phải không? Bất kỳ tài liệu tham khảo về thông số kỹ thuật cho mỗi trình duyệt?
Zhu Tao

4
$ (tài liệu). yet () được kích hoạt khi DOM hoàn tất, không phải khi tất cả các thành phần trang được tải
Pierre

2
@Pierre theo các thành phần trang tôi có nghĩa là DOM -> bất kỳ thành phần nào trong DOM.
mauris

3
chỉ để làm rõ ... window.onload thông thường xảy ra sau # 17 ... vậy tại thời điểm nào # jquery's $ (tài liệu). yet () mã của chạy? # 12? nhưng bản thân DOM được tải ở vị trí số 1 phải không?
armyofda12mnkeys

1
Nếu trong tab <body>, nếu chúng tôi thêm thẻ <link href = "bootstrap.min.css" rel = "biểu định kiểu" /> giữa thẻ <img> và <script> thì không hiển thị cho đến khi bootrap được tải xuống ... vì vậy tôi nghĩ bước [13], [14] cần sửa đổi ... ai đó có thể giải thích hành vi đó không?
Bhuvan

34

1) HTML được tải xuống.

2) HTML được phân tích cú pháp dần dần. Khi đạt được yêu cầu về một tài sản, trình duyệt sẽ cố tải xuống nội dung đó. Một cấu hình mặc định cho hầu hết các máy chủ HTTP và hầu hết các trình duyệt là chỉ xử lý song song hai yêu cầu. IE có thể được cấu hình lại để tải xuống song song số lượng tài sản không giới hạn. Steve Souder đã có thể tải xuống hơn 100 yêu cầu song song trên IE. Ngoại lệ là tập lệnh yêu cầu chặn các yêu cầu tài sản song song trong IE. Đây là lý do tại sao nên đưa tất cả JavaScript vào các tệp JavaScript bên ngoài và đặt yêu cầu ngay trước thẻ thân đóng trong HTML.

3) Khi HTML được phân tích cú pháp, DOM được hiển thị. CSS được kết xuất song song với kết xuất DOM trong gần như tất cả các tác nhân người dùng. Do đó, chúng tôi đặc biệt khuyến nghị đưa tất cả mã CSS vào các tệp CSS bên ngoài được yêu cầu càng cao càng tốt trong phần <head> </ head> của tài liệu. Mặt khác, trang được hiển thị theo sự xuất hiện của vị trí yêu cầu CSS trong DOM và sau đó kết xuất bắt đầu lại từ đầu.

4) Chỉ sau khi DOM được hiển thị hoàn toàn và các yêu cầu cho tất cả các tài sản trong trang được giải quyết hoặc hết thời gian thì JavaScript mới thực thi từ sự kiện onload. IE7 và tôi không chắc chắn về IE8, sẽ không hết thời gian nhanh chóng nếu không nhận được phản hồi HTTP từ yêu cầu tài sản. Điều này có nghĩa là một tài sản được JavaScript yêu cầu nội tuyến đến trang, đó là JavaScript được ghi vào các thẻ HTML không có trong một hàm, có thể ngăn việc thực hiện sự kiện onload trong nhiều giờ. Vấn đề này có thể được kích hoạt nếu mã nội tuyến như vậy tồn tại trong trang và không thực thi do xung đột không gian tên gây ra sự cố mã.

Trong số các bước trên, bước tập trung nhiều CPU nhất là phân tích cú pháp DOM / CSS. Nếu bạn muốn trang của bạn được xử lý nhanh hơn thì hãy viết CSS hiệu quả bằng cách loại bỏ các hướng dẫn dư thừa và hợp nhất các hướng dẫn CSS vào các tham chiếu phần tử ít nhất có thể. Giảm số lượng nút trong cây DOM của bạn cũng sẽ tạo ra kết xuất nhanh hơn.

Hãy nhớ rằng mỗi nội dung bạn yêu cầu từ HTML hoặc thậm chí từ các tài sản CSS / JavaScript của bạn được yêu cầu với một tiêu đề HTTP riêng. Điều này tiêu tốn băng thông và yêu cầu xử lý theo yêu cầu. Nếu bạn muốn làm cho trang của mình tải nhanh nhất có thể thì hãy giảm số lượng yêu cầu HTTP và giảm kích thước HTML của bạn. Bạn không làm cho người dùng của bạn trải nghiệm bất kỳ ưu đãi nào bằng cách tính trung bình trọng lượng trang ở mức 180k chỉ từ HTML. Nhiều nhà phát triển đăng ký một số sai lầm mà người dùng quyết định về chất lượng nội dung trên trang trong 6 nano giây và sau đó thanh trừng truy vấn DNS từ máy chủ của anh ta và đốt cháy máy tính của anh ta nếu không hài lòng, vì vậy thay vào đó họ cung cấp trang đẹp nhất có thể tại 250k HTML. Giữ HTML của bạn ngắn và ngọt ngào để người dùng có thể tải các trang của bạn nhanh hơn.


2
hợp nhất các hướng dẫn CSS vào các tham chiếu phần tử ít nhất có thể Nghe có vẻ lạ. Nếu tôi cần tạo kiểu ba yếu tố, tôi cần tham khảo chính xác ba yếu tố. Tôi không thể tham khảo một đến phong cách mười, tôi có thể? Hoặc giải thích về điều đó
Green

12

Mở trang của bạn trong Firefox và nhận addon HTTPFox. Nó sẽ cho bạn biết tất cả những gì bạn cần.

Tìm thấy điều này trên archivist.incuito:

http://archivist.incutio.com/viewlist/css-discuss/76444

Khi bạn lần đầu tiên yêu cầu một trang, trình duyệt của bạn sẽ gửi yêu cầu GET đến máy chủ, trả về HTML cho trình duyệt. Trình duyệt sau đó bắt đầu phân tích trang (có thể trước khi tất cả trang đó được trả lại).

Khi nó tìm thấy một tham chiếu đến một thực thể bên ngoài như tệp CSS, tệp hình ảnh, tệp tập lệnh, tệp Flash hoặc bất kỳ thứ gì khác bên ngoài trang (trên cùng một máy chủ / tên miền), nó sẽ chuẩn bị để thực hiện một yêu cầu NHẬN thêm cho tài nguyên đó.

Tuy nhiên, tiêu chuẩn HTTP chỉ định rằng trình duyệt không nên thực hiện nhiều hơn hai yêu cầu đồng thời cho cùng một tên miền. Vì vậy, nó đặt mỗi yêu cầu đến một tên miền cụ thể trong hàng đợi và khi mỗi thực thể được trả về, nó sẽ bắt đầu yêu cầu tiếp theo trong hàng đợi cho tên miền đó.

Thời gian để thực thể được trả về tùy thuộc vào kích thước của nó, tải mà máy chủ hiện đang gặp phải và hoạt động của mọi máy đơn lẻ giữa máy chạy trình duyệt và máy chủ. Về nguyên tắc, danh sách các máy này có thể khác nhau đối với mọi yêu cầu, đến mức một hình ảnh có thể đi từ Hoa Kỳ đến tôi ở Anh qua Đại Tây Dương, trong khi một máy khác từ cùng một máy chủ xuất hiện qua Thái Bình Dương, Châu Á và Châu Âu, mà mất nhiều thời gian hơn. Vì vậy, bạn có thể nhận được một chuỗi như sau, trong đó một trang có (theo thứ tự này) tham chiếu đến ba tệp tập lệnh và năm tệp hình ảnh, tất cả các kích cỡ khác nhau:

  1. NHẬN script1 và script2; yêu cầu hàng đợi cho script3 và hình ảnh1-5.
  2. script2 đến (nó nhỏ hơn script1): GET script3, xếp hàng hình ảnh1-5.
  3. script1 đến; NHẬN hình ảnh1, xếp hàng hình ảnh2-5.
  4. image1 đến, NHẬN image2, xếp hàng hình ảnh3-5.
  5. script3 không đến được do sự cố mạng - NHẬN lại script3 (thử lại tự động).
  6. image2 đến, script3 vẫn không ở đây; NHẬN hình ảnh3, xếp hàng hình ảnh4-5.
  7. hình ảnh 3 đến; NHẬN image4, xếp hàng image5, script3 vẫn đang trên đường.
  8. image4 đến, NHẬN hình ảnh5;
  9. hình ảnh5 đến.
  10. script3 đến.

Tóm lại: bất kỳ thứ tự cũ nào, tùy thuộc vào những gì máy chủ đang làm, phần còn lại của Internet đang làm gì, và liệu có bất cứ điều gì có lỗi hay không và phải được tải lại. Điều này có vẻ như là một cách làm việc kỳ lạ, nhưng Internet hoàn toàn không thể thực hiện được (không chỉ WWW) hoạt động với bất kỳ mức độ tin cậy nào nếu nó không được thực hiện theo cách này.

Ngoài ra, hàng đợi nội bộ của trình duyệt có thể không tìm nạp các thực thể theo thứ tự chúng xuất hiện trong trang - không bắt buộc theo bất kỳ tiêu chuẩn nào.

(Ồ, và đừng quên bộ nhớ đệm, cả trong trình duyệt và các proxy lưu trữ được sử dụng bởi các ISP để giảm tải cho mạng.)



2

AFAIK, trình duyệt (ít nhất là Firefox) yêu cầu mọi tài nguyên ngay khi phân tích cú pháp. Nếu nó gặp thẻ img, nó sẽ yêu cầu hình ảnh đó ngay khi thẻ img được phân tích cú pháp. Và đó có thể là ngay cả trước khi nó nhận được toàn bộ tài liệu HTML ... đó là nó vẫn có thể tải xuống tài liệu HTML khi điều đó xảy ra.

Đối với Firefox, có các hàng đợi trình duyệt được áp dụng, tùy thuộc vào cách chúng được đặt trong about: config. Ví dụ: nó sẽ không cố tải xuống nhiều hơn 8 tệp cùng một lúc từ cùng một máy chủ ... các yêu cầu bổ sung sẽ được xếp hàng. Tôi nghĩ rằng có giới hạn cho mỗi tên miền, mỗi giới hạn proxy và các nội dung khác, được ghi lại trên trang web Mozilla và có thể được đặt trong about: config. Tôi đọc ở đâu đó rằng IE không có giới hạn như vậy.

Sự kiện sẵn sàng của jQuery được kích hoạt ngay khi tài liệu HTML chính được tải xuống và DOM được phân tích cú pháp. Sau đó, sự kiện tải được kích hoạt khi tất cả các tài nguyên được liên kết (CSS, hình ảnh, v.v.) cũng đã được tải xuống và phân tích cú pháp. Nó được làm rõ trong tài liệu jQuery.

Nếu bạn muốn kiểm soát thứ tự tải tất cả, tôi tin rằng cách đáng tin cậy nhất để thực hiện là thông qua JavaScript.



1

Câu trả lời được chọn có vẻ như không áp dụng cho các trình duyệt hiện đại, ít nhất là trên Firefox 52. Điều tôi quan sát được là các yêu cầu tải tài nguyên như css, javascript được đưa ra trước khi trình phân tích cú pháp HTML đến phần tử, ví dụ

<html>
  <head>
    <!-- prints the date before parsing and blocks HTMP parsering -->
    <script>
      console.log("start: " + (new Date()).toISOString());
      for(var i=0; i<1000000000; i++) {};
    </script>

    <script src="jquery.js" type="text/javascript"></script>
    <script src="abc.js" type="text/javascript"></script>
    <link rel="stylesheets" type="text/css" href="abc.css"></link>
    <style>h2{font-wight:bold;}</style>
    <script>
      $(document).ready(function(){
      $("#img").attr("src", "kkk.png");
     });
   </script>
 </head>
 <body>
   <img id="img" src="abc.jpg" style="width:400px;height:300px;"/>
   <script src="kkk.js" type="text/javascript"></script>
   </body>
</html>

Điều tôi nhận thấy là thời gian bắt đầu yêu cầu tải tài nguyên css và javascript không bị chặn. Có vẻ như Firefox có quét HTML và xác định các tài nguyên chính (không bao gồm tài nguyên img) trước khi bắt đầu phân tích HTML.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.