Search

프론트엔드 한방 정리

대분류
기타
소분류
알쓸신잡
유형
Frontend
부유형
브라우저
HTML
CSS
JavaScript
TypeScript
React
Vue
최종 편집 일시
2024/10/29 07:37
생성 일시
2024/04/14 13:48
14 more properties

브라우저

주소창에 google.com을 입력하면 일어나는 일

1. 웹 브라우저에 URL을 입력하고 Enter 키를 누릅니다.
2. 웹 브라우저가 도메인의 IP 주소를 조회합니다. (먼저 캐시를 찾고, 그다음 DNS를 검색합니다.)
3. 웹 브라우저가 찾은 IP 주소를 기반으로 서버와의 TCP 연결을 시작합니다.
4. 웹 브라우저가 HTTP 요청을 서버로 전송합니다. (필요한 경우, HTTPS 보안 통신이 진행됩니다.)
5. 웹 서버가 요청을 처리하고 응답을 다시 웹 브라우저로 전송합니다.
6. 웹 브라우저가 전송 받은 콘텐츠를 렌더링합니다.

브라우저 렌더링 과정

1.
HTML 변환, 토큰화, 렉싱 과정을 거쳐 DOM을 생성
2.
CSS도 마찬가지로 CSSOM을 생성
3.
위 과정을 거쳐 생성된 TREE를 결합하여 렌더링 트리를 생성 - 이때 페이지를 렌더링하는데 필요한 노드만 포함
4.
레이아웃 단계 - 뷰포트내에 각 노드의 정확한 위치와 크기를 계산
5.
계산된 값을 이용해 각 노드를 화면상의 실제 픽셀로 변환하고 레이어를 만든다.
6.
레이어를 합성하여 실제 화면에 출력

사이트 렌더링 시간이 길어질 때 확인 해봐야할 것은?

첫번째로 웹팩 사용입니다. 웹팩을 사용하면 파일 용량이 압축되고 모듈 번들링을 통해 파일 개수가 감소합니다.
두번째로 image lazy loading입니다. Img 태그에 loading=’lazy’ 속성을 작성하면 화면에 실제로 이미지가 보여야 할 때 이미지를 다운로드하여 CSS, JS 파일보다도 먼저 다운로드하게 됩니다.
세번째로 lazy component입니다. Lazy component를 사용하면 첫 화면에 보이지 않는 컴포넌트는 나중에 다운로드하기 때문에 처음에 다운로드해야 할 파일 개수가 감소합니다.
네번째로 웹 폰트입니다. 압축률이 제일 좋은 WOFF2 형식의 폰트를 사용하는 것이 제일 좋고, WOFF2 형식의 폰트를 지원하지 않은 브라우저가 있을 경우를 대비해서 폴백 형식을 통해 그 다음으로 압축률이 좋은 WOFF 형식을 지정할 수 있습니다. 또 실생활에서 거의 사용하지 않는 글자를 폰트에서 제거한 서브셋 폰트를 통해 폰트 용량을 줄일 수 있습니다.
마지막으로 이미지 최적화입니다. 만약 이미지가 사용 용도에 비해 불필요하게 크면 이미지 크기를 줄입니다. 또 색상이 많은 이미지는 JPG 형식을, 색상이 적은 이미지는 PNG 형식을 사용하는 것이 좋습니다. 그리고 이미지 최적화 사이트를 통해 사진의 색상 수를 줄일 수 있어 이미지 파일 용량을 줄여 이미지를 최적화할 수 있습니다.

CORS

교차 출처 리소스 공유
프로토콜, 도메인(호스트 이름), 포트가 전부 동일해야함, 아니면 에러 발생
해결법
응답 헤더의 Access-Control-Allow-Origin에 접근을 허용할 출처를 반환하는 방법
서버에서 CORS 헤더 설정
프록시 서버 사용
Next.js API Route에서 CORS 설정

Payload와 Header의 차이는?

Payload는 전송할 실제 데이터이고, Header는 Payload의 정보를 담고 있는 보충 데이터
Header는 데이터 블록의 맨 앞에 위치하며 데이터가 어디로 전송되어야 하는지 어떤 데이터인지 등의 부가적인 정보를 담고 있습니다.

localStorage, sessionStorage, cookie의 차이

localStorage는 같은 도메인에 대하여 같은 정보를 저장하며, 창을 닫거나 탭을 닫는 등 세션이 만료되어도 정보가 지워지지 않습니다.
sessionStorage는 같은 도메인이더라도 탭, 창 별로 서로 다른 정보를 저장하며, 세션이 만료되면 데이터도 함께 사라집니다.
session : 웹서버에 웹 컨테이너의 상태를 유지하기 위한 정보를 저장 - 서버에 저장, 느리고 안전
Cookie는 용량이 상당히 작은 텍스트 파일로, 만료 기간을 가져 일정 시간이 지나면 만료되어 데이터가 삭제됩니다. - 클라이언트에 저장 - 빠르고 취약
사용 용도
localStorage : 자동로그인
sessionStorage : 자동 임시 저장 용도
cookie : 팝업창 안보게 하는 용도

