2011-03-05 2 views
5

질문에 답하기 전에. Event Loop에서 나는 http://en.wikipedia.org/wiki/Event_loop을 언급하고 있다고 말하자. 이것은 브라우저가 구현하는 것입니다. 자세한 내용은 http://javascript.info/tutorial/further-javascript-features/events-and-timing-depth을 참조하십시오.자바 스크립트를 완전히 이해하지 못합니다. 스레딩

이 질문은 힘들고 길기 때문에 부담주세요. 그리고 모든 대답에 감사드립니다!


그래서. 자, 내가 이해하는 것처럼, JavaScript에는 하나의 메인 스레드가 있습니다 (대부분의 브라우저 환경에서). 그래서, 같은 코드 :

for (var color = 0x000; color < 0xfff; color++) { 
    $('div').css('background-color', color.toString(16)); 
} 

흰색 검정색에서 애니메이션을 생산하지만, 다음 이 발생 할 때 (렌더링이 완료되기 때문에 코드가 처리 된 후 것을 볼 수 없습니다 - 브라우저가 이벤트 루프로 들어감). 당신이 애니메이션을보고 싶다면

, 당신은 할 수 :에서는 setTimeout이 후 처리됩니다 브라우저 이벤트 루프 스택에 새로운 이벤트를 밀어 때문에

for (var color = 0x000; color < 0xfff; color++) { 
    setTimeout(function() { 
     $('div').css('background-color', color.toString(16)); 
    }, 0); 
} 

위의 예는, 눈에 보이는 애니메이션을 생성 할 것 아무것도 실행되지 않습니다 (이벤트 루프에 들어가서 다음에 무엇을 할 것인지 확인하십시오).

이 경우 브라우저에 스택으로 푸시 된 0xfff (4095) 이벤트가있는 것으로 보이며 각 이벤트는 그 사이의 렌더링 프로세스로 처리됩니다. 그래서, 제 첫 질문 (# 1)은 정확히 렌더링이 일어날 때입니까? 이벤트 루프 스택의 두 이벤트를 처리하는 사이에 항상 발생합니까?


두 번째 질문은 내가 당신에게 준 javascript.info 웹 사이트 링크의 코드에 관한 것입니다. 여기

... 
    function func() { 
    timer = setTimeout(func, 0) 
    div.style.backgroundColor = '#'+i.toString(16) 
    if (i++ == 0xFFFFFF) stop() 
    } 

timer = setTimeout(func, 0) 
.... 

내 질문에 그 브라우저가 div.style. ... = ... 라인에 도달 할 때마다 스택 이벤트 루프에 새로운 "렌더링"이벤트를 밀어 것입니까? 하지만 setTimeout 호출로 인해 이벤트가 처음으로 푸시되지 않습니까? 그래서 브라우저는 다음과 같은 스택으로 끝납니 까?

div 스타일이 변경되기 전에 setTimeout 호출이 처리되었으므로?

rendering event 
setTimeout event 
rendering event 

및 렌더링 이벤트 이전의 setTimeout 전화가 계속 : 그 스택과 같은 방법 경우에, 나는 브라우저가 이벤트 루프가의 setTimeout의 콜백을 처리하고 필요 끝날 것를 입력 다음 번 생각할 겁니다 생산 되었습니까?

답변

6

1 : 반드시 그렇지는 않습니다. 다양한 수준의 브라우저가 최적화를 구현합니다. 예를 들어 레이아웃을 고비용으로 다시 계산하기 전에 여러 스타일 변경을 수집하기를 기다릴 수 있습니다. 그래서 대답은 : 특정 브라우저에 따라 다릅니다.

이보십시오 : http://taligarsiel.com/Projects/howbrowserswork1.htm#Render_tree_construction은 (문서 시월 일자 2009 년입니다 - 즉, 충분히 최신 상태)

Q2 : 렌더링은 반드시 JS 실행과 동일하지 않습니다 - 그 두 개의 서로 다른 엔진을합니다. JS 엔진은 렌더링에 대한 책임이 없으며 렌더링 엔진과 인터페이스합니다.두 번째 질문에 대한 주요 메시지는 렌더링 엔진에서 JS의 독립성 인 입니다. 브라우저 (또는 웹 페이지)가 자바 스크립트를 필요로하지 않는다는 것을 기억하십시오. 주요 목적은 CSS 스타일 규칙을 기반으로 HTML을 렌더링하는 것입니다. Javascript는 HTML (DOM 트리)과 스타일 규칙을 조작하는 한 가지 방법 일뿐입니다.

스타일 정의를 읽으면 렌더링 엔진을 강제로 실행할 수 있습니다.이 시점에서 렌더링 엔진은 특히 위치 변화가있는 경우 스타일 변경 사항을 처리 할 수 ​​밖에 없습니다. 그렇기 때문에 스타일을 많이 변경하거나 요소를 많이 추가하기 전에 렌더링 트리에서 객체를 제거해야합니다 (예 : display : none - visibility : hidden은 요소의 크기가 여전히 레이아웃으로 고려되기 때문에 충분하지 않습니다). 많은 행이 하나씩 ("for"루프) 테이블에 추가 될 때.

전혀 질문의 일부가 아니지만 display : none과 visibility : hidden의 차이점을 언급 한 이래로 숨겨진 위치를 추가 할 때 고려해야 할 사항 : 대화 상자와 같은 절대적인 요소. 눈에 띄는 차이는 절대적으로 배치 된 요소가 다른 방법을 사용하여 숨겨져 있는지 여부에 관계없이 내부적으로 큰 차이가 있습니다. 숨김 : visibility : hidden 요소는 렌더링 트리의 일부이며 표시 : none입니다. 아니. 예를 들어, "표시 없음"스타일이 "없음"과 "없음"사이에서 전환 될 때 숨겨져 있기 때문에 표시 및 숨기기를 사용해야합니다. 브라우저가 먼저 렌더링해야하는 "차단"

+0

일을 :-) – Martijn

