OOP에 대해 설명하세요

카테고리 CS

OOP란 무엇인가요?

OOP(Obeject-Oriented-Programming)는 객체지향 프로그래밍을 말한다.

객체지향 프로그래밍이란, 실세계에 존재하고 우리가 인지하는 객체라는 대상을 추상화하여 프로그래밍에 접목 시킨 방식으로,

프로그래밍 관점에서 데이터를 추상화할 때, 상태와 행동을 가진 객체를 만들고 이 객체들간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방식을 객체지향 프로그래밍이라 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const TV = {
name: "Samsung UHD Ultra",
price: "1,000,000원",
state: "off",
volume: 10,
turnOn() {
this.state = "on";
},
turnOff() {
this.state = "off";
},
volumeUp(num = 10) {
this.volume += num;
},
volumeDown(num = 10) {
this.volume -= num;
},
};

위는 TV라는 데이터를 상태와 행동으로 추상화한 객체로 표현한 것이다.

OOP의 특징은 무엇인가요?

1. 캡슐화

캡슐화란 객체를 특정한 목적을 위해 변수 혹은 메서드 하나로 묶는 것을 말한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const counter = (() => {
let count = 0;

return {
getCount() {
return count;
},
increase() {
count += 1;
},
decrease() {
count -= 1;
},
};
})();

위 예시는 counter를 캡슐화한 예시이다. 이렇게 캡슐화를 하게되면 count라는 변수에 대해 참조하거나 변경하는 함수를 통해서만 간접적으로 접근이 가능하도록 하여 해당 데이터를 은닉하고 안전하게 보존하기 위해 사용한다.

2. 추상화

우리는 앞서 TV라는 데이터를 추상화하였다. 하지만 추상화는 예시처럼 간단하지만은 않다. 추상적으로 큰 틀에 공통적인 요소나 필수적인 요소를 담는 것을 말한다.

다시 TV의 예를 들어보겠다. 우리가 실생활의 모든 데이터(TV, 냉장고, 인덕션, 청소기 등)를 모두 개별적으로 만드는 것보단 이들의 공통적인 특성을 가진 큰 틀의 객체를 만들고 해당 객체의 상속을 받고 본인만의 특별한 기능을 추가하는 방법으로 객체를 생성해나가는 것이 중복을 줄이고 확장성의 장점을 살려 추상화를 할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class HomeAppliance {
constructor(name, price) {
this.state = "off";
this.name = name;
this.price = price;
}
turnOn() {
this.state = "on";
}
turnOff() {
this.state = "off";
}
...
}

const TV = new HomeAppliance("Samsung UHD Smart TV", 1000000);
const Refrigerator = new HomeAppliance("Samsung BSpoke", 2000000);
const vacuumCleaner = new HomeAppliance("Dyson", 800000);

위 예시처럼 가전제품이라는 데이터를 추상화하여 객체로 생성한 뒤, 해당 객체의 상속을 받아 공통적인 행동을 할 수 있는 객체를 생성하여 TV, 냉장고, 청소기 데이터를 추상화하였다.

3. 상속 및 다형성

다형성은 같은 동작이지만 다른 결과물을 반환하는 특징을 말한다.

상속과 다형성을 통해 기능을 확장하거나 변경하는 것이 가능하다. 그렇게 되면 코드의 재사용 및 코드 길이 감소되고 유지보수가 용이해지는 장점이 있다.

1
2
3
4
5
6
7
// 숫자를 문자열로 바꾸는 경우
const number = 100;
const string1 = number.toString();

// 날짜를 문자열로 바꾸는 경우
const date = new Date();
const string2 = date.toString();

위 예시는 다형성의 예시이다. toString()이라는 메서드를 사용하여 타입에 따라 적절한 변환 방식을 정의해둠으로써 객체의 종류와 상관없는 추상도가 높은 변환 형식을 구현할 수 있다는 장점이 있다.

이러한 다형성의 개념을 녹여내는 방법은 오버라이딩(Overriding), 오버로딩(Overloading) 두가지가 있다.

오버라이딩(Overriding)

자식 클래스가 부모 클래스에게 상속받은 메서드를 특정 형태로 구현하는 것을 말한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Animal {
constructor(name, legs) {
this.name = name;
this.legs = legs;
}
move() {
console.log("move forward faster!!");
}
eat() {
console.log("eat food");
}
}