Cookie

세션쿠키(Session Cookie)
사용자가 사이트 탐색 시에 관련한 설정들과 선호사항을 저장하는 임시 쿠키정도라고 생각하면 된다. 브라우저를 닫는 순간 삭제된다.
지속쿠키(Persistent Cookie)
지속쿠키는 세션쿠키와 다르게 삭제되지 않고 더 길게 유지가 가능하다. 지속쿠키는 디스크에 저장되며, 브라우저를 닫거나 컴퓨터를 재시작해도 남아닜다. 사용자 로그인 항상 유지와 같은 곳에 사용한다.
세션쿠키와 지속쿠키는 파기시점 외에 차이점이 없다. Discard라는 파라미터가 설정되어 있거나, 파기까지 남은시간인 Expires또는 Max-Age라는 파라미터가 없으면 세션쿠키이다.

HTML

RESTful API란?

표준 HTTP 메소드(GET, POST, PUT, DELETE + PATCH)를 사용하여 서버와 통신하는 것
 REST가 표준 (API 아키텍처)이고 CRUD가 함수

HTTP 메소드란?

리소스를 조회하는 메서드 POST뺴곤 멱등성 존재 하지만 PATCH는 보장되지 않는다.
멱등성 : 연산을 여러 번 적용해도 결과가 달라지지않는것
GET
쿼리스트링(?name=)을 통해 데이터 전달
브라우저 히스토리에도 기록이 남는다.
POST
새로운 리소스 생성 201 - 데이터를 바디에 쿼리 파라미터(Key-Value)형식으로 전달
데이터가 외부로 노출되지 않음
속도는 GET - 캐싱 사용, 보안은 POST
PUT
덮어쓰기 - 리소스 완전 대체
부분 수정 불가
PATCH
리소스 수정
부분 수정 가능
DELETE
리소스 제거

HTTP, HTTPS

HyperText 전송(Transfer)에 사용되는 통신 규약(Protocol) - 80
HTTPS : 암호화(SSL, TLS 프로토콜 사용 - 세션 데이터 암호화) - 443

시맨틱 태그

해당 요소의 의미를 명시함으로써, 콘텐츠를 논리적으로 그룹화하고, 각 부분에 어떤 유형의 정보가 포함될 것인지 쉽게 파악할 수 있도록 도와줍니다.
div, header, footer,main, section, article등이 존재
중요한 이유
예로 div, span을 예시로 든다면 display 속성이 div는 블록, span은 inline으로 되어있기에 width, height속성은 div에만 먹히게 된다.
ul과 ol의 사용법 - li만 직계자식으로 가져야한다.

CSS

Flex 속성 설명해주세요.

Flexbox는 기존 컨텐츠를 수평으로 배치할 때 쉽게 해결할 수 있도록 추가된 기능입니다. 다양한 디바이스 환경에서 언제나 똑같은 레이아웃을 유지시켜줌으로서 반응형 웹 사이트에 유용하게 쓰입니다. Flex는 컨텐츠를 감싸는 상위 부모요소인 Flex Container와 각 컨텐츠들인 자식 요소 Flex Item으로 구성되어 있습니다. Flexbox 적용방법은 부모 요소인 container에 display:flex를 선언하고 전체적인 정렬과 관련된 속성인 flex-direaction, align-items, flex-wrap 같은 속성을 정의합니다. 그리고 자식 요소인 flex item에는 flex-grow, flex-shrink 같은 크기나 순서 같은 속성을 정의합니다.

Box model에 대해 설명해주세요.

모든 HTML 요소는 BOX모양으로 구성되며, 이것을 박스모델이라고 합니다. 박스 모델은 총 네 영역으로 이루어지고, 이 네가지 영역은 padding, border, margin, content로 구분합니다. Content는 텍스트나 이미지가 들어가 있는 박스의 실질적인 부분으로 색상, 너비, 높이 등을 지정할 수 있으며, padding은 내용과 테두리 사이의 간격입니다. 또 border는 내용과 패딩 주변을 감싸는 테두리이며, margin은 테두리와 이웃하는 요소 사이의 간격입니다.

Display에 대해 설명해주세요.

Display 속성은 요소를 배치할 때 사용합니다. None, block, inline, inline-block, flex, grid 총 5가지 속성이 있는데 none은 요소가 차지하는 공간이 사라지게 만듭니다.
Block은 블록 박스 요소에 기본으로 적용되는 값으로, 인라인 박스 요소를 블록 박스 요소로 변경시킬 수 있고, Inline은 box와는 반대로 사용됩니다.
Inline-block은 block 요소의 특성과 inline 요소의 특성을 따릅니다. Block 요소의 특성으로는 width와 height를 지정할 수 있고 margin, border, padding 영역을 갖는다는 점이 있습니다. Inline 요소의 특성으로는 요소의 크기가 내용에 의존적이라는 점과 줄바꿈 현상이 일어나지 않는다는 점입니다.
Flexbox는 1차원 레이아웃을 대상으로 하고, 컨테이너들의 레이아웃, 정렬 그리고 간격을 설정하는데 효과적입니다. Flexbox는 주로 반응형을 만들 때 사용됩니다.
Grid는 2차원 레이아웃을 대상으로 하고 그리드 기반의 레이아웃을 생성할 때 사용합니다.

