[javascript] 웹 페이지의로드 및 실행 순서

웹 기반 프로젝트를 수행했지만 일반 웹 페이지의로드 및 실행 순서에 대해서는별로 생각하지 않습니다. 그러나 이제 세부 사항을 알아야합니다. Google 또는 SO에서 답변을 찾기가 어렵 기 때문에이 질문을 만들었습니다.

샘플 페이지는 다음과 같습니다.

<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>

내 질문은 다음과 같습니다.

  1. 이 페이지는 어떻게로드됩니까?
  2. 로딩 순서는 무엇입니까?
  3. JS 코드는 언제 실행됩니까? (인라인 및 외부)
  4. CSS는 언제 실행됩니까?
  5. 언제 $ (document) .ready가 실행됩니까?
  6. abc.jpg가 다운로드됩니까? 아니면 그냥 kkk.png를 다운로드합니까?

다음과 같은 이해가 있습니다.

  1. 브라우저는 처음에 html (DOM)을로드합니다.
  2. 브라우저는 외부 리소스를 위에서 아래로 한 줄씩로드하기 시작합니다.
  3. a <script>가 충족되면로드가 차단되고 JS 파일이로드되어 실행될 때까지 기다린 후 계속합니다.
  4. 다른 리소스 (CSS / 이미지)는 병렬로로드되고 필요한 경우 (예 : CSS) 실행됩니다.

아니면 다음과 같습니다.

브라우저는 html (DOM)을 구문 분석하고 외부 리소스를 배열 또는 스택 형 구조로 가져옵니다. html이로드 된 후 브라우저는 모든 리소스가로드 될 때까지 구조에서 외부 리소스를 병렬로로드하고 실행하기 시작합니다. 그러면 JS에 따라 사용자의 행동에 따라 DOM이 변경됩니다.

누구나 HTML 페이지의 응답을 받았을 때 어떤 일이 발생하는지 자세히 설명 할 수 있습니까? 브라우저마다 다릅니 까? 이 질문에 대한 언급이 있습니까?

감사.

편집하다:

Firebug를 사용하여 Firefox에서 실험했습니다. 다음 이미지로 표시됩니다.
대체 텍스트



답변

샘플에 따르면

<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>

대략 실행 흐름은 다음과 같습니다.

  1. HTML 문서가 다운로드됩니다
  2. HTML 문서 파싱이 시작됩니다
  3. HTML 파싱 도달 <script src="jquery.js" ...
  4. jquery.js 다운로드 및 파싱
  5. HTML 파싱 도달 <script src="abc.js" ...
  6. abc.js 다운로드, 파싱 및 실행
  7. HTML 파싱 도달 <link href="abc.css" ...
  8. abc.css 다운로드 및 파싱
  9. HTML 파싱 도달 <style>...</style>
  10. 내부 CSS 규칙이 구문 분석되고 정의됩니다.
  11. HTML 파싱 도달 <script>...</script>
  12. 내부 자바 스크립트가 구문 분석되고 실행됩니다.
  13. HTML 파싱 도달 <img src="abc.jpg" ...
  14. abc.jpg 다운로드되어 표시됩니다
  15. HTML 파싱 도달 <script src="kkk.js" ...
  16. kkk.js 다운로드, 파싱 및 실행
  17. HTML 문서 끝 파싱

다운로드는 브라우저의 동작으로 인해 비동기식 및 비 블로킹 일 수 있습니다. 예를 들어 Firefox에는 도메인 당 동시 요청 수를 제한하는이 설정이 있습니다.

또한 구성 요소가 이미 캐시되었는지 여부에 따라 가까운 미래 요청에서 구성 요소를 다시 요청하지 않을 수 있습니다. 구성 요소가 캐시 된 경우 실제 URL 대신 캐시에서 구성 요소가로드됩니다.