class Dog extends Animal {
move() {
console.log("move like a dog!");
}
bark() {
console.log("Wal! Wal!");
}
}

const animal = new Animal("eagle", 2);
const dog = new Dog("seechu", 4);

dog.move(); // move like a dog!
animal.move(); // move forward faster!!

위 예시에서 자식 클래스는 부모 클래스에게 상속받은 move 메서드를 새롭게 정의하였다. 그리고 자식 클래스의 인스턴스와 부모 클래스의 인스턴스에서 각각 move 메서드를 사용했을 때, 각자 클래스에 정의된 move 메서드가 동작하는 것을 알 수 있다.

오버로딩(Overloading)

하나의 클래스안에서 같은 이름의 메서드를 사용하지만 매개변수, Return Type 등의 특징에 따라 다른 용도로 사용되도록 구현하는 것을 말한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Animal {
constructor(name, legs) {
this.name = name;
this.legs = legs;
}

move(direction, distance) {
if (!direction || !distance) {
console.log("move forward faster!!");
} else {
console.log(`move ${direction} for ${distance}`);
}
}

eat() {
console.log("eat food");
}
}

const pig = new Animal("kong-e", 4);

pig.move(); // move forward faster!!
pig.move("right", "10m"); // move right for 10m

위 예시는 자바스크립트에서 오버로딩을 구현한 예시이다. move라는 메서드를 사용할 때, 매개변수가 있고 없고에 따라 다르게 동작하도록 구현하였다.

댓글 공유

SSR과 CSR에 대해 설명하라

카테고리 CS

🐥 SSR과 CSR에 대해 설명하라

SSR은 서버 사이드 렌더링의 줄임말로, 클라이언트가 서버에 요청을 보낼 때 서버에서 HTML,JS 등을 렌더링하고 클라이언트에게 완성된 HTML 파일을 응답해주는 방식이다.

CSR은 서버에 요청을 보내면 서버에서 HTML,JS 리소스 파일등을 받은 이후 브라우저에서 렌더링을 진행하는 것이다. 이후 클라이언트는 서버에게 데이터만 요청하면서 브라우저가 렌더링한 페이지에 서버의 응답으로 받은 데이터만 패칭해주면 된다.

😃 특징

✈️ 초기 로딩 속도

SSR은 클라이언트가 요청한 부분의 페이지만 렌더링해서 보내주면 되므로 초기 로딩 속도가 CSR에 비해서 빠른 반면, CSR은 HTML,JS, 모든 리소스를 한번에 로드하기 때문에 초기 로드 속도가 느리다.

❗️ 서버 부하

SSR은 View가 바뀔 때마다 서버에 요청을 보내고 서버는 그 때마다 응답해줘야하므로 서버의 부하가 높고 UX 측면에서는 깜빡임 현상이 있는 단점이 있다. 반면, CSR은 데이터 요청이 있을 때만 서버에 요청을 하기 때문에 서버 부하가 적다.

📚 SEO

SSR은 서버가 렌더링을 하고 완성된 페이지를 클라이언트에게 보내주는데, 그 안에는 SEO에 사용되는 meta 태그 등이 미리 정의 되어 있어 SEO 측면에서 유리하다. 반면 CSR은 초기에 비어있는 HTML 파일을 보내주고 JS를 다운로드하여 브라우저에서 렌더링이 완료되기 전까지는 빈 파일로 남아있기 때문에, SEO 측면에서 불리하다.

Next.js에서 SSR,CSR

이번 과제에서 Next.js를 사용하면서 새롭게 배우게 된 사실을 정리해본다. Next.js는 기본적으로 SSR을 지원한다. SSR을 지원하는 방법으로는 2가지 방법이 있는데,

첫번째, 클라이언트가 요청할 때마다 서버에서 렌더링을 해주는 진짜 SSR 방식

두번째, 미리 렌더링을 끝내놓은 페이지를 클라이언트가 요청할 때마다 캐싱하여 보여주는 SSG 방식

그리고 CSR까지 지원해준다.

Next.js를 사용하다보니 SSR, CSR, SSG에 대한 이해가 더 잘되는 것 같아서 마무리로 적어보았다.

댓글 공유