Position에 대해 설명해주세요.

Position 속성은 문서 상에 요소를 배치하는 방법을 지정하며, Static, relative, absolute, fixed, sticky 총 5가지 속성이 있습니다. Static은 position의 기본 값이며, 요소를 문서 흐름에 맞게 배치합니다. Relative는 요소가 차지하는 공간은 static과 같으나 top/right/left/bottom 값을 적용시킬 수 있습니다. Absolute는 일반적인 문서 흐름에서 제거되고 부모 블록의 박스 안에 속해 위치가 지정됩니다. 만약 전부 static 값을 갖고 있으면 최상위 블록에 의존합니다. Fixed는 요소가 페이지의 평소 위치에서 제거되고 뷰포트를 기준으로 지정된 위치에 배치되며 스크롤할 때 이동하지 않습니다. 마지막으로 sticky는 지정된 임계값을 넘을 때까지 relative 위치로 처리되며 특정 지점에서 fixed 위치로 처리됩니다.

JavaScript

연결리스트, 어레이 차이

Array는 연속된 메모리 공간에 존재하고 Linked List는 메모리 상에서 떨어져 있는 데이터들이 앞의 데이터와 뒤의 데이터를 기억하는 형태로 존재
Array에 저장되어 있는 데이터를 조회할 때는 O(1)로 가능하지만 Linked List는 O(N)이 소요된다.
Array에 데이터 추가 및 삭제할 때는 O(N)이 소요되지만 Linked List는 O(1)로 가능하다.
Array - Stack, 정적
Linked List - Heap, 동적

힙,스택이 뭐냐

메모리 공간을 구분할 때 코드, 데이터, 힙, 스택 영역으로 구분된다.
힙 - 런 타임에 의해 크기 결정 : 큐를 위해 만들어진 자료구조
메모리의 낮은 주소 → 높은 주소, FIFO(선입선출)
스택 - 컴파일 타임에 의해 크기 결정
메모리의 높은 주소 → 낮은 주소, LIFO(후입선출)
JS엔진 - 메모리 힙, 콜스택
메모리 힙 : 객체, 배열, 함수와 같이 크기가 동적으로 변할 수 있는 참조타입 값 을 저장하는 곳
콜 스택 : 원시타입 값과 함수 호출의 실행 컨텍스트를 저장하는 곳
콜 스택이 계속 쌓이다가 한계점을 만나게 되면 스택 오버플로우 발생

Queue

한쪽 끝에서만 삽입이 이루어지고, 다른 한쪽 끝에서는 삭제 연산만 이루어지는 유한 순서 리스트 FIFO
Microtask Queue
Microtask Queue는 Promise나 async/await, process.nextTick, Object.observe, MutationObserver과 같은 비동기 호출을 넘겨받는다.
그리고 Microtask의 우선순위는 일반 task(또는 macrotask)보다 더 높다.
async/await에선 이거만 존재
Macrotask Queue
Task Queue - setTimeout(), setInterval(), setImmediate()를 넘겨받음

시간복잡도란?

알고리즘의 수행시간을 평가
점근적 표기법 중 빅오-최악, 빅오메가-최선 빅세타-평균 표기법을 이용

Ajax - 코드를 효율적으로 작성해야하나?

수많은 Ajax요청이 일어나는 현대 웹에서 Ajax 요청 1번이 지배적인 지연을 일으키기에 별 소용이 없다. → 사용성에 미치는건 네트워크 지연속도가 영향을 가장 많이 미친다.
Ajax란? JavaScript와 XML을 이용한 비동기적 정보 교환 기법- JS를 사용해서 브라우저가 서버에게 비동기 방식으로 데이터를 요청하고, 서버가 응답한 데이터를 수신하여 웹페이지를 동적으로 갱신하는 프로그래밍 방식
최근 XML보다 JSON이 주로 사용된다.

CSRF나 XSS 공격을 막는 방법은?

CSRF Token을 생성하여 세션에 저장하고, 프론트엔드에서 요청 시 해당 Token을 함께 전송하여 인증합니다. SameSite 속성을 쿠키에 설정하여 도메인이 다른 사이트에서는 쿠키를 사용할 수 없도록 제한하는 방법도 있습니다
입력 값의 유효성 검증 및 정규식을 통한 불필요한 문자 제거 필터링, 출력값을 인코딩 처리하여 스크립트 실행 방지, HTTPS(SSL) 사용 - 통신 프로토콜 암호화

var, let, const