구문 분석이 종료되고 문서가 준비되어로드되면 이벤트 onload가 시작됩니다. 따라서 onload발사되면 $("#img").attr("src","kkk.png");실행됩니다. 그래서:

  1. 문서가 준비되었으며 온로드가 시작되었습니다.
  2. 자바 스크립트 실행 적중 $("#img").attr("src", "kkk.png");
  3. kkk.png 다운로드되어로드됩니다 #img

$(document).ready()이벤트는 실제로 모든 페이지 구성 요소가로드 및 준비가되었을 경우, 트리거 된 경우입니다. 그것에 대해 자세히 읽으십시오 : http://docs.jquery.com/Tutorials:Introducing_$ (document) .ready ()

편집-이 부분은 병렬 부분에 대해 더 자세히 설명합니다.

기본적으로 브라우저는 일반적으로 HTML 파서, Javascript / DOM 및 CSS의 3 가지 방법으로 각 페이지를 실행합니다.

HTML 구문 분석기는 마크 업 언어의 구문 분석 및 해석을 담당하므로 다른 두 구성 요소를 호출 할 수 있어야합니다.

예를 들어 파서가이 줄을 가로 질러 오는 경우 :

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

파서는 3 번, 2 번은 자바 스크립트, 1 번은 CSS를 호출합니다. 먼저 파서는이 요소를 생성하고이 요소와 관련된 모든 속성과 함께이 요소를 DOM 네임 스페이스에 등록합니다. 둘째, 파서는 onclick 이벤트를이 특정 요소에 바인딩하기 위해 호출합니다. 마지막으로 CSS 스레드를 다시 호출하여 CSS 스타일을이 특정 요소에 적용합니다.

실행은 하향식이며 단일 스레드입니다. 자바 스크립트는 멀티 스레드로 보일 수 있지만 실제로는 자바 스크립트는 단일 스레드입니다. 외부 자바 스크립트 파일을로드 할 때 기본 HTML 페이지의 구문 분석이 일시 중단 된 이유입니다.

그러나 CSS 규칙은 항상 적용되므로 CSS 파일을 동시에 다운로드 할 수 있습니다. 즉, 요소는 항상 최신 CSS 규칙이 정의되어 다시 그려 져서 차단을 해제합니다.

요소는 구문 분석 된 후에 만 ​​DOM에서 사용할 수 있습니다. 따라서 특정 요소로 작업 할 때 스크립트는 항상 창 onload 이벤트 이후 또는 window onload 이벤트 내에 배치됩니다.

이와 같은 스크립트는 오류를 발생시킵니다 (jQuery에서).

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

스크립트가 구문 분석 될 때 #mydiv요소가 여전히 정의되지 않았기 때문입니다. 대신 이것은 작동합니다 :

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

또는

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


답변

1) HTML이 다운로드됩니다.

2) HTML이 점진적으로 구문 분석됩니다. 자산 요청에 도달하면 브라우저는 자산 다운로드를 시도합니다. 대부분의 HTTP 서버 및 대부분의 브라우저에 대한 기본 구성은 두 개의 요청 만 병렬로 처리하는 것입니다. 무제한의 자산을 동시에 다운로드하도록 IE를 재구성 할 수 있습니다. Steve Souders는 IE에서 100 개가 넘는 요청을 동시에 다운로드 할 수있었습니다. 단, 스크립트 요청은 IE에서 병렬 자산 요청을 차단합니다. 그렇기 때문에 모든 JavaScript를 외부 JavaScript 파일에 넣고 HTML에서 body 태그를 닫기 직전에 요청을 넣는 것이 좋습니다.

3) HTML이 파싱되면 DOM이 렌더링됩니다. CSS는 거의 모든 사용자 에이전트에서 DOM 렌더링과 병렬로 렌더링됩니다. 결과적으로 모든 CSS 코드를 문서의 <head> </ head> 섹션에서 가능한 많이 요청 된 외부 CSS 파일에 넣는 것이 좋습니다. 그렇지 않으면 페이지가 DOM에서 CSS 요청 위치의 발생까지 렌더링 된 다음 렌더링이 맨 위에서 시작됩니다.

