브라우저는 모든 페이지로드에서 자바 스크립트를 구문 분석합니까?


190

페이지를 새로 고칠 때마다 브라우저 (IE 및 Firefox)가 링크 된 JavaScript 파일을 구문 분석합니까?

그들은 파일을 캐시 할 수 있으므로 매번 다운로드하려고 시도하지 않을 것이라고 생각하지만 각 페이지가 본질적으로 분리되어 있기 때문에 이전 코드를 분해하고 다시 구문 분석 할 것으로 기대합니다.

이것은 비효율적이지만 완벽하게 이해할 수는 있지만 최신 브라우저가 사이트 내에서 구문 분석 단계를 피할만큼 영리한지 궁금합니다. 사이트에서 ExtJS 또는 jQuery와 같은 자바 스크립트 라이브러리를 사용하는 경우를 생각하고 있습니다.


4
내 2c : 구문 분석 된 Javascript 파일 캐싱의 성능 이점이 너무 작아서 의미있는 최적화가 될 수 없다고 생각합니다.
Itay Maman

2
내 벤치 마크에서 실제로 중요 할 수 있습니다. 예를 들어 jQuery로드 시간은 약 30msec (고속 데스크톱 시스템에서)이며, 그 중 20 %는 코드를 실행 가능한 표현으로 만 구문 분석하고 나머지는 실행 중입니다 (예 :이 경우 jQuery 객체 초기화). 모바일 환경에서 2 개 또는 3 개의 라이브러리를 사용하는 경우 JavaScript 실행이 차단되고 모든 JS 스크립트가 메모리에로드 될 때까지 페이지가 비어있는 경우이 지연이 관련 될 수 있습니다.
djjeck

답변:


338

이것들은 내가 파낼 수 있었던 세부 사항입니다. JavaScript는 일반적으로 VM에서 해석되고 VM에서 실행되는 것으로 간주되지만 실제로는 소스를 기계 코드로 직접 컴파일하는 경향이있는 최신 인터프리터에서는 그렇지 않습니다 (IE 제외).


크롬 : V8 엔진

V8에는 컴파일 캐시가 있습니다. 최대 5 개의 가비지 콜렉션에 대한 소스 해시를 사용하여 컴파일 된 JavaScript를 저장합니다. 이는 두 개의 동일한 소스 코드 조각이 포함 된 방식에 관계없이 메모리에서 캐시 항목을 공유 함을 의미합니다. 이 캐시는 페이지를 다시로드 할 때 지워지지 않습니다.

출처


업데이트-2015 년 3 월 19 일

Chrome 팀은 JavaScript 스트리밍 및 캐싱을위한 새로운 기술에 대한 세부 정보를 발표 했습니다 .

  1. 스크립트 스트리밍

스크립트 스트리밍은 JavaScript 파일의 구문 분석을 최적화합니다. [...]

버전 41부터 Chrome은 다운로드가 시작되는 즉시 비동기 및 지연된 스크립트를 별도의 스레드에서 구문 분석합니다. 즉, 다운로드가 완료된 후 밀리 초 만에 파싱이 완료 될 수 있으며 페이지 로딩 속도가 10 % 빨라집니다.

  1. 코드 캐싱

일반적으로 V8 엔진은 방문 할 때마다 페이지의 JavaScript를 컴파일하여 프로세서가 이해하는 지침으로 바꿉니다. 컴파일 된 코드는 컴파일 타임에 머신의 상태와 컨텍스트에 크게 의존하므로 사용자가 페이지에서 벗어나면이 컴파일 된 코드는 삭제됩니다.

Chrome 42에는 컴파일 된 코드의 로컬 사본을 저장하는 고급 기술이 도입되어 사용자가 페이지로 돌아올 때 다운로드, 파싱 및 컴파일 단계를 모두 건너 뛸 수 있습니다. 모든 페이지로드에서 Chrome은 컴파일 시간의 약 40 %를 피하고 휴대 기기의 소중한 배터리를 절약 할 수 있습니다.


오페라 : Carakan Engine

실제로 이것은 소스 코드가 최근에 컴파일 된 다른 프로그램의 소스 코드와 동일한 스크립트 프로그램을 컴파일하려고 할 때마다 컴파일러의 이전 출력을 재사용하고 컴파일 단계를 완전히 건너 뜁니다. 이 캐시는 뉴스 서비스의 다른 뉴스 기사와 같이 동일한 사이트에서 페이지마다 페이지를로드하는 일반적인 브라우징 시나리오에서 매우 효과적입니다. 각 페이지는 종종 동일하거나 때로는 매우 큰 스크립트 라이브러리를로드하기 때문입니다.