var 재선언 가능, let const 재선언 불가
var, let 값 재할당 가능, const 재할당 불가
var 함수 레벨 스코프 - 함수 외부 참조 불가, let const - 블록레벨 스코프, 모든 코드 블록 외부에서는 참조 불가

호이스팅

코드가 실행되는 과정에서 선언부를 코드의 최상단으로 끌어올리는 것처럼 보이게 하는것.
var은 변수를 선언하고 초기화하는 과정이 동시에 일어나서 호이스팅이 발생
let/const선언 변수는 호이스팅되지 않는 것이 아니다. 스코프에 진입할 때 변수가 만들어지고 TDZ(Temporal Dead Zone)가 생성되지만, 코드 실행이 변수가 실제 있는 위치에 도달할 때까지 액세스할 수 없는 것이다. let/const변수가 선언된 시점에서 제어흐름은 TDZ를 떠난 상태가 되며, 변수를 사용할 수 있게 된다.
함수 : 변수 : 초기화 undefined - 따라서 함수표현식을 사용했을경우 변수 호이스팅으로 작동하여 에러가 발생한다

이벤트 캡쳐링, 버블링

버블링 : 자식 → 부모 요소 핸들러로 반복이 되면서 핸들러가 동작하는 현상
캡쳐링 : 최상위 태그에서 해당 태그를 찾아 내려감

This

1.
일반 함수에서 호출될 경우 Browser-side에서는 window, Server-side(Node.js)에서는 global 객체를 의미
2.
메서드로 호출되었을 경우 해당 메소드를 호출한 객체에 바인딩
3.
생성자 안에서 호출했을 경우 생성자 함수가 생성하는 객체로 this가 바인딩
4.
apply, call, bind와 같은 명시적 바인딩을 한 this는 첫번째 인자값을 반환
apply는 두번째 매개변수가 배열일 때 apply를 사용한다.
apply()와 call()은 보통 유사배열 객체에게 배열 메서드를 쓰고자 할 때 사용
5.
화살표 함수는 전역 컨텍스트에서 실행되더라도 this를 새로 정의하지 않고, 바로 바깥 함수나 클래스의 this를 사용

콜백함수

함수의 매개변수로 다른 함수를 전달하고, 어떠한 이벤트가 발생한 후 매개변수로 전달한 함수가 다시 호출하는 것을 의미. - 보통 비동기 처리 시 사용
콜백지옥 방지를 위해, Promise나 Async/Await을 사용

실행 컨텍스트

코드를 실행하기 위해 필요한 정보들을 가진 범위를 객체 형태로 나타낸 것
VariableEnvrionment는 현재 컨텍스트 내부의 식별자 정보인 EnvironmentRecord와 외부 환경 정보인 outerEnvironmentReference
LexicalEnvironment는 VariableEnvrionment를 그대로 복사하여 사용하나 변경 사항이 실시간으로 적용되어 VariableEnvrionment는 초기 상태를 저장하고, LexicalEnvironment는 최신 상태를 저장
ThisBinding는 this 식별자가 바라보고 있는 대상 객체

Promise

비동기 연산이 종료된 이후에 결과값이나 실패 사유를 처리하기 위한 것 - 값 반환 가능
resolve와 reject를 파라메터로 받고 있는데 비동기 작업이 성공하면 resolve 함수를 호출하고, 실패하면 reject 함수를 호출
사이클
fulfilled(처리 완료) - 작업 성공 : then()호출
비동기 작업이 수행된 이후 수행할 코드
rejected(거부 됨) - 작업 실패 : catch()호출
pending(보류 됨) - 작업 시작 전
settled(해결 됨) - 처리 완료 혹은 거부 됨

async-await

코드 가독성을 좋게 만들어주는 비동기 처리 패턴
async는 프로미스를 반환, 아닌건 프로미스로 감싸 반환
await를 만나면 프로미스가 처리될 떄까지 대기
프로미스가 처리되어 resolve될 땐 값만 따로 추출하여 리턴 가능

클로저

외부 함수보다 중첩 함수가 더 오래 유지되는 경우 중첩 함수는 이미 생명 주기가 종료한 외부 함수의 변수를 참조할 수 있는데 이런 중첩 함수를 뜻함
상태가 의도치 않게 변경되지 않도록 상태를 안전하게 은닉하고 특정 함수에게만 상태 변경을 허용하기 위해 사용
렉시컬(정적) 스코프
JS엔진이 함수를 어디에 정의했는지에 따라 상위 스코프를 결정하는 것
스코프 : 실행 컨텍스트의 렉시컬 환경

웹팩과 바벨에 대해서 설명

웹팩은 여러 개의 파일을 하나로 합쳐주는 모듈 번들러
웹팩은 모듈 지원, 파일 분할, css loader, jsx 변환 작업을 해줍니다.
그리고 여러 개로 나눠진 자바스크립트 파일을 html이 실행할 수 있는 하나의 자바스크립트 파일로 합쳐줍니다. 이로 인해 네트워크 접속의 부담을 줄여 더 빠른 서비스를 제공할 수 있습니다.
바벨은 대표적인 트랜스파일러인데 모든 브라우저가 ES6 문법을 제공하지 않기 때문에 ES5 문법으로 변환시켜줍니다

