[20231222 TIL] 브라우저 렌더링 / HTML script 비동기 호출 / JavaScript Data Type

Haizel·2023년 12월 22일
1
post-thumbnail

01. 브라우저 렌더링 과정


먼저 HTML/CSS/JS 파일이 어떻게 브라우저를 통해 화면에 보여지는지 이해하는 과정이 필요하다.

브라우저 렌더링이란, HTML/CSS/Javascript 파일 등을 브라우저 화면에 그리는 과정을 말한다.

  1. 사용자가 브라우저에 사이트를 접속하면, 브라우저는 서버로부터 HTML/CSS/Javascript 등 필요한 리소스를 다운 받는다.

  2. 브라우저의 브라우저 엔진은 HTML 문서를 파싱해 DOM(Document Object Model, 문서 객체 모델)트리를, CSS파일을 파싱해 CSSOM 트리를 형성한다.

  3. 그 후 DOM트리와 CSSOM트리를 결합해 렌더 트리를 형성한다.

  4. 렌더트리를 기반으로 각 요소를 배치하는 레이아웃 단계와, 화면에 요소를 그리는 페인팅 과정까지 완료되면 렌더링이 종료되고, 사용자는 접속한 사이트의 화면을 볼 수 있다.

이때 중요한 점은, HTML 문서 파싱 중, CSS 요소 혹은 Script 요소가 있다면, 브라우저 엔진은 그 즉시 HTML 파싱을 멈추고, 해당 요소를 먼저 읽게 된다.

👉 따라서 HTML 문서 내에 stylesheet파일 혹은 script파일이 어디에 위치하는지에 따라 브라우저 렌더링 속도 등이 달라진다.


02. HTML내 적절한 stylesheet, script 위치는?


결론부터 말하자면, 브라우저의 페이지 로딩 속도를 높이기 위해서는

stylesheet(CSS)는 head 태그에,
script(Javascript)는 body태그 최하단에 위치
하는 것이 좋다.

HTML 문서는 위에서부터 코드가 실행되기 때문에 head 요소가 다 실행된 후 → body 요소가 실행된다.

① stylesheet(CSS) head에

CSS는 화면의 요소를 배치하고 그리는 역할을 하기 때문에, 늦게 호출될 경우 사용자는 스타일이 적용되지 않은 화면을 만날 수 있다.

따라서 가장 먼저 실행되는 head요소 안에 두는 것이 좋다.

② script(Javascript)는 body에

앞서 보았다 싶이 HTML 문서는 head의 요소가 모두 실행되어야 body가 실행된다. 만약 Script 파일이 head 요소이고 용량이 크다면 body 요소의 실행이 늦어지게 되므로, 사용자는 모든 요소가 실행될 때까지 빈 화면에서 =기다리게 된다.

이는 사용자 경험(UX, User Experience)에도 좋지 않기 때문에, script파일은 body 태그의 최하단에 두어, 화면이 다 그려진 후에 호출하는 것이 좋다.


📝 NOTE

💡 브라우저
브라우저는 여러 엔진로 구성되어 있는데, 대표적으로 브라우저 엔진, 렌더링(레이아웃)엔진, JS 엔진 등으로 구성된다.



💡브라우저 엔진
사용자가 어떤 액션을 하는 것부터(인터페이스) ~ 화면에 결과물을 그려 보여주기까지의 과정을 담당한다. 브라우저 엔진은 화면에 결과를 보여주는 렌더링 엔진JS 구문을 분석하는 JS 런타임 엔진(JS 엔진)을 포함한다.


💡렌더링 엔진
사용자가 요청한 HTML문서와 CSS를 파싱하여 화면에 그리는 역할을 한다.
※렌더링 엔진은 종종 브라우저 엔진에 포함된 개념으로 불리기도 하는데, JS 엔진은 브라우저 없이 독립적인 환경에서도 실행(ex, Node.js)될 수 있지만, 렌더링 엔진은 불가능하기 때문이다.


💡 파싱(parsing, 구문분석)

하나의 프로그램을 런타임 환경(ex, 브라우저 내 자바스크립트 엔진)이 실제로 행할 수 있는 내부 포맷으로 분석하고 변환하는 것을 의미한다.