Next.js는 왜 사용하나요?

카테고리 CS

Next.js를 왜 사용하나요?

Next.js는 빠르게 웹 애플리케이션을 만들기 위한 React 프레임워크이다.

우리가 웹 애플리케이션을 만들기 위해서는 단순히 React로 코드만 짜서는 만들 수 없다.

UI는 물론, 라우팅, 데이터 패칭, 렌더링, 성능 최적화, 확장성, DX 까지도 고려하여 웹 애플리케이션을 만들어야한다.

그렇기 때문에 우리는 각 부분을 직접 구현할 지 아니면 라이브러리나 프레임워크와 같은 도구를 사용할지 결정해야한다.

즉, 우리는 React로 UI를 구축한 뒤 Next.js의 기능을 점진적으로 도입하여 라우팅, 데이터 가져오기 등 애플레이케이션 요구사항을 해결함과 동시에 UX, DX까지 개선할 수 있다.

Next.js 특징

👍 장점

  • SWR을 사용하여 컴파일, 축소, 코드분할, 번들링 작업을 하고 Babel보다 17배 빠른 컴파일 속도를 갖는다.
  • 페이지 별 SSR, CSR, SSG를 사용할 수 있다. 이를 통해 SEO 최적화 가능
  • React 프로젝트에서 Next.js로 점진적 마이그레이션 용이

👎 단점

  • SSR을 사용하여 서버 부하가 있을 수 있다.
  • 페이지 이동 시 깜빡거림

댓글 공유

객체 불변성에 대해 설명하라.

자바스크립트에서 데이터는 변경 불가능한 원시값, 변경 가능한 참조값으로 구성된다.

변경 가능한 참조값이 바로 객체를 말하는데, 객체는 값을 참조값으로 전달하고 전달 받으므로 객체가 참조를 통해 공유되어 있다면 하나를 바꿨을 때, 다른 것들도 바뀔 위험이 있다.

1
2
3
4
5
6
7
const a = { a: 10, b: 200 };
const c = a;

c.a = 30;

console.log(c); // {a: 30, b: 200}
console.log(a); // {a: 30, b: 200}

위와 같은 문제를 해결하기 위한 방법으로 객체를 불변객체로 만들거나, 참조값을 복사하는 것이 아닌 객체의 값을 복사하여 새로운 객체를 생성하는 방법이 있다.

객체를 불변 객체로 만드는 방법은 Object.freeze메서드와 Object.seal 메서드를 사용하는 방법이 있다. 두 메서드는 직속 프로퍼티에만 적용된다(얕은 방지).

Object.freeze(), Object.seal()의 차이는 Object.freeze()는 해당 객체에 속성 추가, 기존 속성 변경, 삭제가 모두 불가능하지만 Object.seal()은 새로운 속성 추가및 삭제가 불가능하고 기존 속성 변경은 가능하다.

객체의 값을 복사하는 방법으로는 Object.assign()를 사용하는 방법, ES6 Spread 문법이 있다. 이 두가지 방법 역시 얕은 복사이므로, 깊은 복사를 하려면 라이브러리를 사용하거나 새로 추가된 structedClone() 메서드를 사용하는 방법이 있다.

structedClone() 메서드는 Function 객체, DOM Node, 객체들의 몇몇 파라미터 일부 기능에 제한이 있다.

리액트에서 Props, State를 불변객체로 다루는 이유는?

리액트에서는 Props와 State의 변경을 불변성을 이용해 감지하고 리렌더링을 발생시킨다.

만약 불변 객체를 사용하지 않는다면, 객체의 값이 어디에서 바뀌게 되었는지 예상하기 어렵고 해당 객체도 엉망이 될 것이다.

setState는 비동기적으로 State를 변경시키는데, 불변 객체로 다루지 않고 직접 State를 변경시킨다면 이전의 값이 반환될 수 있다.

댓글 공유

이벤트 루프가 비동기 함수를 어떻게 처리하는지 설명하라.

우선 자바스크립트는 한번에 하나의 일을 처리할 수 있는 싱글 스레드 처리방식을 가진다.

그러므로 동기적으로 일을 처리할 때에 시간이 오래 걸리는 처리를 할 경우 다음 일에 블로킹이 발생한다.

