[내일배움캠프 TIL] 33일차

Jaehyeon Ye·2022년 12월 14일
0

오늘 새로 배운 것

JS 객체

배열은 인덱스를 key로 가진다.
사실 JS의 모든 객체는 key, value를 가진다.

객체 생성 방식

  • 객체 리터럴 방식
let obj = {a:"객체", b:0}
  • 객체 생성자 방식
let obj = new Object()

객체는 const로 선언이 되어도 값이 바뀔 수 있다!

const는 재선언과 재할당이 안된다고 배웠다.
하지만,

const d = [111, 'aaaaa', true];
d[0] = 222;

console.log(d); //[ 222, 'aaaaa', true ]

오류가 나지 않고 d의 0번째 인덱스에 해당하는 값이 바뀌어서 출력되는 것을 확인했다.
상수의 경우는 const로 선언되면 재할당이 안되지만 객체의 경우는 다르다.
상수는 어떤 메모리 공간에 그 값이 바로 저장되지만, 객체의 경우 해당 인덱스의 메모리 공간에 값이 바로 저장되는 것이 아닌 그 값은 다른 메모리 공간에 할당되고 그 메모리 공간의 주소를 저장하는 것이다. 그렇기 때문에 위와 같은 상황에서 d[0]이라는 다른 공간에 저장된 주소로 주소값이 바뀌어 출력되는 것이다.

콜백함수(Callback function)

인수로 넘겨준 함수를 콜백함수라고 함

const func = (name, callbackfunc) => {
  console.log(callbackfunc(name));
};

const callbackfunc = (name) => {
  return '제 이름은 ' + name + ' 입니다.';
};

func('Github', callbackfunc); //제 이름은 Github 입니다.

함수 선언식과 함수 표현식

함수 선언식은 코드가 실행되기 전 함수가 미리 저장돼있기 때문에 코드 상에서 호출이 먼저 되더라도 정상적으로 출력되는데 반해, 함수 표현식은 변수에 함수를 할당하는 코드가 실행될 때 (실행 컨텍스트가 이 표현식 도달할 때) 함수가 그때 할당되기 때문에 이 코드 전에 먼저 호출이 되면 reference 오류가 난다.

자료 저장소

Cookie, 로컬 스토리지, 세션 스토리지...
로그인 정보 기억하기 체크할 경우 정보가 여기 저장

렌더링 엔진

파싱 단계: DOM트리와 CSSOM 트리 생성
파싱 예:

["<", "div",">", ...]

렌더 트리 단계: DOM과 CSSOM을 묶어서 렌더 트리 생성
레이아웃 단계: 랜더 트리에서 각 노드가 어디에 어떻게 그려져야하는지 계산
페인트 단계: 계산한대로 화면에 element 배치

브라우저가 파스 트리 자체를 읽을 순 없고 파스 트리가지고 토큰화 과정을 통해 DOM 트리를 만든다. DOM 트리는 html element로 이루어진 트리이다. CSSOM 트리도 마찬가지이다. CSS로 파스트리 만든 후에 브라우저가 읽을 수 있는 CSSOM 트리로 만들어진다.

렌더 트리가 화면에 나타날 요소 결정. 레이아웃 단계에서는 화면에 보여주기로 한 노드들의 정확한 위치와 크기, 순서들을 계산함

페인트 단계에서는 위의 계산대로 배치하는 단계

더티 비트 시스템

브라우저의 렌더링 엔진 입장에서는 레이아웃이 변경되면 페이지를 다시 그려줘야함. 근데 전부 다 다시 그리는 것은 비효율적이므로 렌더 트리를 계산할 때 처음부터 샅샅히 다 뒤지는 게 아니고 특정 부분만 다시 계산해서 리소스를 줄임

렌더 트리를 root부터 다 탐색을 하면서 바뀐 element를 버려야하니까(dirty element)이 element를 다른 곳에 모은 다음 일괄 작업을 함.