4) DOM이 완전히 렌더링되고 페이지의 모든 자산에 대한 요청이 해결되거나 JavaScript가 onload 이벤트에서 실행되는 시간이 초과 된 후에 만 ​​가능합니다. IE7 및 IE8에 대해 잘 모르겠지만 자산 요청에서 HTTP 응답을받지 못하면 자산을 빨리 시간 초과하지 않습니다. 이는 함수에 포함되지 않은 HTML 태그로 작성된 JavaScript 인 페이지에 대해 JavaScript로 요청한 자산이 몇 시간 동안 onload 이벤트의 실행을 막을 수 있음을 의미합니다. 이러한 인라인 코드가 페이지에 존재하고 코드 충돌을 일으키는 네임 스페이스 충돌로 인해 실행에 실패하면이 문제가 발생할 수 있습니다.

위의 단계 중 CPU를 가장 많이 사용하는 단계는 DOM / CSS의 구문 분석입니다. 페이지를 더 빠르게 처리하려면 중복 명령어를 제거하고 CSS 명령어를 가능한 가장 적은 요소 참조로 통합하여 효율적인 CSS를 작성하십시오. DOM 트리에서 노드 수를 줄이면 렌더링 속도가 빨라집니다.

HTML 또는 CSS / JavaScript 자산에서 요청한 각 자산은 별도의 HTTP 헤더로 요청됩니다. 이것은 대역폭을 소비하며 요청마다 처리해야합니다. 페이지를 가능한 빨리로드하려면 HTTP 요청 수를 줄이고 HTML 크기를 줄이십시오. HTML만으로 페이지 무게를 180k로 평균하여 사용자에게 호의를 베풀지 않습니다. 많은 개발자들은 사용자가 6 나노초 안에 페이지의 콘텐츠 품질에 대해 마음을 정한 다음 서버에서 DNS 쿼리를 제거하고 컴퓨터가 불쾌 할 경우 컴퓨터를 굽는다는 잘못된 오류에 동의합니다. HTML 250k 사용자가 페이지를 더 빠르게로드 할 수 있도록 HTML을 짧고 깔끔하게 유지하십시오.


답변

Firefox에서 페이지를 열고 HTTPFox 애드온을 받으십시오. 필요한 모든 것을 알려줄 것입니다.

archivist.incuito에서 이것을 찾았습니다.

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

페이지를 처음 요청하면 브라우저가 서버에 GET 요청을 보내면 HTML이 브라우저로 반환됩니다. 그런 다음 브라우저가 페이지 구문 분석을 시작합니다 (모든 페이지가 반환되기 전에).

CSS 파일, 이미지 파일, 스크립트 파일, 플래시 파일 또는 같은 서버 / 도메인의 페이지 외부에있는 외부 파일과 같은 외부 엔티티에 대한 참조를 찾으면 해당 자원에 대한 추가 GET 요청

그러나 HTTP 표준은 브라우저가 동일한 도메인에 대해 두 개 이상의 동시 요청을해서는 안된다고 지정합니다. 따라서 각 요청을 대기열의 특정 도메인에 넣고 각 엔티티가 반환되면 해당 도메인의 대기열에서 다음 요청을 시작합니다.

엔티티가 리턴되는 데 걸리는 시간은 크기, 서버가 현재 겪고있는로드 및 브라우저를 실행하는 머신과 서버 사이의 모든 단일 머신의 활동에 따라 다릅니다. 한 대의 이미지가 대서양을 통해 영국에서 미국으로 이동할 수있는 한도 내에서이 기계의 목록은 원칙적으로 다를 수 있으며, 동일한 서버의 다른 이미지는 태평양, 아시아 및 유럽을 통해 나옵니다. 시간이 더 걸립니다. 따라서 다음과 같은 시퀀스를 얻을 수 있습니다. 여기서 페이지에는 순서가 다른 3 개의 스크립트 파일과 5 개의 이미지 파일이 참조됩니다 (이 순서대로).

  1. GET script1 및 script2; script3 및 images1-5에 대한 대기열 요청.
  2. script2가 도착합니다 (script1보다 작습니다) : GET script3, queue images1-5.
  3. script1이 도착합니다. 이미지 1, 대기열 이미지 2-5를 가져옵니다.
  4. image1 도착, GET image2, 대기열 이미지 3-5
  5. 네트워크 문제로 인해 script3이 도착하지 못했습니다. script3을 다시 GET하십시오 (자동 재시도).
  6. image2가 도착했지만 script3은 여전히 ​​여기에 없습니다. 이미지 3, 대기열 이미지 4-5를 가져옵니다.
  7. 이미지 3이 도착한다. GET image4, queue image5, script3이 아직 진행 중입니다.
  8. image4 도착, image5 GET;
  9. image5가 도착합니다.
  10. script3이 도착합니다.