이러한 블로킹 현상을 해결하기 위해 비동기식 처리 방식을 사용하고 여러 개의 일이 동시에 처리되는 것처럼 느껴지도록 도와주는 이벤트 루프가 있다.

이벤트 루프는 브라우저에 내장된 기능 중 하나이다.

이벤트 루프

위 사진은 이벤트 루프가 동작하는 방식을 보여주는 사진이다.

  • 콜 스택 : 함수 호출 시 함수 실행 컨텍스트가 콜 스택에 푸시되어 순차적으로 실행된다.
  • 태스크 큐 : 타이머 함수의 콜백 함수 또는 이벤트 핸들러가 일시적으로 보관되는 영역이다. 태스크 큐와는 별도로 프로미스의 후속처리 메서드의 콜백 함수가 일시적으로 보관되는 마이크로 태스크 큐도 존재한다.
  • 이벤트 루프 : 이벤트 루프는 현재 콜 스택에 실행중인 실행 컨텍스트가 있는지, 태스크 큐에 대기중인 함수가 있는지 확인하여 콜 스택이 비어있고 태스크 큐에 대기중인 함수가 있다면 이벤트 루프가 순차적(FIFO)으로 태스크 큐에 대기중인 함수를 콜 스택으로 이동시킨다. 즉, 태스크 큐에 일시 보관된 함수들은 비동기 처리 방식으로 동작한다.

비동기 처리에서 소스코드 평가 및 실행을 제외한 모든 코드는 브라우저 또는 NodeJS가 담당한다. 브라우저는 멀티 스레드로 동작한다.

댓글 공유

모의 면접 2차 회고

카테고리 CS

📌 1분 자기소개 파트

기술면접만 진행하실 줄 알았는데 갑자기 자기소개를 하라하셔서 당황하여 말을 제대로 못했다.

  • ~ 하는 편입니다. 보다는 ~ 합니다. 라고 명료하게 답변하자

📚 기술면접 파트

비동기 함수와 이벤트 루프에 대한 설명해라

  • Web API, setTimeout, 이벤트리스너등의 특수한 경우에서 자바스크립트는 멀티스레드로 동작하는 것처럼 보이는 것이다. 실제로 자바스크립트는 싱글 스레드이다.
  • 일련의 과정을 설명하는데 짜임새가 부족하였다.
  • 자바스크립트는 원래 싱글 스레드인데, 런타임 이전에서 AJAX나 비동기 코드를 위해 불가피하게 멀티 스레드를 두어 사용하게 되었다 라는 보충 설명 해주면 좋을 것 같다.

객체 불변성에 대해 설명해라

  • 리액트와 객체 불변성을 연관짓는 설명이 부족하다.
  • ~ 한다고 생각합니다 대신 ~ 할 수 있습니다로 바꿔서 말하기

This 설명하라

  • 처음에 4가지 분류를 말하였는데 말하다보니 까먹어서 3가지밖에 말하지 못한 부분이 아쉬웠다.
  • 화살표 함수는 this를 가지고 있지 않으므로, 내부의 this는 상위 스코프의 this에 바인딩된다.

var, let, const 비교 설명하라

  • 스코프 설명하면서 함수레벨 스코프, 블록 레벨 스코프가 왜 더 안전한 코드를 짤 수 있도록 하는 지에 대한 설명 보충

함수가 일급 객체인 이유는?

  • 좀 더 자세한 설명이 필요하다.
  • 특징을 2가지 밖에 말하지 못하여 아쉬웠다.

클로저 설명, 장점 및 주의점

  • 주의점 설명이 부족했다. 클로저는 외부 함수의 실행 컨텍스트가 사라져도 내부 함수에 대한 참조가 유지되고 있기 때문에 메모리 누수에 대한 부분도 고려해줘야한다.
  • 리액트내에서도 useEffect 함수 내부에서 클린업 함수를 해주어 메모리 누수를 방지하여야 한다.

CORS 우회 방법 설명하라

  • 프록시 객체라는 설명이 모호해서 아쉬웠다. 프록시 서버에 대한 설명을 프록시 객체로 잘못 답변하였다.

제너레이터에 대해 설명하라

  • 제너레이터 공부하자…

