Skip to content

Latest commit

 

History

History
246 lines (182 loc) · 9.7 KB

220826.md

File metadata and controls

246 lines (182 loc) · 9.7 KB

1. 브라우저 렌더링 원리

1-1. 홈페이지가 사용자에게 보이는 순서에 대해서 설명해주세요. (브라우저 렌더링 과정)

브라우저의 주요 기능

  • 사용자가 선택한 자원을 서버에 요청하고 브라우저에 표시하는 것
    • 자원은 보통 HTML 문서지만 PDF나 이미지 또는 다른 형태일 수 있다.
    • 자원의 주소는 URI(Uniform Resource Identifier)에 의해 정해진다.

브라우저의 기본 구조

Untitled

  1. 사용자 인터페이스 - 주소 표시줄, 이전/다음 버튼, 북마크 메뉴 등. 요청한 페이지를 보여주는 창을 제외한 나머지 모든 부분.
  2. 브라우저 엔진 - 사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어.
  3. 렌더링 엔진 - 요청한 콘텐츠를 표시. 예를 들어 HTML을 요청하면 HTML과 CSS를 파싱하여 화면에 표시함.
  4. 통신 - HTTP 요청과 같은 네트워크 호출에 사용됨.
  5. UI 백엔드 - 콤보 박스와 창 같은 기본적인 장치를 그림.
  6. 자바스크립트 해석기 - 자바스크립트 코드를 해석하고 실행.
  7. 자료 저장소 - 쿠키 등 모든 종류의 자원을 저장하는 계층.

렌더링 엔진

  • 요청받은 내용을 브라우저 화면에 표시하는 일

  • 파이어폭스는 모질라에서 직접 만든 게코(Gecko) 엔진을 사용하고 사파리와 크롬은 웹킷(Webkit) 엔진을 사용한다.

  • 동작 과정

    Untitled

    • 렌더링 엔진은 HTML 문서를 파싱하고 “콘텐츠 트리” 내부에서 태그를 DOM 노드로 변환한 후 외부 CSS 파일과 함께 포함된 스타일 요소도 파싱한다.
    • 스타일 정보와 HTML 표시 규칙은 “렌더 트리”라고 부르는 또 다른 트리를 생성한다.
      • 렌더 트리는 색상 또는 면적과 같은 시각적 속성이 있는 사각형을 포함하고 있는데 정해진 순서대로 화면에 표시된다.
    • 렌더 트리 생성이 끝나면 배치가 시작되는데 이것은 각 노드가 화면의 정확한 위치에 표시되는 것을 의미한다.
    • 다음은 UI 백엔드에서 렌더 트리의 각 노드를 가로지르며 형상을 만들어 내는 그리기 과정이 진행된다.
  • 일련의 과정들이 점진적으로 진행되는 것을 아는 것이 중요하다.

  • 렌더링 엔진은 좀 더 나은 사용자 경험을 위해 가능하면 빠르게 내용을 표시하는데 모든 HTML을 파싱할 때까지 기다리지 않고 배치와 그리기 과정을 시작한다. 네트워크로부터 나머지 내용이 전송되기를 기다리는 동시에 받은 내용의 일부를 먼저 화면에 표시한다.

  • 웹킷 동작 과정

    Untitled


정리

  1. 주소창에 원하는 주소를 입력합니다. (ex. www.naver.com)
  2. 입력한 주소의 정확한 주소를 DNS서버에서 ip주소로 변환하여 실제 서버를 찾습니다.
  3. 서버에서 클라이언트가 요청한 자원을 보내줍니다. (보통 HTML문서)
  4. 클라이언트는 HTML문서를 파싱하여 DOM을 생성합니다.
    1. 중간에 CSS나 JS스크립트를 다운받는 태그를 만나면 DOM 생성을 중지하고 해당 자원들을 다운로드합니다.
  5. HTML → DOM, CSS → CSSOM 을 생성합니다.
  6. 이렇게 만들어진 DOM과 CSSOM은 브라우저에 시각적으로 출력하기(렌더링)위해 렌더트리로 결합합니다.
  7. 각 노드를 배치한 후에 UI 백엔드를 통해 그립니다.

참고 사이트

2. 호이스팅에 대해서 설명해보세요.

호이스팅(Hoisting)

자바스크립트 및 액션스크립트코드를 인터프리터가 로드할 때, 변수의 정의가 그 범위에 따라 선언과 할당으로 분리되어 변수의 선언을 항상 컨텍스트 내의 최상위로 끌어올리는 것을 의미한다. 이는 오로지 변수에만 해당되는 것은 아니고 함수도 가능하며, 자바스크립트에서 함수의 호출을 첫 줄에서 하고 마지막 줄에 함수를 정의해도 문제없이 작동되도록 하는 유용한 특성이다.

호이스팅이란?

  • 자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모두 모아서 유효 범위의 최상단에 선언한다.
    • 자바스크립트 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(); // 함수 호출

함수표현식

  • 함수표현식은 함수선언문과 달리 선언과 호출 순서에 따라서 정상적으로 함수가 실행되지 않을 수 있다.
    • 함수표현식에서는 선언과 할당의 분리가 일어난다.
  1. 함수표현식의 선언이 호출보다 위에 있는 경우 - 정상 출력
/* 정상 */
function printName(firstname) {
  // 함수선언문
  var inner = function () {
    // 함수표현식
    return 'inner value';
  };

  var result = inner(); // 함수 "호출"
  console.log('name is ' + result);
}

printName(); // > "name is inner value"
  1. 함수표현식의 선언이 호출보다 아래에 있는 경우 (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’로 지정되기 때문
  1. 함수표현식의 선언이 호출보다 아래에 있는 경우 (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를 사용한다.