setTimeou 스레드 메커니즘에 대한 간략한 분석

一个新手
풀어 주다: 2017-09-09 09:16:22
원래의
1164명이 탐색했습니다.

High Performance JavaScript 책을 읽을 때 다음 문장을 보았습니다.

이런 방식으로 페이지 상단에 스크립트를 배치하면 일반적으로 사용자가 작업을 수행하기 전에 눈에 띄는 지연이 발생하며 종종 빈 흰색 페이지 형태로 표시됩니다.

설명은 다음과 같습니다:

스크립트 스크립트를 헤드에 배치하면 일반적으로 다음과 같이 상당한 지연이 발생합니다. 페이지가 열릴 때 페이지가 비어 있고 사용자가 읽을 수 없습니다. 또는 어떤 방식으로든 상호작용할 수 있습니다.

내가 이해한 바는 js를 헤드에 배치하면 js의 로드 및 실행으로 인해 페이지 렌더링이 지연된다는 것입니다. js를 맨 뒤에 배치하면 페이지 렌더링이 js의 로딩이나 실행보다 먼저 이루어지므로 js의 차단에 영향을 받지 않고 사용자에게 가장 먼저 제시될 수 있습니다.

확인하기 위해 다음 실험을 수행했습니다.

<p>hello world</p><script type="text/javascript">  
    function f() {    
    var t = +new Date();

    //运行5秒    while(true) {
      if(+new Date() - t > 5) {
        break;
      }
    }
  }
  f();  // ①</script>
로그인 후 복사

실험 결과가 흥미롭습니다. hello world가 나오기 전에 5초 동안 기다렸습니다.

심층 검증: 위 스크립트 부분을 js 외부 링크로 도입하거나 동적으로 로드하세요. 5초를 기다려도 결과가 나왔습니다.

이는 모든 js가 로드되고 실행된 후에만 페이지 렌더링이 발생해야 함을 의미합니다. 위 문단에 뭔가 문제가 있습니다.

이것은 js가 DOM 작업을 포함하지 않는 한 이를 헤드와 테일에 배치해도 동일한 효과가 있다는 것을 의미합니까? 물론 그렇지 않습니다. 예를 들어 html에 그림이나 기타 리소스가 있는 경우 js가 헤드에 배치되면 그림 다운로드는 js 실행이 끝날 때까지 기다려야 시작됩니다. 그러나 js가 tail에 배치되면 그림 다운로드가 시작됩니다. 사진 다운로드는 js 실행을 차단하지 않으므로 이미지 다운로드와 js 실행을 동시에 수행할 수 있습니다.

이것이 문제의 끝인가요? 물론 아닙니다. 프론트 엔드 작업에서 매우 중요한 부분은 위의 js를 최적화하는 방법입니다. 그래서 나는 setTimeout을 생각했습니다.

setTimeout은 js 코드 실행을 지연하는 데 사용됩니다. 뒤에 있는 js 실행을 차단하지 않는다는 장점이 있습니다. 따라서 setTimeout도 페이지 렌더링을 차단하지 않을 것 같습니다.

옵션 1: 위의 ① 부분을 다음으로 대체합니다.

 setTimeout(f,0);
로그인 후 복사

결과적으로 hello world가 나오기 전에 여전히 5초를 기다려야 합니다. 그러나 주의 깊게 살펴보면 브라우저 라벨에 로드 기호가 없다는 것을 알게 될 것입니다.

계속해서 추측해 보세요. 0은 너무 작기 때문에 브라우저는 setTimeout 뒤에 js 코드가 없음을 발견하고 즉시 setTimeout의 콘텐츠, 즉 f 함수를 실행합니다. 따라서 시간을 100ms로 변경하십시오.

옵션 2: 위의 ① 부분을 다음으로 대체합니다.

setTimeout(f, 100);
로그인 후 복사

결과적으로 hello world가 즉시 팝업됩니다. 조금 흥분됩니다. 관심 있는 학생들은 계속 테스트할 수 있습니다. 이 때 중요한 값이 있다는 것을 알게 될 것입니다(브라우저마다 다른 중요한 값이 있습니다). setTimeout의 두 번째 매개변수가 이 임계값보다 크면 hello world가 즉시 나타납니다. , 내부 기능이 완료되면 기다려야 합니다.

놀랍네요, 왜 이런 일이 일어날까요? 이 질문에 대답하려면 브라우저의 스레딩 메커니즘을 연구해야 합니다.

우리는 브라우저 내부에 최소한 두 개의 스레드, 즉 js를 구문 분석하는 스레드와 인터페이스를 렌더링하는 스레드가 있다는 것을 알고 있습니다. 여기서는 일시적으로 JS 스레드와 UI 스레드라고 부릅니다.

js는 DOM을 조작할 수 있으므로 이러한 요소의 속성을 수정하면서 인터페이스를 렌더링하면(즉, JS 스레드와 UI 스레드가 동시에 실행되는 경우) 렌더링 스레드 전후에 얻은 요소 데이터가 일관성이 없습니다. 따라서 예측할 수 없는 렌더링 결과를 방지하기 위해 브라우저에서는 JS 스레드와 UI 스레드가 대기열에서 동기적으로 실행되도록 제어합니다.

위의 질문으로 돌아가서, setTimeout이 실행되면 JS 스레드가 실행되는 도중에 새로운 타이머 스레드가 열립니다. JS 스레드가 완료되면 setTimeout이 즉시 실행되기 시작합니다( 즉, 시간이 위의 임계 값보다 작습니다. UI 스레드가 너무 오랫동안 실행되어 setTimeout이 심각하게 지연되어 발생하는 나쁜 경험을 피하기 위해 브라우저는 setTimeout이 만료될 때까지 기다리도록 선택한 다음 실행됩니다. 내부의 js. setTimeout이 만료되는 데 오랜 시간이 걸리는 것으로 확인되면 시간 낭비를 피하기 위해 브라우저는 즉시 UI 스레드로 전환하도록 선택합니다.

결론: setTimeout을 사용하면 시간이 많이 걸리는 js 코드를 처리할 수 있지만 두 번째 매개변수를 너무 작게 설정하지 않도록 주의하세요. 그렇지 않으면 동일한 빈 페이지가 표시됩니다. 모든 브라우저를 만족시킬 수 있는 약 100ms를 권장합니다. 물론, IE와 호환될 수 없다면 setTimeout을 포기하고 웹 작업자가 좋은 선택이 될 것입니다.

HTML4에서 js로 만든 프로그램은 단일 스레드입니다. Web Workers는 HTML5의 새로운 기능이며 웹 애플리케이션에서 백그라운드 처리를 구현하는 데 사용되는 기술입니다. 다음 API를 사용하면 백그라운드에서 실행되는 스레드를 만드는 것이 매우 쉽습니다.

var worker = new Worker(&#39;*.js&#39;);// 后台线程是不能访问页面或窗口对象的// 但可通过发送消息和接受消息与后台线程传递数据worker.onmessage = function (e) {};
worker.postMessage = function (e) {};
로그인 후 복사

위 내용은 setTimeou 스레드 메커니즘에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