✏️ 총평

  • 정제된 단어로 정리해서 답변을 하면 더 좋을 것 같다.
  • 객체 변경 불가성 중요하니깐 제대로 알아두자. 상태값을 객체로 주로 저장하기 때문에, 이 자체의 참조값을 바꿔야지만 내부적으로 렌더링이 일어난다.
  • 클로저의 주의점에 대해서는 클린업 함수, 메모리 누수 설명 보충하자.
  • 1급 객체에 대한 특징 및 조건 설명을 풍부하게 해보자.
  • CORS 해결 방법에 대한 설명을 제대로 답변하지 못하였으니 공부하자.

댓글 공유

🛠 JWT 토큰 방식이란?

JWT는 JSON Web Token의 약자로, 인증에 필요한 데이터를 암호화한 JSON으로 이루어진 토큰을 말한다.

기존의 세션 인증방식은 인증관련 정보를 세션 저장소라는 DB에 저장하여 서버가 과부하 되거나 서버를 확장하기가 어려웠다.

이러한 문제 때문에 서버자원을 절약하기 위해 사용자 인증에 필요한 정보를 토큰 자체에 담아두는 JWT를 사용하게 되었다.

토큰은 로그인 이후 서버가 만들어주는 문자열이고, 토큰 안에는 사용자의 로그인 정보와 서버의 서명이 들어있다.

JWT 토큰 방식 순서

  1. 사용자가 로그인을 하면 서버는 사용자에게 사용자 로그인 정보 및 서버의 서명이 들어간 토큰을 발급한다.
  2. 사용자는 토큰을 가지고 권한이 필요한 API 작업을 요청한다.
  3. 서버는 토큰의 유효성 검사를 통해 요청에 응답한다.

JWT 토큰 특징

👍 장점

  • 서버에서 사용자 정보를 저장해둘 필요가 없어 서버 스케일링시 큰 문제가 없다.
  • 별도의 I/O 작업 없는 빠른 인증 처리 가능

👎 단점

  • 한번 발급된 토큰은 수정 및 폐기가 불가능하다.(클라이언트에게 있으니깐!)
    • 그렇기 때문에 유효기간을 짧게 설정해주는것이 중요하다.
  • 토큰의 길이가 늘어날 수록 네트워크 부하가 심해진다.

댓글 공유

SPA는 무엇인가요?

카테고리 CS

✏️ SPA란?

Single Page Application의 약자로, 단일 페이지로 구성된 애플리케이션을 말한다.

전통적으로 브라우저는 서버에서 HTML을 받아 렌더링 해주는 역할을 한다. 즉, 사용자가 다른 URL로 이동하거나 사용자 액션에 의해 화면의 UI가 변경될 때마다 서버에 HTML을 요청하고 응답받는 서버측 렌더링(SSR)을 사용한다.

하지만 오늘날 최신 SPA에서는 대화형 요소와 동적인 요소가 많아 클라이언트가 작업을 수행하고 작업에 대한 응답을 받을 수 있는 클라이언트 사이드 렌더링(CSR)을 사용한다.

🤓 SPA 동작 원리

  1. 브라우저는 웹에 필요한 소스코드 및 스타일 시트를 서버로부터 응답받아 초기 페이지를 렌더링한다.
  2. 대화형 요소, 동적인 요소에 의해 새 페이지가 필요해지면, 새 페이지에 필요한 새 데이터는 서버에게 AJAX 요청을 보낸다. 이후 SPA는 초기 페이지 로드시 다운로드한 JavaScript를 통해 응답받은 데이터를 페이지에 동적으로 업데이트한다.

사용자가 다른 페이지로 이동할 때 새로고침이 발생하지 않는다. 페이지의 URL은 HTML5 History API를 통해 업데이트된다.

📚 SPA 특징

👍 장점

  • 앱의 반응속도가 빨라지고 새로고침으로 인한 깜빡임 현상이 사라진다.
  • 페이지 렌더링 시 중복된 데이터를 다시 다운받을 필요가 없어 서버에 대한 HTTP 요청이 줄어든다.
  • 클라이언트와 서버간의 문제를 명확히 구분할 수 있다. 서버 코드를 수정하지 않고도 다양한 플랫폼을 위한 새로운 클라이언트를 쉽게 구축할 수 있다.

