FrontEnd Develop/JavaScript DeepDive

JS THEME #3. 브라우저 심층분석

Frisbeen 2025. 2. 1. 17:17

브라우저의 역할?

모든 브라우저는 자바스크립트를 해석하고 실행할 수 있는 자바스크립트 엔진을 내장하고 있다.

브라우저뿐만 아니라 Node.js도 자바스크립트 엔진을 내장하고 있다. 따라서 자바스크립트는 브라우저와 Node.js 환경에서 실행할 수 있다.

기본적으로 브라우저에서 동작하는 코드는 Node.js 환경에서도 동작한다.

Node.js와의 차이

브라우저와 Node.js는 존재 목적이 다르다.

브라우저는 HTML, CSS, 자바스크립트를 실행하여 웹 페이지를 화면에 렌더링하는 것이 주된 목적이지만, Node.js는 서버 개발 환경을 제공하는 것이 주된 목적이다.

따라서 브라우저와 Node.js 모두 자바스크립트의 코어인 ECMAScript를 실행할 수 있지만 브라우저와 Node.js에서 ECMAScript 이외에 추가적으로 제공하는 기능은 호환되지 않는다.

크롭 브라우저

개발자 도구

크롬 브라우저가 제공하는 개발자 도구(DevTools)은 자바스크립트 개발에 필수적인 강력한 도구이다. 개발자 도구는 브라우저에 기본 내장되어 있으므로 별도의 설치가 필요없다. 개발자 도구는 아래의 단축키로 오픈할 수 있다.

패널 설명

Elements 로딩된 웹 페이지의 DOM과 CSS를 편집하여 렌더링된 뷰를 확인해 볼 수 있다. 단, 편집한 내용이 저장되지는 않는다. 웹 페이지가 의도된 대로 렌더링되지 않았다면 이 패널을 확인하여 유용한 힌트를 얻을 수 있다.  
Console 로딩된 웹 페이지의 에러를 확인하거나 자바스크립트 소스코드에 포함시킨 console.log 메소드의 결과를 확인해 볼 수 있다.  
Sources 로딩된 웹 페이지의 자바스크립트 코드를 디버깅할 수 있다.  
Network 로딩된 웹 페이지에 관련한 네트워크 요청(request) 정보와 퍼포먼스를 확인할 수 있다.  
Application 웹 스토리지, 세션, 쿠키를 확인하고 관리할 수 있다.  

그 중 콘솔

개발자 도구의 Console(콘솔) 패널은 자바스크립트 코드에서 에러가 발생하여 애플리케이션이 정상적으로 동작하지 않을 때 가장 우선적으로 살펴보아야 할 곳이다.

→ 디버깅의 시작점

구현 단계에서는 에러가 빈번하게 발생하므로 항상 콘솔을 열어둔 상태에서 개발을 진행하는 것이 좋다. 콘솔을 열어두지 않으면 에러가 발생했는지 조차 알 수 없는 경우가 있다.

에러가 발생하지 않아도 ..

에러가 발생한 경우가 아니더라도 콘솔은 매우 유용하다. 구현 단계에서 디버깅을 실행하는 것보다 간편하게 값을 확인하며 개발을 진행하기 위해 console.log 함수를 사용하는 경우가 많다. console.log(…)는 소괄호 안에 있는 코드의 실행 결과를 콘솔에 출력하는 함수이다. 이 함수를 사용해 확인하고 싶은 값을 콘솔에 출력해 확인할 수 있다.

콘솔은 자바스크립트 코드를 직접 입력하여 그 결과를 확인할 수 있는 REPL(Read Eval Print Loop: 입력 수행 출력 반복) 환경으로 사용할 수도 있다. 개발자 도구의 Console 패널을 클릭하면 아래와 같이 프롬프트(>)가 깜박이는 것을 확인할 수 있다.

Node.js와 Npm?

Node.js는 주로 서버 사이드 애플리케이션 개발에 사용되며 이에 필요한 모듈, 파일 시스템, HTTP 등 빌트인 API를 제공한다. Node.js는 데이터를 실시간 처리하여 빈번한 I/O가 발생하는 SPA(Single Page Application)에 적합하다. 하지만 CPU 사용률이 높은 애플리케이션에는 권장하지 않는다.

Node.js는 백엔드 영역의 서버 애플리케이션 개발뿐만 아니라 프런트엔드 영역의 다양한 도구나 라이브러리도 Node.js 환경에서 동작한다. 따라서 Node.js는 프런트엔드 모던 자바스크립트 개발에 필수적인 환경이라고 할 수 있다.

npm(node package manager)은 자바스크립트 패키지 매니저이다. Node.js에서 사용할 수 있는 모듈들을 패키지화하여 모아둔 저장소 역할과 패키지 설치 및 관리를 위한 CLI(Command line interface)를 제공한다. 자신이 작성한 패키지를 공개할 수도 있고 필요한 패키지를 검색하여 재사용할 수도 있다.

브라우저는 어떻게 동작할까?