따라서 JavaScript는 페이지를 다시로드 할 때 캐시되므로 동일한 스크립트에 대한 두 가지 요청은 다시 컴파일되지 않습니다.

출처


Firefox : SpiderMonkey 엔진

SpiderMonkey는 Nanojit기본 백엔드 인 JIT 컴파일러로 사용합니다. 머신 코드를 컴파일하는 과정은 여기에서 볼 수 있습니다 . 요컨대, 스크립트가로드되면 다시 컴파일 하는 것처럼 보입니다 . 그러나 내부를 자세히 살펴보면 컴파일을 추적하는 데 사용되는 Nanojit더 높은 수준의 모니터 jstracer가 컴파일 중 3 단계를 통해 전환 할 수 있으며 Nanojit다음과 같은 이점이 있습니다 .

추적 모니터의 초기 상태는 모니터링입니다. 이것은 spidermonkey가 바이트 코드를 해석하고 있음을 의미합니다. spidermonkey가 역방향 점프 바이트 코드를 해석 할 때마다 모니터는 점프 대상 프로그램 카운터 (PC) 값이 점프 한 횟수를 기록합니다. 이 숫자를 PC의 적중 횟수라고합니다. 특정 PC의 적중 횟수가 임계 값에 도달하면 대상이 핫한 것으로 간주됩니다.

모니터가 대상 PC가 뜨겁다 고 판단하면 해당 대상 PC에 대한 고유 코드를 보유하는 단편이 있는지 확인하기 위해 단편의 해시 테이블을 찾습니다. 그러한 조각을 찾으면 실행 모드로 전환됩니다. 그렇지 않으면 녹화 모드로 전환됩니다.

이는 hot코드 조각의 경우 기본 코드가 캐시 됨을 의미합니다 . 다시 컴파일 할 필요가 없다는 의미입니다. 해시 된 기본 섹션이 페이지 새로 고침 사이에 유지되는지는 확실하지 않습니다. 그러나 나는 그들이 있다고 가정합니다. 누구든지 이것에 대한 증거를 찾을 수 있다면 훌륭합니다.

편집 : 모질라 개발자 Boris Zbarsky는 Gecko가 컴파일 된 스크립트를 아직 캐시하지 않는다고 언급 한 것으로 알려졌습니다 . 이 SO 답변 에서 가져온 .


Safari : JavaScriptCore / SquirelFish 엔진

이 구현에 대한 최상의 답변은 이미 다른 사람에 의해 제공되었다고 생각합니다. .

우리는 현재 바이트 코드 (또는 네이티브 코드)를 캐시하지 않습니다. 그것은이입니다
우리가 고려한 옵션, 그러나, 현재, 코드 생성은이다
우리가 추구하지 않는, 그래서 JS 실행 시간 (<2 %)의 사소한 부분
순간이.

이것은 Maciej Stachowiak에 의해 작성되었습니다 Safari의 수석 개발자 인 . 그래서 우리는 그것을 사실로 받아 들일 수 있다고 생각합니다.

다른 정보를 찾을 수 없지만 최신 SquirrelFish Extreme엔진 의 속도 향상에 대한 자세한 내용은 여기 를 참조하거나 모험적인 느낌이 드는 경우 여기 에서 소스 코드를 찾아보십시오 .


IE : 차크라 엔진

이 필드에는 IE9의 JavaScript 엔진 (Chakra)에 관한 최신 정보가 없습니다. 누구든지 아는 것이 있으면 의견을 말하십시오.

이것은 비공식적이지만 IE의 오래된 엔진 구현의 경우 Eric Lippert ( JScript의 MS 개발자 )는 블로그에 다음과 같이 답변 합니다. 있다는 :

JScript Classic은 JScript Classic 프로그램이 실행되기 전에 코드를 완전히 구문 검사하고 전체 구문 분석 트리를 생성하며 바이트 코드를 생성한다는 점에서 컴파일 된 언어처럼 작동합니다. 그런 다음 바이트 코드 인터프리터를 통해 바이트 코드를 실행합니다. 그런 의미에서 JScript는 Java만큼 "컴파일 된"것입니다. 차이점은 JScript에서는 독점 바이트 코드를 유지하거나 검사 할 수 없다는 것 입니다. 또한 바이트 코드는 JVM 바이트 코드보다 훨씬 높은 수준입니다 .JScript Classic 바이트 코드 언어는 구문 분석 트리의 선형화에 지나지 않으며 JVM 바이트 코드는 분명히 저수준 스택 시스템에서 작동하도록 설계되었습니다.

이것은 바이트 코드가 어떤 식 으로든 지속되지 않으므로 바이트 코드가 캐시되지 않음을 나타냅니다.