👎 단점

  • 초기에 웹에 필요한 모든 데이터를 서버로 부터 로드 받기 때문에 초기 페이지 로드 시간이 길다.
  • 모든 요청을 단일 진입점으로 라우트하고 클라이언트 측 라우팅이 단일 진입점에서 응답받을 수 있도록 서버를 구성하는 추가 단계가 필요하다.
1
2
3
4
5
6
// server.js

// 브라우저 새로고침 시 서버는 index.html 파일을 응답하고 클라이언트는 window.location.pathname을 참조해 라우팅
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "public/index.html"));
});
  • SPA는 JavaScript에 의존하는데 검색 엔진이 크롤링 중에 JavaScript를 실행하지 않기 때문에 해당 웹이 빈 컨텐츠로 표시될 수 있어 SEO 최적화에 부적합하다.

    이를 해결하기 위해 서버측에서 앱을 렌더링하거나 Prerender 같은 서비스를 사용하여 브라우저에서 JavaScript를 렌더링하고 정적 HTML을 저장한 다음 크롤러에게 반환할 수 있다.

댓글 공유

브라우저란?

브라우저는 HTML, CSS, Javascript로 작성된 텍스트 문서를 서버에게 요청하여 응답을 받아 의미있는 단위인 토큰으로 파싱하여 시각적으로 렌더링 해주는 역할을 담당한다.

브라우저 렌더링 과정

1. 요청과 응답

서버에 요청하기 위해 브라우저는 주소창을 제공한다. 주소창에 URL을 입력하면 URL의 호스트 이름이 DNS를 통해 IP주소로 변환되고 IP 주소를 갖는 서버에게 요청을 전송한다.

이렇게 요청을 보내면 서버는 서버의 루트 폴더에 존재하는 정적파일로 응답을 보낸다. 기본적으로 index.html이다.

2. HTML 파싱과 DOM 생성

브라우저 요청에 의해 서버가 응답한 HTML 문서는 문자열로 이루어진 순수한 텍스트이다.

그래서 HTML 문서를 파싱하여 브라우저가 이해할 수 있는 자료구조인 DOM을 생성한다.

  1. 문자열로 변환된 HTML문서를 토큰화한다.
  2. 각 토큰을 객체로 변환하여 노드를 생성한다. 노드는 DOM을 구성하는 기본 요소이다. ex) 문서 노드, 요소 노드 등
  3. HTML 문서는 중첩관계를 통해 부자관계가 형성된다. 이러한 부자관계를 반영하여 모든 노드들을 트리 자료구조로 구성한다. 이러한 노드들로 구성된 트리 자료구조를 DOM이라 부른다.

3. CSS 파싱과 CSSOM 생성

렌더링 엔진은 HTML을 한줄씩 읽어나가며 순차적으로 파싱하여 DOM을 생성해 나간다. DOM을 생성하다가 CSS를 로드하는 link 태그나 style 태그를 만나면 DOM 생성을 일시중단한다.

그 결과 CSS 파일을 서버에 요청하여 응답받은 CSS 파일이나 style 태그 내의 CSS를 HTML과 동일한 과정으로 토큰화 생성 → CSSOM 생성 과정을 거친다. 이후 파싱이 완료되면 HTML 파싱이 중단된 지점부터 다시 HTML을 파싱하기 시작한다.

4. 렌더 트리 생성

앞선 과정에서 생성된 DOM과 CSSOM은 렌더링을 위해 렌더 트리로 결합된다. 이 때 브라우저 화면에 렌더링되지 않는 노드(meta태그, script 태그 등)와 CSS에 의해 표시되지 않는(display:none) 노드들은 포함하지 않는다.

지금까지의 렌더링 과정은 여러번 반복되서 실행될 수 있다. 렌더링이 반복 실행되는 원인은 다음과 같다.

  • 자바스크립트에 의한 노드 추가 또는 삭제
  • 브라우저 창의 리사이징에 의한 viewport 크기 변경
  • HTML 요소의 레이아웃(위치와 크기)을 변경시키는 width, height, margin, padding, border, display, position 등의 스타일 변경

이러한 리렌더링은 비용이 많이 들고 성능에 악영향을 주므로 리렌더링이 적게 발생하도록 하여야한다.

5. 자바스크립트 파싱과 실행