얕은 복사와 깊은 복사란?

우선 기본형의 복사는 값이 그대로 복사되는 것을 의미합니다.
그리고 참조형의 얕은 복사는 참조값의 복사를 나타냅니다. 이는 데이터가 그대로 생성되는 것이 아닌 해당 데이터의 참조값을 전달하여 한 데이터를 공유하는 것입니다.
마지막으로 참조형의 깊은 복사는 얕은 복사처럼 참조값이 복사되는 것이 아니라 값만 복사되어 독립적인 메모리에 값 자체를 할당하여 생성합니다. 1차원 배열을 복사할 땐 Object.assign()이나 spread operator를 사용하고 2차원 이상의 배열을 복사할 땐 함수를 커스텀하여 하는 방법과 lodash 라이브러리의 cloneDeep() 메소드를 이용하여 복사하는 방법이 있습니다.

프로토타입

React, Vue

쓰는 이유

Virtual DOM이 존재하기 때문. 기존의 DOM은 페이지가 바뀔 때마다 새 HTML을 로드하면서 DOM 전체를 바꾸게 되는데 Virtual DOM은 DOM과 비교해서 달라진 부분만 찾아 바꾸기 때문 - DOM보다 빠르진 않지만 DOM 관리를 자동화하고 추상화하여 직접 할 필요가 없게 해주기에 사용
컴포넌트 단위 작성인데, 컴포넌트 단위로 작성하게 되면 또 다른 웹에서 재사용이 가능해집니다. 이는 생산성과 유지 보수를 용이하게 함
커뮤니티가 잘되어있다. > Vue
Vue는 대신 러닝 커브가 적다.

CP클래스 컴포넌트와 FP함수 컴포넌트의 차이 

클래스 컴포넌트의 경우 state의 사용이 가능하여 상태 저장이 가능하고, 리액트 라이프 사이클 메서드를 사용 가능합니다. 함수가 아닌 클래스이기 때문에 return문이 없고 render() 함수가 필수적으로 있어야 JSX 반환이 가능합니다.
함수 컴포넌트는 클래스보다 선언하기 좀 더 편하고, 함수는 한번 실행되고 나면 메모리 상에서 사라지기 때문에 메모리 자원을 덜 사용하는 것이 장점입니다. 함수형 컴포넌트에서는 hook을 사용할 수 있고, return문을 사용
리액트에서 컴포넌트를 만드는 방법에는 클래스형 컴포넌트(class components)와 함수형 컴포넌트(functional components)가 있습니다. 클래스형 컴포넌트는 ES6의 클래스(class)를 사용하여 컴포넌트를 정의합니다. 이 방식은 React의 컴포넌트의 상태(state)와 생명주기(lifecycle)를 다룰 때 매우 유용합니다.
반면에 함수형 컴포넌트는 ES6의 화살표 함수(arrow function)를 사용하여 컴포넌트를 정의합니다. 이 방식은 훅(hook) API와 함께 많이 사용되며, 컴포넌트의 상태와 생명주기를 다룰 때도 유용합니다.
클래스형 컴포넌트와 함수형 컴포넌트의 가장 큰 차이점은 상태와 생명주기의 다루는 방식입니다. 클래스형 컴포넌트는 상태를 this.state로 정의하고, 생명주기 메서드를 오버라이드하여 다양한 작업을 수행합니다.
반면에 함수형 컴포넌트는 상태를 useState 훅을 사용하여 정의하고, useEffect 훅을 사용하여 생명주기를 다룹니다. 또한, 클래스형 컴포넌트에서는 this 키워드를 사용하여 상태나 메서드를 참조하며, 함수형 컴포넌트에서는 this 키워드를 사용하지 않습니다. 이러한 차이점 때문에, 함수형 컴포넌트는 더 간결하고 가독성이 좋아지며, 테스트와 리팩토링이 쉽게 이루어질 수 있습니다.

SPA, SSR (단일 페이지 애플리케이션)

사용자에게 빠른 인터렉션을 제공해야하고 페이지 내 정보가 빠르게 바뀌는 경우
서버에서 필요한 데이터만 비동기로 받아와서 동적으로 현재 화면에 다시 렌더링 하는 방식
다수의 페이지를 표시하는 데 있어서 과거 전통적인 방식으로 페이지 전환을 수행하지 않고, 마치 하나의 페이지인 것처럼 처리하는 기술
전체 화면을 새로 내려받지 않기 때문에 높은 반응성과 빠른 로딩 속도를 가능하게 한다.
사용자 경험이 우선시 될 경우에는 SPA,
초기 로딩 속도와 SEO(검색엔진) 중요한 경우에는 SSR
CSR과 비교하였을 경우 SSR은 최초 페이지 로딩이 느리다.
1.
굳이 SEO 적용 또는 데이터 pre-rendering이 필요 없다면 CSR 방식
2.
정적 문서로 충분한 화면이면서 빠른 HTML 문서 반환이 필요하다면 SSG 방식
3.
매 요청마다 달라지는 화면이면서 서버 사이드로 이를 렌더링 하고자 한다면 SSR 방식