더티 비트 시스템을 최적화한다고 해도 한번에 한 5개 정도 변경되면 다행이지만 순차적으로 시간 간격을 어느 정도 두고 바뀌는 일이 생기면 일을 생길 때마다 매번 화면에 다시 그려주게 된다. 스케줄러에 모아서 일을 하기는 하지만 잠깐 잠깐 우리가 인지 못할 정도로 (1초에 60번 이상) 모아서 일을 하고 이런식으로 순차적으로 일을 주게 되면 스케줄러에 계속 일을 주게 된다. JS로 DOM을 직접 조작하는 것은 연산 비용이 굉장히 큰 행위이다. 이러한 이유로 가상 DOM 개념이 등장하게 된다.

폴리필(polyfill)

자바스크립트의 최신기술을 구버전 브라우저에서 사용하기 위해서는 변화과 함께 폴리필도 사용해야 한다. 폴리필은 런타임 기능 주입을 말한다.
런타임 기능 주입은 브라우저에서 코드가 실행될 때 기능이 있는지 없는지 확인한 뒤 없을 경우에만 코드 변환을 하는 기능을 말한다.

Virtual DOM

JS로 DOM을 직접 조작할 때는 어떤 엘리먼트를 추가, 삭제하는 변경이 있었을 때 레이아웃 단계와 페인트 단계에서 리소스가 많이 들어간다. 성능 최적화를 위해선 레이아웃, 페인트 단계의 연산을 줄여야한다. node가 그려지는 위치와 모양 계산하고 배치하는 이 연산을 줄이려면 렌더 트리를 완전히 처음부터 계산하는 게 아니라 바로 변경 부분을 찾아가서 바꾸는 것이다. 그래서 더티 비트 시스템이 추가되고 바꿔야할 것을 스케줄러에 넣어서 한번에 처리하는 것이다.
즉, 어떤 로드를 수정할 때 어떤 것을 변경할지 기록해놨다가 한번에 처리한다.

리액트는 SPA 방식인데 일단 html이 한 개밖에 없다. 컴포넌트를 바꿔 끼워가면서 보여주려면 DOM조작이 계속 일어나야하고 수정이 계속 일어난다. 근데 최적화를 하려면 최대한 변경할 것들을 모았다가 한번에 처리를 해야한다. 그래서 가상 DOM(Virtual DOM) 개념이 등장한다.

메모리 안에 가상 DOM을 메모리에 넣어놓는데 실제 화면에 보이는 게 아니니 실제 DOM보다 메모리가 훨씬 줄어든다. 가상 DOM에 변경사항을 넣어놓고 실제 DOM의 변경된 것만 한번에 반영하는 것이다. 그러나 가상 DOM을 쓴다고 무조건 빠른 게 아니다. 코드 관리를 잘못하면 가상 DOM을 사용하는 게 훨씬 느려질 수도 있다. 즉 리액트를 사용하지 않는 게 더 나을 수도 있다.

&& 연산자

왼쪽 피연산자가 true일때만 오른쪽 피연산자를 리턴하는 문법.
예를 들어,

{showTimer && <Timer/>}

의 경우 showTimer가 true일때만

<Timer/>

를 리턴한다.

하루를 돌아보며...

Todolist에서 삭제 버튼 클릭 시 삭제 여부를 한번더 되묻는 모달창과 삭제, 취소 기능은 구현하였다. 하지만 수정 시 input 태그를 비워놓은 뒤 수정취소 버튼을 클릭하면 공백 입력이 허용되는 문제가 남아있는데 이걸 어떻게 해결할지 잘 모르겠다.
useEffect로 수정 input이 언마운트될 때 마지막 입력값이 공백이 아니라면 마지막 타이틀 값이 출력되도록 어떻게 해봐야할지 고민이다.
그리고 CSS 공부 좀 더 해야겠다...

profile
FE Developer

0개의 댓글