10
+1, 훌륭한 글쓰기. 그러나 Firefox와 관련 하여 Mozilla Developer Boris Zbarsky가 Gecko가 현재이 작업을 수행하지 않는다고 설명하는 StackOverflow 질문을 참조하십시오 .
cha0site

고마워, 나는 여행에서 그것을 보았지만 다른 증거를 찾을 수 없었습니다. 답을 편집하겠습니다.
Jivings 2013

1
IE에 대해 무슨 말을했는지 2003 년에 말한 것을 참고 : IE9의 JS 엔진 첫 번째 릴리스는 2011 년 IE9에 있었다
gsnedders

또한 Opera는 단순히 재로드하는 것 이상으로 JS 바이트 코드를 캐시합니다. 그러나 생성 된 기계 코드는 캐시되지 않습니다.
gsnedders 2012

2
@Jivings 위의 내용을 소스로 사용하십시오. (필자는 Carakan 팀에있는 사람 중 하나입니다.)
gsnedders

12

Opera는 다른 답변에서 언급했듯이 그것을 수행합니다. ( 소스 )

Firefox (SpiderMonkey 엔진)는 바이트 코드를 캐시 하지 않습니다 . ( 소스 )

WebKit (Safari, Konqueror)은 바이트 코드를 캐시 하지 않습니다 . ( 소스 )

IE [6/7/8] 또는 V8 (Chrome)에 대해 잘 모르겠습니다. V8은 그렇지 않지만 IE는 일종의 캐싱을 수행 할 수 있다고 생각합니다. IE는 폐쇄 소스이므로 확실하지 않지만 V8에서는 기계 코드로 직접 컴파일되기 때문에 "컴파일 된"코드를 캐시하는 것이 이치에 맞지 않을 수 있습니다.


1
IE6–8은 거의 확실하지 않습니다. IE9는 가능하지만 어느 쪽의 증거도 없습니다. 컴파일 된 JS는 꽤 자주 크기 때문에 어디에도 캐시되지 않을 수 있습니다.
gsnedders

@gsnedders : IE8이 기술적으로 그것을 할 수 없다고 확신하지 못합니다. 공식이 아닌 가까운 바이트 코드로 컴파일 되기 때문에 캐시하지 않는 기술적 인 이유가 없습니다. IE9는 네이티브 코드로 컴파일하기 위해 JIT를 추가하는 것 같습니다.
cha0site

2
바이트 코드는 IE에서 영원히 사용되었습니다. IE8의 새로운 기능은 없습니다. 단지 인터프리터에게 인터프리터의 성능이 구문 분석 시간보다 훨씬 느리다는 것은 단지 관련이 없습니다. IE9에는 완전히 새로운 (처음부터) JS 엔진이 있으므로이 둘 사이에는 아무것도 없습니다.
gsnedders 2013

3

내가 아는 한 Opera 만 구문 분석 된 JavaScript를 캐시합니다. 여기에서 "캐시 된 컴파일 된 프로그램"섹션을 참조 하십시오 .


감사합니다. 다른 브라우저 제품군에 대한 자세한 정보가 있습니까?
ajreal


0

정답은 "항상 그런 것은 아닙니다"라고 생각합니다. 내가 이해 한 바에 따르면 브라우저와 서버는 캐시되는 대상을 결정하는 역할을합니다. 매번 파일을 다시로드 해야하는 경우 Apache 내에서 파일을 구성 할 수 있어야한다고 생각합니다 (예 : Apache). 물론, 사용자의 브라우저가 해당 설정을 무시하도록 구성 될 수 있다고 가정하지만 아마도 가능성이 낮습니다.

따라서 대부분의 실제 경우 자바 스크립트 파일 자체가 캐시되지만 페이지가로드 될 때마다 동적으로 해석됩니다.


0

브라우저는 확실히 캐싱을 사용하지만, 브라우저는 페이지를 새로 고칠 때마다 JavaScript를 구문 분석합니다. 브라우저가 페이지를로드 할 때마다 2 개의 1.Content Tree와 2.render tree가 생성됩니다.

이 렌더 트리는 dom 요소의 시각적 레이아웃에 대한 정보로 구성됩니다. 따라서 페이지가로드 될 때마다 자바 스크립트가 구문 분석되고 자바 스크립트에 의한 동적 변경 사항은 dom 요소 배치, 요소 표시 / 숨기기, 요소 추가 / 제거와 같이 브라우저가 렌더링 트리를 다시 생성하게합니다. 그러나 FF 및 크롬과 같은 현대적인 브라우저는 약간 다르게 처리하며 점진적 렌더링 개념을 가지고 있으므로 위에서 언급 한 js의 동적 변경이있을 때마다 해당 요소 만 렌더링되고 다시 페인트됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.