HTML 파싱의 결과물 DOM은 HTML 문서의 구조와 정보뿐 아니라 HTML 요소와 스타일을 변경할 수 있는 프로그래밍 인터페이스로서 DOM API를 제공한다.

즉, DOM API를 사용하여 이미 생성된 DOM을 동적으로 조작할 수 있다.

CSS 파싱과정과 마찬가지로 script 태그 만나면 DOM 생성을 일시 중단한다.

이후 자바스크립트 파일을 서버에 요청하여 응답받은 파일이나 script 태그내의 코드를 파싱하기 위해 자바스크립트 엔진에 제어권을 넘긴다. (렌더링 엔진 → 자바스크립트 엔진으로 제어권 이동)

이후 자바스크립트 파싱과 실행이 종료되면 렌더링 엔진으로 다시 제어권 넘겨 HTML 파싱 중단된 시점부터 DOM 생성을 재개한다.

6. 리플로우와 리페인트

만약 자바스크립트 코드에 DOM, CSSOM을 변경하는 DOM API가 사용된 경우 DOM, CSSOM이 변경되고 변경된 DOM, CSSOM으로 다시 렌더트리로 결합되고 레이아웃과 페인트 과정을 거쳐 브라우저 화면에 다시 렌더링한다. 이를 리플로우, 리페인트라고 한다.

리플로우가 발생하면 성능을 저하시키므로 리플로우가 발생하는 메서드 사용을 최소화 하여야 한다. 일단 가독성 위주로 코딩을 하되 성능 측정하여 렌더링에 2초 이상 걸린다면 리팩터링을 하여 성능을 개선해야한다.

댓글 공유

📌 호이스팅이란?

호이스팅이란 코드에서 선언이 마치 코드 최상단으로 옮겨진 것처럼 동작하는 것을 말한다.

1
2
3
4
5
6
7
8
9
// var 선언은 에러를 발생하지 않는다.
console.log(foo); // undefined
var foo = 1;
console.log(foo); // 1

// let/const 선언은 에러를 발생 시킨다.
console.log(bar); // ReferenceError: bar is not defined
let bar = 2;
console.log(bar); // 2

마치 위 예제를 보았을 때, let, const 키워드로 선언할 경우 호이스팅이 발생하지 않는 것처럼 느낄 수 있는데, let, const 키워드로 선언했을 경우에도 호이스팅이 발생한다.

위 예제에서 오류를 발생시키는 것은 var 키워드의 경우 변수 선언 단계와 초기화 단계가 동시에 진행되므로 이 때, 변수가 선언됨과 동시에 undefined로 초기화되어 오류를 발생시키지 않는다.

반면, let, const 키워드는 선언단계와 초기화 단계가 분리되어 진행되어 초기화 단계 이전에 해당 변수를 참조하게 되면 참조에러를 발생시킨다.

선언단계 ~ 초기화 단계 시작 전까지 구간을 Temporal Dead Zone(일시적 사각 지대)라고 한다.

📚 함수 호이스팅

호이스팅은 선언 단계가 마치 최상단으로 올라간 것처럼 동작하는 것을 말하므로 이는 변수 선언과 함수 선언 모두 해당될 수 있다.

변수 선언은 앞의 예제에서 다루었으니 함수 호이스팅 예제를 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
const numbers = [1, 2, 3, 4, 5];
const doubled = doubleNum(numbers);
const trippled = trippleNum(numbers);

const doubleNum = (num) => {
return num.map((n) => n * 2);
};

const trippleNum = (num) => {
return num.map((n) => n * 3);
};

// Uncaught ReferenceError: doubleNum is not defined
  • 위 예제에서는 화살표 함수가 표현식으로 선언되었으므로 변수 호이스팅이 발생하여 오류를 발생하는 것을 볼 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
const numbers = [1, 2, 3, 4, 5];
const doubled = doubleNum(numbers);
const trippled = trippleNum(numbers);
console.log(doubled); // [2, 4, 6, 8, 10]
console.log(trippled); // [3, 6, 9, 12, 15]

function doubleNum(num) {
return num.map((n) => n * 2);
}

function trippleNum(num) {
return num.map((n) => n * 3);
}
  • 위 예제에서는 함수 선언식으로 함수를 정의하여서 함수 호이스팅이 발생하여 오류를 발생시키지 않았다.

댓글 공유

loco9939

author.bio


author.job