1

언급 한 기사는 자바 스크립트 만 고려합니다. 브라우저에서 더 많은 일이 발생합니다. reflowing 및 repainting/더 많은 것들에 의해 트리거 될 수 있습니다; 이것에 대한 자세한 정보는 다음 링크를보십시오.

  • http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/
  • http://www.browserscope.org/reflow/about
  • 나는이 목적을 위해의 setTimeout을 사용하지 것이다

      .

      편집 : 의견에 따라 requestAnimationFrame을 사용하는 것이 좋습니다. 이 글을 쓰는 시점에서 이것은 대부분의 브라우저의 불안정한 릴리스에서만 사용할 수 있습니다. 그러나 브라우저 간 액세스를 제공하는 severallibraries을 사용할 수 있으며, 필요한 경우 setTimeout을 사용합니다.

      새로운뿐만 아니라 오래된 브라우저에서 근무하는 예를 들어,이 데모를 살펴 보자 : http://paulirish.com/2011/requestanimationframe-for-smart-animating/

    +0

    마지막 문장에 대한 대응의 브라우저가 작동하는 방법 '에 대한 링크 : 애니메이션을 얻으려면 (시간이 지남에 따라 하나 이상의 CSS 스타일 속성을 변경하는 것) 실제로 setTimeout을 사용해야합니다. 그렇지 않으면 : 1) JS 엔진 (및 브라우저!) 실행을 차단합니다. 2) 눈에 보이는 변경 사항이 없습니다. 최적화 된 렌더링 엔진이 많은 스타일 변경을 감지하고 대부분 또는 모든 렌더링을 다시 렌더링하기 전에 수집하기 때문에. –

    +0

    네 말이 맞아. 미안해. 나는 그 질문을 잘못 읽었고 (나는 그 당시 읽고 있던 다른 질문과 혼동했다.) – Martijn

    +0

    사실, 사용 가능한 경우 window.requestAnimationFrame()을 사용해야합니다. – Tower

    관련 문제