구글의 Chrome V8 자바스크립트 엔진으로 빌드된 자바스크립트 런타임 환경(Runtime Environment)인 Node.js의 등장으로 자바스크립트는 웹 브라우저를 벗어나 서버 사이드 애플리케이션 개발에서도 사용되는 범용 개발 언어가 되었다.

→ 하지만 자바스크립트가 가장 많이 사용되는 분야는 역시 웹 브라우저 환경에서 동작하는 웹 페이지/애플리케이션이다.

대부분의 프로그래밍 언어는 운영체제(Operating System, OS) 위에서 실행되지만 웹 애플리케이션의 자바스크립트는 브라우저에서 HTML, CSS와 함께 실행된다. 따라서 브라우저 환경을 고려할 때 보다 효율적인 자바스크립트 프로그래밍이 가능하다.

중요한 핵심기능은..

사용자가 참조하고자하는 웹페이지를 서버에 요청하고 서버의 응답을 받아 브라우저에 표시하는 것이다.

브라우저는 서버로부터 HTML,CSS,JavaScript, 이미지 파일 등등을 응답받는다.

HTML CSS 파일은 렌더링 엔진의 HTML parser에 의해 Parsing되어 DOM, CSSOM 트리로 변환되며 렌더 트리로 결합된다.

 

한편 자바스크립트는..

렌더링 엔전이 아닌 자바스크립트 엔진이 따로 처리하는데, HTML 파서는 script 태그를 만나면 자바스크립트 코드를 실행하기 위해 DOM 생성 프로세스를 중지하고 자바스크립트 엔진으로 제어권한을 넘김.

넘겨받은 자바스크립트엔진은 script 태그 내의 자바스크립트 코드 또는 script 태그의 src 어트리뷰트에 정의된 자바스크립트 파일을 로드하고 파싱하여 실행한다.

실행이 끝났으면 다시 HTML 파서의 역할로 제어 권한을 넘긴 후 브라우저가 중지했던 시점부터 재시작한다.

→ 해당 실행은 명백히 동기적으로 동작하겠다. 아래 좀 더 쉽게 설명한 버전

동기적으로 작동한다는 뜻은 ONE BY ONE의 의미다.

1️⃣ HTML 파싱

• 브라우저는 **HTML 파일을 위에서 아래로 읽으며 **DOM(Document Object Model)을 생성함

• <script> 태그를 만나면 JavaScript 실행이 끝날 때까지 HTML 파싱이 중단됨

2️⃣ CSS 파싱

HTML을 해석하는 동안 CSS도 다운로드하고 해석하며, CSSOM(CSS Object Model) 생성

• CSS가 완성되기 전까지는 렌더링 블록(Rending Block) 발생 가능 → 화면이 즉시 그려지지 않음

3️⃣ JS 실행

<script> 태그를 만나면 해당 JavaScript를 로드하고 실행

• JavaScript는 DOM을 조작할 수 있으므로, 실행 중에 HTML이 변경될 수도 있음

• 이 과정에서 HTML 파싱이 일시 중단!

4️⃣ 렌더링(화면에 출력)

DOM + CSSOM → Render Tree 형성

• Render Tree가 최종적으로 **Layout(배치) & Paint(그리기)**를 진행하면서 브라우저 화면에 표시됨

브라우저의 동기(synchronoun)적 동작과 script의 최적의 위치

위 설명으로 우린 브라우저는 HTML,CSS, JS의 렌더링 프로세스를 동기적으로 작동한다는것을 알았다. 이에 따라 script tag의 위치가 매우 중요하다는 것을 간접적으로 이해할수 있다.

그렇다면 어디에 위치해야하는데요 → body tag 아래 혹으느 바로 위에!

그 이유는 아래와 같다.

  • HTML 요소들이 스크립트 로딩 지연으로 인해 렌더링에 지장 받는 일이 발생하지 않음
  • 페이지 로딩 시간이 단축된다.
  • DOM이 완성되지 않은 상태에서 자바스크립트가 DOM을 조작한다면 에러가 발생한다.

저는 싫은데요 하실 분들을 위한 설명

✅ <head>에 script를 넣을 경우

• JavaScript를 실행하느라 HTML 파싱이 멈춤

DOM이 완성되지 않으면, JS가 요소를 찾지 못해 오류 발생 가능

• 해결 방법 → defer 또는 async 속성을 사용 가능

✅ </body> 직전에 script를 넣을 경우 (권장)

HTML이 먼저 렌더링된 후 JavaScript 실행

• HTML 요소들이 모두 파싱된 후에 실행되므로 DOM 조작 오류가 없음

• 페이지 로딩 속도 최적화 가능

그래도 전 head에 script를 배치할래요

💡 defer를 사용하면 head에 위치해도 문제 없음!

<head>
  <script src="script.js" defer></script>
</head>

HTML 파싱을 멈추지 않고 끝까지 진행한 후 JS 실행

✅ <body> 아래에 <script>를 두는 것과 동일한 효과

모던 웹에서는 defer가 가장 추천되는 방식

 

선택은 알아서 하면 될지 않을까.

Reference