- 사용자가 선택한 자원을 서버에 요청하고 브라우저에 표시하는 것
- 자원은 보통 HTML 문서지만 PDF나 이미지 또는 다른 형태일 수 있다.
- 자원의 주소는 URI(Uniform Resource Identifier)에 의해 정해진다.
- 사용자 인터페이스 - 주소 표시줄, 이전/다음 버튼, 북마크 메뉴 등. 요청한 페이지를 보여주는 창을 제외한 나머지 모든 부분.
- 브라우저 엔진 - 사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어.
- 렌더링 엔진 - 요청한 콘텐츠를 표시. 예를 들어 HTML을 요청하면 HTML과 CSS를 파싱하여 화면에 표시함.
- 통신 - HTTP 요청과 같은 네트워크 호출에 사용됨.
- UI 백엔드 - 콤보 박스와 창 같은 기본적인 장치를 그림.
- 자바스크립트 해석기 - 자바스크립트 코드를 해석하고 실행.
- 자료 저장소 - 쿠키 등 모든 종류의 자원을 저장하는 계층.
-
요청받은 내용을 브라우저 화면에 표시하는 일
-
파이어폭스는 모질라에서 직접 만든 게코(Gecko) 엔진을 사용하고 사파리와 크롬은 웹킷(Webkit) 엔진을 사용한다.
-
동작 과정
- 렌더링 엔진은 HTML 문서를 파싱하고 “콘텐츠 트리” 내부에서 태그를 DOM 노드로 변환한 후 외부 CSS 파일과 함께 포함된 스타일 요소도 파싱한다.
- 스타일 정보와 HTML 표시 규칙은 “렌더 트리”라고 부르는 또 다른 트리를 생성한다.
- 렌더 트리는 색상 또는 면적과 같은 시각적 속성이 있는 사각형을 포함하고 있는데 정해진 순서대로 화면에 표시된다.
- 렌더 트리 생성이 끝나면 배치가 시작되는데 이것은 각 노드가 화면의 정확한 위치에 표시되는 것을 의미한다.
- 다음은 UI 백엔드에서 렌더 트리의 각 노드를 가로지르며 형상을 만들어 내는 그리기 과정이 진행된다.
-
일련의 과정들이 점진적으로 진행되는 것을 아는 것이 중요하다.
-
렌더링 엔진은 좀 더 나은 사용자 경험을 위해 가능하면 빠르게 내용을 표시하는데 모든 HTML을 파싱할 때까지 기다리지 않고 배치와 그리기 과정을 시작한다. 네트워크로부터 나머지 내용이 전송되기를 기다리는 동시에 받은 내용의 일부를 먼저 화면에 표시한다.
-
웹킷 동작 과정
정리
- 주소창에 원하는 주소를 입력합니다. (ex. www.naver.com)
- 입력한 주소의 정확한 주소를
DNS서버
에서 ip주소로 변환하여 실제 서버를 찾습니다. - 서버에서 클라이언트가 요청한 자원을 보내줍니다. (보통 HTML문서)
- 클라이언트는 HTML문서를 파싱하여 DOM을 생성합니다.
- 중간에 CSS나 JS스크립트를 다운받는 태그를 만나면 DOM 생성을 중지하고 해당 자원들을 다운로드합니다.
- HTML →
DOM
, CSS →CSSOM
을 생성합니다. - 이렇게 만들어진 DOM과 CSSOM은 브라우저에 시각적으로 출력하기(
렌더링
)위해렌더트리
로 결합합니다. - 각 노드를 배치한 후에 UI 백엔드를 통해 그립니다.
참고 사이트
자바스크립트 및 액션스크립트코드를 인터프리터가 로드할 때, 변수의 정의가 그 범위에 따라 선언과 할당으로 분리되어 변수의 선언을 항상 컨텍스트 내의 최상위로 끌어올리는 것을 의미한다. 이는 오로지 변수에만 해당되는 것은 아니고 함수도 가능하며, 자바스크립트에서 함수의 호출을 첫 줄에서 하고 마지막 줄에 함수를 정의해도 문제없이 작동되도록 하는 유용한 특성이다.
- 자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모두 모아서 유효 범위의 최상단에 선언한다.
- 자바스크립트 Parser가 함수 실행 전 해당 함수를 한 번 훑는다.
- 함수 안에 존재하는 변수/함수 선언에 대한 정보를 기억하고 있다가 실행시킨다.
- 유효 범위: 함수 블록
{}
안에서 유효
- 즉, 함수 내에서 아래쪽에 존재하는 내용 중 필요한 값들을 끌어올리는 것이다.
- 실제로 코드가 끌어올려지는 것은 아니며, 자바스크립트 Parser 내부적으로 끌어올려서 처리하는 것이다.
- 실제 메모리에서는 변화가 없다.
- var 변수 선언과 함수선언문에서만 호이스팅이 일어난다.
- var 변수/함수의 선언만 위로 끌어올려지며, 할당은 끌어올려지지 않는다.
- let/const 변수 선언과 함수표현식에서는 호이스팅이 발생하지 않는다.
함수선언문
- 함수선언문은 코드를 구현한 위치와 관계없이 자바스크립트의 특징인 호이스팅에 따라 브라우저가 자바스크립트를 해석할 때 맨 위로 끌어올려진다.
/* 정상 출력 */
function printName(firstname) {
// 함수선언문
var result = inner(); // "선언 및 할당"
console.log(typeof inner); // > "function"
console.log('name is ' + result); // > "name is inner value"
function inner() {
// 함수선언문
return 'inner value';
}
}
printName(); // 함수 호출
함수표현식
- 함수표현식은 함수선언문과 달리 선언과 호출 순서에 따라서 정상적으로 함수가 실행되지 않을 수 있다.
- 함수표현식에서는 선언과 할당의 분리가 일어난다.
- 함수표현식의 선언이 호출보다 위에 있는 경우 - 정상 출력
/* 정상 */
function printName(firstname) {
// 함수선언문
var inner = function () {
// 함수표현식
return 'inner value';
};
var result = inner(); // 함수 "호출"
console.log('name is ' + result);
}
printName(); // > "name is inner value"
- 함수표현식의 선언이 호출보다 아래에 있는 경우 (var 변수에 할당)
function printName(firstname) {
console.log(inner);
var result = inner();
console.log('name is ' + result);
var inner = function () {
return 'inner value';
};
}
printName();
제대로 동작이 될까요? 어떤 에러가 날까요?
/* 오류 */
function printName(firstname) {
// 함수선언문
console.log(inner); // > "undefined": 선언은 되어 있지만 값이 할당되어있지 않은 경우
var result = inner(); // ERROR!!
console.log('name is ' + result);
var inner = function () {
// 함수표현식
return 'inner value';
};
}
printName(); // > TypeError: inner is not a function
- “inner is not defined”이라는 오류가 아닌 “inner is not a function”이라는 TypeError가 나오는 이유?
- printName이 실행되는 순간 Hoisting에 의해 inner는 ‘undefined’로 지정되기 때문
- 함수표현식의 선언이 호출보다 아래에 있는 경우 (const/let 변수에 할당)
function printName(firstname) {
console.log(inner);
let result = inner();
console.log('name is ' + result);
let inner = function () {
return 'inner value';
};
}
printName();
제대로 동작이 될까요? 어떤 에러가 날까요?
/* 오류 */
function printName(firstname) {
// 함수선언문
console.log(inner); // ERROR!!
let result = inner();
console.log('name is ' + result);
let inner = function () {
// 함수표현식
return 'inner value';
};
}
printName(); // > ReferenceError: inner is not defined
- let/const의 경우, 호이스팅이 일어나지 않기 때문에 console.log(inner)에서 inner에 대한 선언이 되어있지 않기 때문에 inner is not defined라는 ReferenceError가 발생한다.
같은 이름의 var 변수 선언과 함수 선언에서의 호이스팅
var myName = 'hi';
function myName() {
console.log('yuddomack');
}
function yourName() {
console.log('everyone');
}
var yourName = 'bye';
console.log(typeof myName); // > ?
console.log(typeof yourName); // > ?
- 변수 선언이 함수 선언보다 위로 끌어올려진다.
값이 할당되어 있지 않은 변수와 할당되어 있는 변수에서의 호이스팅
var myName = 'Heee'; // 값 할당
var yourName; // 값 할당 X
function myName() {
// 같은 이름의 함수 선언
console.log('myName Function');
}
function yourName() {
// 같은 이름의 함수 선언
console.log('yourName Function');
}
console.log(typeof myName); // > ?
console.log(typeof yourName); // > ?
-
값이 할당되어 있지 않은 변수의 경우, 함수선언문이 변수를 덮어쓴다.
-
값이 할당되어 있는 변수의 경우, 변수가 함수선언문을 덮어쓴다.
-
코드의 가독성과 유지보수를 위해 호이스팅이 일어나지 않도록 함수와 변수를 가급적 코드 상단부에서 선언하여 호이스팅으로 인한 스코프 꼬임 현상을 방지하고 var대신 let/const를 사용한다.