한마디로 : 서버가 수행하는 작업, 인터넷의 나머지 작업 및 오류가 있고 다시 가져와야하는지 여부에 따라 오래된 순서입니다. 이것은 이상한 일처럼 보일 수 있지만 WWW뿐만 아니라 인터넷이 이런 식으로 수행되지 않으면 어느 정도의 신뢰성으로 작동하는 것은 문자 그대로 불가능합니다.

또한 브라우저의 내부 대기열은 페이지에 표시된 순서대로 엔티티를 가져 오지 않을 수 있습니다. 표준에는 필요하지 않습니다.

(오, 브라우저에서와 네트워크에서 부하를 줄이기 위해 ISP가 사용하는 캐싱 프록시 모두에서 캐싱을 잊지 마십시오.)


답변

귀하의 웹 사이트 속도를 높이기 위해이를 요청하는 경우 웹 사이트 속도 향상을 위한 모범 사례 에서 Yahoo의 페이지를 확인하십시오 . 웹 사이트 속도를 높이기위한 많은 모범 사례가 있습니다.


답변

브라우저 (적어도 Firefox)는 파싱하자마자 모든 리소스를 요청합니다. img 태그가 발견되면 img 태그가 구문 분석되는 즉시 해당 이미지를 요청합니다. 그리고 그것은 HTML 문서의 전체를 받기 전에도 가능합니다. 즉, 그것이 일어날 때 여전히 HTML 문서를 다운로드 할 수 있습니다.

Firefox의 경우 about : config에 설정된 방식에 따라 적용되는 브라우저 큐가 있습니다. 예를 들어 동일한 서버에서 한 번에 8 개 이상의 파일을 다운로드하려고 시도하지 않습니다. 추가 요청이 대기됩니다. 도메인 당 제한, 프록시 제한 및 기타 사항이 있으며 Mozilla 웹 사이트에 설명되어 있으며 about : config에서 설정할 수 있다고 생각합니다. 나는 IE가 그런 한계가 없다는 곳을 읽었습니다.

기본 HTML 문서 가 다운로드되고 DOM이 구문 분석 되는 즉시 jQuery 준비 이벤트가 시작됩니다 . 그런 다음 연결된 모든 리소스 (CSS, 이미지 등)를 다운로드하고 파싱하면로드 이벤트가 시작됩니다. jQuery 문서에서 명확합니다.

로드 된 모든 순서를 제어하려면 JavaScript를 사용하는 것이 가장 신뢰할 수있는 방법이라고 생각합니다.


답변

Dynatrace AJAX Edition 은 정확한 페이지 로딩, 파싱 및 실행 순서를 보여줍니다.


답변

선택한 답변은 적어도 Firefox 52에서는 최신 브라우저에 적용되지 않는 것 같습니다. 내가 관찰 한 것은 HTML 파서가 요소에 도달하기 전에 CSS, 자바 스크립트와 같은 리소스로드 요청이 발행된다는 것입니다.

<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>

내가 CSS와 자바 스크립트 리소스를로드하는 요청의 시작 시간이 차단되지 않았다는 것을 알았습니다. Firefox에 HTML 스캔이 있고 HTML 구문 분석을 시작하기 전에 주요 리소스 (img 리소스는 포함되지 않음)를 식별 한 것 같습니다.