자연어 처리에서 택스트 문서를 분석해 문장 구조, 어휘, 문법, 의미 등을 이해하는 과정으로, 파싱 과정을 통해 검색 엔진이 검색 쿼리를 이해하거나 기계 번연 시스템이 언어를 해석하는데 사용된다.


03. HTML에서 script 비동기 호출


asnycdefer 어트리뷰트를 사용하면 HTML파싱과 자바스크립트 파일의 로드를 비동기적으로 동시에 진행할 수 있다.

① asnyc

<script src="/app.js" async></script> 

asnyc 속성은 HTML 파싱이 끝나지 않았더라도, 스크립트 코드 로드가 완료되는 즉시, 스크립트가 실행된다.

따라서 실행 순서가 보장되지 않기 때문에, HTML 문서 내에 여러 script 파일이 있고, 해당 코드의 순서 보장이 필요한 경우엔 asnyc 속성이 적합하지 않다.

💡 또한 스크립트 코드 안에 DOM API를 통해 DOM을 조작하는 코드가 있다면, 실행 시점에 DOM트리가 제대로 구성되지 않아, 기능이 제대로 작동하지 않는 문제가 발생할 수 있다.


② defer

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

defer 속성은 스크립트 파일의 로드가 완료되어도 HTML 파싱이 끝날 때까지 실행을 지연했다가, HTML 파싱이 모두 끝나면 스크립트를 실행한다.

따라서 asnyc 속성과 달리 순서를 보장할 수 있고, 기능 이슈 문제를 해결할 수 있다.


04. 자바스크립트의 데이터 타입(Data Type)


JavaScript는 동적 타입이 있는 동적 언어이다. 따라서 JavaScript의 변수는 ① 어떤 특정 타입과 연결되지 않으며, ② 모든 타입의 값으로 할당(또는 재할당)이 가능하다.

let foo = 42; // number
foo = "bar"; // string
foo = true; // boolean

① 원시 자료형 (Primitive data type)

원시 자료형 타입은 변경 불가능한 값 (immutable value)이며, pass-by-value(값에 의한 전달)로 이루어진다.

• string (문자열)

텍스트 데이터를 나타내며, 각 문자마다 인덱스를 가진다.(인덱스는 0부터 시작한다)


• Number (숫자)

±(2의 1074승)범위의 값을 나타내며, 해당 범위를 넘어가면 양수값은 +Infinity, 음수값은 -Infinity로 변환된다.

Number 타입은 소수점이 없는 정수 타입과 소수점을 갖는 부동 소수점(float)으로 나뉜다.

  • Number.MAX_VALUE보다 큰 양수 값 : +Infinity로 변환
  • Number.MIN_VALUE보다 작은 양수 값 : +0으로 변환
  • Number.MAX_VALUE보다 작은 음수 값 : -Infinity로 변환
  • Number.MIN_VALUE보다 큰 음수 값 : -0으로 변환

• Boolean

논리 요소를 나타내며, true와 false 두 가지의 값을 가진다.

🚨 false로 변환되는 값

0, null, NaN, undefine, 빈문자열('')falsy한 값으로 간주된다.


• Undefined

자바스크립트에서의 undefinednull은 모두 값이 비어있음을 나타대는 데이터 타입으로, 다만 차이점이 존재한다.

undefined는 기본적으로 값이 할당되지 않은 변수의 값으로 사용되며, undefined타입의 변수의 값 또한 undefined이다.

따라서 자바스크립트에서 undefined는 타입인 동시에 값을 나타내는 데이터 타입이다.

let temp; 
console.log(temp); // undefined (temp에 값이 할당되지 않았음)

temp = undefined;
console.log(temp); // undefined (temp에 값으로 undefined가 할당됨)

• Null

undefined와 마찬가지로 값이 비어있음을 의미하지만, null 타입은 명시적으로 값이 비어있음을 나타낸다.

🚨 Null 타입 사용 시 주의점

null 타입의 데이터 사용시 주의할 점은 null값을 할당한 변수의 데이터 타입은 obejct이다.
따라서 null 타입 변수는 typeof 연산자로 데이터 타입을 확인할 수 없기 때문에 일치 연산자(===)를 사용해야 한다,

let temp = null;

console.log(typeof tmp); // object
console.log(tmp === null); // true
console.log(tmp); // null

• Symbol