CSR과 SSR의 차이점

SSR은 사용자가 웹페이지에 접근할 때, 서버에 각각 페이지에 대해 요청하고 서버에서 HTML, JS 파일 등을 모두 다운로드하여 화면에 렌더링 하는 방식입니다.
반면에, CSR은 클라이언트 측에서 HTML을 반환한 후에, JS가 동작하면서 데이터만을 주고받아 클라이언트에서 렌더링을 진행합니다.

 CSR

유저와 상호작용이 많다
대부분이 고객의 개인정보로 이루어진 페이지들이라 검색엔진에 노출될 필요는 없다

 SSR

회사 홈페이지여서 홍보나 상위노출이 필요하다
누구에게나 항상 같은 내용을 보여준다
업데이트가 빈번해 해당 페이지 데이터가 자주 바뀐다

 SSG

회사 홈페이지여서 홍보나 상위노출이 필요하다
누구에게나 항상 같은 내용을 보여준다
업데이트를 거의 하지 않는다

Universal Rendering (초기 렌더링으로는 SSR + 이후 CSR)

사용자에 따라 페이지 내용이 달라진다
빠른 interaction과 화면 깜빡임이 없어야 한다
SEO를 포기할 수 없어 상위노출이 되면 좋겠다

SSG(Static Site Generator)가 무엇인가요?

SSG(Static Site Generator)는 정적 웹사이트를 생성하는 도구
이는 사전에 서버에서 HTML, CSS, JavaScript 등의 파일을 생성하여, 클라이언트에게 전송되는 방식으로 작동
SSG를 사용하면 동적인 웹사이트와는 달리, 데이터베이스나 서버 사이드 렌더링을 필요로 하지 않는 빠르고 안전한 웹 페이지 생성 가능
SSG의 장점
성능: 모든 페이지가 미리 생성되어 있기 때문에, 서버는 단순히 정적 파일을 제공만 하면 되므로 로딩 시간이 매우 빠릅니다.
보안: 데이터베이스나 서버 사이드 스크립트를 사용하지 않으므로 보안 취약점이 적습니다.
스케일링: 정적 파일을 다루기 때문에 트래픽이 많아져도 서버 부하가 크게 증가하지 않습니다. CDN(Content Delivery Network)을 통해 쉽게 전 세계에 분산 배포할 수 있습니다.
유지 관리: 정적 파일만 다루기 때문에 유지 관리가 비교적 간단합니다.
SSG의 단점
동적 기능 제한: 실시간으로 변하는 콘텐츠를 처리하기 어렵습니다. 동적 기능이 필요한 경우 외부 API나 클라이언트 사이드 JavaScript를 사용해야 합니다.
콘텐츠 업데이트: 사이트의 내용을 업데이트 하려면 전체 사이트를 다시 생성하고 배포해야 합니다. 크고 복잡한 사이트에서는 이 과정이 시간을 많이 소요될 수 있습니다.

useMemo()란? (렌더링 성능 최적화 방법)

컴포넌트의 성능을 최적화시킬 수 있는 hook이고, Memoization된 값을 반환
여기서 memoization된 값은 연산의 결과값을 메모리에 저장해두고 동일한 입력이 들어오면 값을 재사용한다는 것을 의미

useCallback()이란?(렌더링 성능 최적화 방법)

Memoization된 함수를 반환하는 대표적인 hook
함수를 props로 넘겨줄 경우 함수는 객체이고,
새로 생성된 함수는 다른 참조 값을 가져 하위 컴포넌트가 재렌더링이 발생하게 됩니다.
이런 경우 useCallback()으로 함수를 감싸면 의존성 배열 안에 넣어준 값이 바뀔 경우를 제외하고 항상 동일한 객체를 넘겨줌으로써 불필요한 재렌더링을 방지할 수 있습니다.

Memoization (렌더링 성능 최적화 방법)

계산 결과를 메모리에 저장해 두고 동일한 계산이 요청될 때 다시 계산하지 않고 저장된 값을 반환하는 최적화 기법 - 어플 속도 향상 가능

Redux, Flux

리액트 없이 사용할 수 있는 상태 관리 JS 라이브러리
전역 상태 관리에 도움이 된다.
Action → Dispatch → Store → View 순서로 데이터가 단방향으로 흐른다.(Flux)
Flux : 애플리케이션 데이터 흐름을 관리하는 패턴 - 단방향
예측가능성을 높여준다.
데이터의 일관성을 유지하기 쉽게 만들어준다.
버그를 발견하기 쉽게 해준다.
테스트를 쉽게 해준다.