Symbol은 ECMA Script 6에서 등장한 새로운 데이터 타입으로, 충돌 위험이 없는 고유한 프로퍼티를 만들기 위한 데이터 타입이다.


let tmp = Symbol('tmp');

console.log(typeof tmp); // symbol
console.log(tmp === Symbol('tmp')); // false : 고유한 값으로 같지 않다.

② 참조 자료형 (Reference data type)

javascript에서는 기본 데이터 타입(원시 자료형)을 제외한 모든 값은 객체로 취급되며, Property와 Method를 포함할 수 있는 독립적 주체이다.

객체는 참조에 의한 전달 (pass-by-reference)방식으로 전달된다.

따라서 객체 뿐만 아니라, 배열이나 함수 등도 모두 객체로 표현된다.

• Object(객체)

객체는 중괄호{}로 표현할 수 있으며, key-value 한쌍의 객체 데이터인 속성(property)을 가진다.

let obj = {
  name: 'John Doe',
  age: 30,
  passed: true,
  getInfo: function () {
    return this.name + ', ' + this.age;
  },
};

console.log(typeof obj); // object

05. Null vs Undefined vs undeclared vs NaN


언뜻보면 비슷해보이는 4가지 데이터 타입의 차이점을 알아보자.

① Null

null은 객체 형태의 빈 값으로, 값이 없는 것을 의도적으로 명시하기 위해 사용한다.

let name = null;
console.log(name) // null
console.log(typeof name) //object

② Undefined (미정의 변수)

undefined는 변수를 선언하고 값을 할당하기 이전의 값으로, 변수에 값을 할당하지 않은 상태를 말한다.

변수는 변수 선언 - 변수 초기화 - 변수 할당 3단계를 거쳐 생성되는데, 2번째 단계에서 자바스크립트 엔진이 변수를 초기화할 때 undefined를 사용한다.

let name;
console.log(name); //undefined
console.log(typeof name); //undefined

③ undelared (미선언 변수)

접근 가능한 스코프 내에 변수의 선언조차 하지 않은 상태로, undefined 타입을 갖는다.

console.log(name); //ReferenceError: name is not defined
console.log(typeof name); //undefined

④ NaN (Not a Number)

표현할 수 없는 수치형 결과를 나타내는 타입으로, 해당 값이 유효한 숫자가 아님을 의미한다.

주의할 점은, NaN의 데이터 타입은 Number타입이지만, 컴퓨터로는 표현할 수 없는 숫자값을 의미한다.

let age = NaN;
console.log(age); //NaN
Console.log(typeof age); // number

✴︎ undefined == null vs undefined === null

console.log(undefined == null); //true 
console.log(undefined === null); //false

• 동등 연산자(==)

동등 연산자는 피연산자를 비교할 때, JavaScript 엔진에 의해 암묵적인 타입 변환이 먼저 이뤄진다.
따라서 좌항과 우항의 데이터 타입이 다르더라도 값이 같다면 true를 반환한다.

let name = null;
console.log(typeof name) //object

let name;
console.log(typeof name); //undefined

따라서 null(type of object)과 undefined(type of undefined)의 데이터 타입은 다르지만, 자동형변환을 거쳐 값을 비교하면, 두 타입 모두 값이 없기 때문에 동등 연산자는 일치한다고 판단하여 true를 반환한다.

🚨 nullundefined의 데이터 타입 및 값

데이터 타입
nullobjectfalse
undefinedundefinedfalse

• 일치 연산자(===)

일치 연산자는 피연산자의 데이터 타입과 값이 모두 같을 경우에 true를 반환한다.

nullundefined의 데이터 타입은 다르기 때문에 일치 연산자는 false를 반환한다.


06. 자바스크립트의 변수 선언 규칙


자바스크립트는 변수 선언 시, 일반적으로 카멜 표기법(CamelCase)를 따른다.

  1. 변수명의 첫문자는 소문자로 시작하며, 숫자로는 시작할 수 없다.
  2. 두개 이상의 단어 사용 시 띄어쓰기 대신 대문자로 단어를 구분한다.
  3. 특수문자는 &과 _만 가능하다.

※ CamelCase외에도 PascalCase, snake_case, kebab-case 등 다양한 표기법(naming convention)이 있다.



※ 참고문서

profile
한입 크기로 베어먹는 개발지식 🍰

0개의 댓글

관련 채용 정보