batching

state 값이 변경되었을 경우 React 에서는 해당 컴포넌트를 리렌더링 하며, 불필요한 리렌더링을 방지하기 위해 state를 변경하는 작업을 일괄적으로 처리
이렇게 state 의 업데이트 작업을 모아 일괄 처리하는 방식을 Batching 이라고 하며, 이 덕에 React 에서는 불필요한 리렌더링을 방지 가능
React 18 버전 이하에서는 오직 React 의 이벤트 핸들러 내부의 state update 작업에 대해서만 Batching 이 가능했다. 하지만 Promise나 setTimeout, Native Event Handler 내부의 작업은 불가능했다.
하지만 React 18 버전 이후부터는 단순히 이벤트 핸들러 내부 뿐만이 아니라 Promise나 setTimeout, Native Event Handler 같은 작업에 대해서도 Batching 작업을 자동으로 수행하게 해주었다.
React 18 에서 제공하는 ReactDOM.createRoot 메서드를 기반으로 렌더링을 진행할 경우 모든 state update 작업은 자동으로 Batching 처리

pinia

state, actions, getters 상태관리

Next.js

직관적인 페이지 기반 라우팅 시스팀
next.js는 pre-rendering 뿐만 아니라 페이지 기반 라우팅 시스템도 제공한다. 프로젝트의 가장 바깥 폴더인 /pages 폴더에서 컴포넌트를 export하면 폴더명이 페이지 route가 된다. (/pages/indext.s -> //pages/store/t-shirt -> /store/t-shirt)
/look/[id]와 같은 dynamic route도 지원
페이지간 빠르고 매끄러운 전환을 위한 client-side navigation
next는 < Link /> 컴포넌트를 통해 페이지간의 빠르고 매끄러운 이동을 가능하게 한다. HTML의 a 태그와 달리 페이지를 리로딩하지 않고도 페이지간 이동이 가능하고, link 컴포넌트가 뷰포트에 보였을 때 관련 페이지를 백그라운드에서 미리 가져다 놓기 때문에 사용자가 링크를 클릭했을 때 매우 빠르게 해당 페이지로 이동할 수 있게 해준다. (이것도 제대로 알고나니 와..하고 감탄했다. 이제 link만 써야지)
자동 Code Splitting (코드 분할)
대부분의 사용자들은 웹페이지가 3초 이상 로딩될 시 이를 느리다 판단한다. 코드 분할은 웹의 첫 페이지가 로딩될 때, 거대한 javascript payload를 보내는 것이 아니라, 번들을 여러 조각으로 조각내어서 처음에 가장 필요한 부분만 전송해 주는 방식을 통해 어플리케이션 로드 타임을 줄여준다. 
코드 분할은 webpack, parcel, rollup 등의 모듈 번들러도 지원하고 있는 기능이지만 next.js를 사용하면 별도의 설정없이 자동으로 프로젝트에 적용

라이프사이클

리액트는 컴포넌트 기반의 view를 중심으로 한 라이브러리입니다. 그러다 보니 각각의 컴포넌트에는 라이프사이클 즉, 컴포넌트의 수명 주기가 존재합니다.
컴포넌트의 수명은 보통 페이지에서 렌더링되기 전부터 페이지에서 사라질 때 끝이 납니다.
라이프 사이클은 크게 보면 컴포넌트가 처음 실행될 때인 mount,
데이터에 변화가 있을 때인 update,
컴포넌트가 제거될 때인 unmount 이렇게 3개로 나눌 수 있습니다.
Vue

개발

TDD

테스트 주도 개발이라는 뜻으로, 먼저 테스트 코드를 작성한 후에 구현을 하는 방식입니다. TDD는 실패→ 성공 → 리팩토링이 서로 꼬리를 물고 이뤄집니다. TDD를 진행하면 테스트 케이스를 작성할 때 주로 작은 단위로 만들기 때문에 코드가 방대해지지 않고, 코드의 모듈화가 자연스럽게 잘 이루어집니다. React에서는 테스트를 위한 jest(프레임 워크)와 enzyme(라이브러리)등이 있습니다.
사용 이유
코드를 수정하거나 기능을 추가할 때 수시로 빠르게 검증 할 수 있다.
리팩토링 시에 안정성을 확보할 수 있다.
개발 및 테스팅에 대한 시간과 비용을 절감할 수 있다.
좋은 테스트 특징
빠르고, 독립적이며, 반복 가능하며, 자체 검증이 되고, 적시에 진행해야한다.

에자일(Agile)방법론

소프트웨어 개발 방식
"주문 ➪ 디자인 ➪ 기능구현 ➪ 테스팅 ➪ 배포" x ∞
기능을 축소하고 그 주기를 짧게하여 빠르게 한 주기가 돌게 한 후 중간 테스트(피드백)를 많이 가지는 방식
빠르고 유연하며 신속하게 제품 변경이 가능하다.
고품질 결과물과 지속적인 개선에 초점을 두고, 결과물에 빠른 피드백이 필요한 팀에 적합

SaaS

소프트웨어 기반 서비스
클라우드 컴퓨팅의 일종으로 비용 효율성, 쉬운 액세스, 확장성, 유지 보수 및 업그레이드 책임의 감소, 최신 기술의 이용 등의 장점
편리하고 쉽게 접근이 가능, 비용 절감, 설치 유지보수 쉬움, 확장 용이, 보안 우려 적음
네트워크 영향 많이 받고 데이터 보안 유의, 서비스 제공 업체 의존성 있음

Git branch 전략

Git Flow
Main 브랜치, Develop 브랜치, Supporting 브랜치로 구분하여 브랜치를 관리한다. 이때, Supporting 브랜치는 또 다시 Feature 브랜치, Release 브랜치, Hotfix 브랜치로 나뉜다. - 웹 어플리케이션에 부적합
Main 브랜치는 출시 가능한 프로덕션 코드를 모아두는 브랜치
Hotfix 브랜치는 이미 배포된 버전에 문제가 발생했다면, Hotfix 브랜치를 사용하여 문제를 해결 - Main과 Develop 브랜치에 둘다 머지
Develop 브랜치는 다음 버전 개발을 위한 코드를 모아두는 브랜치
Feature 브랜치는 하나의 기능을 개발하기 위한 브랜치
Release 브랜치는 소프트웨어 배포를 준비하기 위한 브랜치
Github Flow
Git Flow와 비교하여 간단한 구조
Topic 브랜치 : 새로운 기능을 개발할 때에는 Topic 브랜치를 Main 브랜치로부터 생성
Main 브랜치 : 항상 Stable한 상태여야 한다. 이때, Stable하다는 것은 Main의 모든 커밋은 언제 배포하든 문제 없어야하고, 언제든 브랜치를 새로 만들어도 문제가 없어야 한다.
CI/CD 가능 - 소규모 팀에 적합
지속적 통합(Continuous Integration) 및 지속적 제공/배포(Continuous Delivery/Deployment)

TypeScript

타입스크립트를 사용해 본 경험이 있는지? 어떤지?

정적 타입으로 컴파일 단계에서 오류를 포착할 수 있는 장점이 있고, ES6의 새로운 기능들을 사용하기 위해 바벨과 같은 별도의 트랜스파일러를 사용하지 않아도 ES6의 새로운 기능을 기존의 자바스크립트 엔진에서 실행할 수 있습니다. 명시적인 정적 타입 지정은 코드의 가독성을 높이고 디버깅을 쉽게 할 수 있다는 장점이 있었습니다.

타입스크립트의 특징

첫번째로 언어의 패러다임입니다. TypeScript도 JavaScript에 속합니다. 하지만 TypeScript는 클래스와 인터페이스 그리고 정적 타이핑을 제공하는 Java와 같은 객체 지향 프로그래밍 언어이기도 합니다.
두번째로 타이핑 방법입니다. JavaScript는 기본적으로 변수에 값이 할당될 때 변수의 자료형이 결정되는 동적 타이핑 언어입니다. 반면 TypeScript는 선언할 때 타입을 지정해줘야 하는 정적 타이핑 언어입니다.

Type Narrowing / Assertion

Narrowing - 타입 가드
Assertion - as - union type 같은 복잡한 타입을 하나의 정확한 타입으로 줄이는 역할

null / undefined

null = 값이 없음, 변수에 할당 되었지만 값이 없을 경우
undefined = 변수가 초기화 없이 선언됐을 경우

프로젝트

어떻게 프로젝트에서 대용량 데이터를 처리하였나요?

비동기 작업 병렬 처리 : 데이터를 가져와 여러개의 비동기 작업을 순차적으로 실행하였기에 많은 작업을 조회할 때 속도가 느렸습니다. 하지만 저희는 순차적으로 수행하지 않아도 되었기 때문에 Promise.all 메서드를 사용하여 병렬로 실행해 시간을 줄였습니다.
이 작업을 진행하며 for loop 기반 비동기 처리, all, allSettled 메서드에 대해 고민을 해보았는데 저희는 작업이 모두 성공적으로 이루어져야 했기에 all메서드를 사용하였습니다.
이 처리 과정을 통해 순서의 보장이 필요한 경우 for loop를 사용, 성공이 보장되려면 all, 실패가 되더라도 진행시켜야 한다면 allSettled - 성공유무와는 상관없이 무조건 resolve를 보내기 때문 -
비동기 코드 최적화 : 이도 초기에는 트랜젝션 데이터를 조회할 때 조회하고 싶은 해당 트랜젝션과 관련있는 모든 데이터를 조회해야 했기에 속도가 느렸습니다. 이에 저희 팀은 데이터를 부분 조회하게끔 요청을 날려, 코어 서버에 전달해 주었고, 자주 쓰여지는 값들은 따로 mongo에서 캐싱 처리를 해주어 속도를 향상시켰습니다.