Next.js 성능 최적화
프론트엔드 성능 최적화는 웹 애플리케이션의 로딩 속도, 반응성, 사용자 경험(UX)을 개선하는 핵심 요소이다. 이번 글에서는 실제 프로젝트에서 적용한 프론트엔드 성능 최적화 기법을 정리한다. 1. 이미지 최적화 📌 웹사이트의 성능 저하 원인 중 하나는 크기가 큰 이미지 고해상도 이미지는 로드 속도를 늦추고 네트워크 비용을 증가 최적...
프론트엔드 성능 최적화는 웹 애플리케이션의 로딩 속도, 반응성, 사용자 경험(UX)을 개선하는 핵심 요소이다. 이번 글에서는 실제 프로젝트에서 적용한 프론트엔드 성능 최적화 기법을 정리한다. 1. 이미지 최적화 📌 웹사이트의 성능 저하 원인 중 하나는 크기가 큰 이미지 고해상도 이미지는 로드 속도를 늦추고 네트워크 비용을 증가 최적...
Zustand는 가볍고 사용하기 쉬운 상태 관리 라이브러리이다. Redux와 같은 다른 상태 관리 라이브러리보다 보일러플레이트 코드가 적고, 직관적인 API를 제공하기 때문에 러닝커브가 낮아 빠르게 적용할 수 있다. 특히 React 애플리케이션에서 전역 상태를 효율적으로 관리할 수 있으며, 상태 변경이 필요한 컴포넌트만 리렌더링되도록 최적화되어 있다....
Next.js와 React Query를 활용한 SSR 적용 방법 Next.js에서 React Query를 활용하여 서버 사이드 렌더링(SSR)을 적용하는 방법을 설명한다. 이를 통해 SEO 성능을 개선하고, 초기 로딩 속도를 향상시킬 수 있다. 1. SSR에서 React Query를 활용하는 이유 서버에서 데이터를 미리 가져와 클라이언트...
이 글에서 Next.js의 App Router와 Zustand 상태 관리 라이브러리를 사용하여 모달을 구현하고 관리하는 방법을 설명하겠습니다. 1. Provider 생성 및 설정 모달 컴포넌트를 전역적으로 관리하기 위해 ModalProvider를 작성합니다. 이 Provider는 모든 모달을 포함하며, 전역 상태를 통해 어떤 모달을 표시할지 ...
NextAuth를 활용한 인증 시스템 구현하기 NextAuth는 Next.js 애플리케이션에서 인증 기능을 쉽게 구현할 수 있게 해주는 강력한 라이브러리입니다. 이번 포스트에서는 NextAuth를 사용하여 이메일 기반의 인증 시스템을 구축하는 방법을 상세히 알아보겠습니다. 1. 필요한 패키지 설치하기 npm install next-auth @a...
bfcache(Back-Forward Cache)는 사용자가 브라우저의 “뒤로 가기” 또는 “앞으로 가기” 버튼을 눌렀을 때, 페이지를 다시 로드하지 않고 이전 상태 그대로 복원하는 브라우저 기능이다. 하지만 Next.js의 기본 캐싱 전략은 이 기능과 충돌하여, 페이지를 다시 불러오는 문제가 발생할 수 있다. 이번 글에서는 Next.js에서 bfc...
asChild Prop의 사용 이유와 활용 방법 asChild prop은 Radix UI에서 제공하는 기능으로, 기본적으로 특정 컴포넌트의 기본 HTML 요소를 자식 요소로 대체할 때 사용된다. 이를 통해 불필요한 DOM 중첩을 방지하고, 스타일과 기능을 유지하면서 더 유연한 컴포넌트 활용이 가능해진다. 1. asChild의 기본 개념 일반적...
1. onSuccess와 onSettled의 차이점 🔹 onSuccess Mutation이 성공적으로 완료되었을 때만 실행된다. 에러가 발생하면 실행되지 않는다. 데이터가 서버에 저장된 직후 실행되므로, 성공적인 응답을 기반으로 UI를 업데이트할 때 사용된다. const { mutate } = useMutation({ mutat...
이 글에서는 Next.js의 App Router와 Zustand 상태 관리 라이브러리를 사용하여 모달을 구현하고 관리하는 방법을 설명한다. 1. Provider 생성 및 설정 모달 컴포넌트를 전역적으로 관리하기 위해 ModalProvider를 작성한다. 이 Provider는 모든 모달을 포함하며, 전역 상태를 통해 어떤 모달을 표시할지 제어한다...
Web Vitals는 구글에서 웹사이트 성능의 핵심 지표를 정의한 것이다. 이는 사용자가 웹사이트에서 경험하는 중요한 측면을 측정하고, 웹 페이지의 품질을 평가하는 데 도움을 준다. Web Vitals에는 LCP(Largest Contentful Paint), FID(First Input Delay), CLS(Cumulative Layout Shift...
JWT와 세션 연결은 서로 다른 인증 및 상태 관리 방식을 결합하여 보안성과 확장성을 모두 확보하는 방식이다. 이를 통해 각각의 단점을 보완하고, 시스템 요구사항에 맞는 최적의 인증 및 상태 관리 전략을 설계할 수 있다. JWT와 세션을 연결하는 이유 JWT의 단점 보완: JWT는 무상태(stateless)로 설계되어 ...
쿠키(Cookie), 세션(Session), 토큰(Token)은 웹 애플리케이션에서 사용자 인증과 상태 관리를 위해 사용되는 기술로, 각각의 특징과 사용 방식에서 차이가 있다. 1. 쿠키 (Cookie) 정의: 쿠키는 웹 브라우저에 저장되는 작은 데이터 파일이다. 서버에서 클라이언트로 보내지고, 클라이언트는 이를 다시 서버에 보내면서 상태...
1. WebSocket이란? WebSocket은 클라이언트와 서버 간의 양방향, 지속적 연결을 지원하는 프로토콜이다. HTTP 요청-응답 방식과 달리 WebSocket은 연결이 한 번 성립되면 서버와 클라이언트가 실시간으로 데이터를 주고받을 수 있는 통신 채널을 유지한다. 주로 채팅, 실시간 알림, 스트리밍 서비스 등 실시간성이 중요한 애플리케이...
Lighthouse는 웹 페이지의 품질을 측정하는 오픈 소스 툴이다. 성능, 접근성, SEO 등을 측정하며, 각 항목에 대해 점수와 개선 사항을 제공한다. Lighthouse의 주요 요소는 다음과 같다. 1. Performance (성능) 웹 페이지의 로딩 속도와 관련된 성능을 측정한다. 측정 지표: First Co...
1. Jest란? Jest는 JavaScript 애플리케이션을 테스트하기 위한 강력하고 사용하기 쉬운 테스트 프레임워크이다. Facebook에서 개발했으며, React와 같은 라이브러리뿐만 아니라 일반 JavaScript 프로젝트에서도 사용된다. Jest는 테스트 작성, 실행, 디버깅을 간소화하며 단위 테스트(Unit Testing), 통합 테스...
1. 초기 설정 1-1. 패키지 설치 npm install socket.io socket.io-client 1-2. socket.ts 파일 생성 서버 측 설정을 위해 pages/api/socket.ts 파일을 생성한다. import { Server } from "socket.io"; import type { NextApiRequest } f...
1. React Query란? React Query는 React 애플리케이션에서 서버 상태(server state)를 효율적으로 관리하기 위한 라이브러리이다. 데이터 패칭, 캐싱, 동기화, 갱신과 같은 복잡한 작업을 간단한 API로 처리할 수 있다. 주요 사용 사례: REST API 또는 GraphQL에서 데이터를 가져오기. 서버와 클...
1. Docker란? Docker는 애플리케이션을 실행하기 위한 컨테이너(Container)를 생성, 배포, 관리할 수 있는 오픈 소스 플랫폼이다. 컨테이너는 애플리케이션과 그에 필요한 모든 라이브러리, 종속성을 하나의 패키지로 묶어 제공하며, 개발 환경과 운영 환경 간의 차이를 최소화한다. Docker를 사용하면 소프트웨어가 어디에서나(로컬 개...
1. CI/CD란? CI/CD(Continuous Integration and Continuous Deployment)는 애플리케이션 개발에서 빌드, 테스트, 배포를 자동화하는 프로세스를 말한다. CI(Continuous Integration, 지속적 통합) 개발자들이 작성한 코드를 정기적으로 병합하고, 병합된 코드에 대...
1. Prisma와 PostgreSQL Prisma는 현대적인 ORM으로, 데이터베이스와 애플리케이션 간의 상호작용을 쉽게 만들어주는 도구이다. 일반적인 ORM과 달리 타입 안전성과 개발자 경험에 초점을 맞추어, 더 효율적이고 오류를 줄이는 코드를 작성할 수 있게 돕는다. ORM(Object-Relational Mapping): 객체 지향 프...
여행 경로 주어진 항공권을 모두 사용하여 ICN에서 출발하는 여행 경로를 찾는 문제 알파벳 순서가 앞서는 경로를 우선적으로 선택하고, 모든 항공권이 사용되어야 하며 모든 도시를 방문할 수 없는 경우는 없다. 풀이 전략 그래프 생성 항공권 정보를 바탕으로 인접 리스트 형태의 그래프를 생성한다. 각 공항에서 갈 수 있는 ...
아이템 줍기 캐릭터의 초기 위치와 아이템의 위치가 주어질 때, 다각형의 테두리를 따라 이동해야 하며 가장 짧은 거리를 구하는 문제 여러 직사각형으로 이루어진 다각형 테두리(둘레)를 따라 캐릭터가 아이템까지 이동한다. 풀이 전략 좌표 확장 및 테두리 정의좌표를 2배 또는 2배 이상 확장하여 정밀도를 높인다. 이렇게 하면 테두리와 내부를 ...
최소직사각형 완전 탐색이나 최적화 로직을 통해 모든 명함을 수납할 수 있는 최소 크기의 지갑을 계산하는 문제 명함을 적절히 회전하여 모든 명함의 긴 변이 하나로 정렬되도록 하면 문제를 간단히 해결할 수 있다. 풀이 전략 명함 회전 처리 각 명함의 가로 길이(w)와 세로 길이(h)를 비교하여, 더 긴 변이 가로가 되도...
더 맵게 모든 음식이 K 이상이 될 때까지 섞어야 하는 최소 횟수를 구하는 문제 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 두 개의 가장 낮은 스코빌 지수를 섞는 과정을 반복한다. 각 섞는 과정은 다음과 같다: 새로운 스코빌 지수 = (가장 낮은 스코빌 지수) + (두 번째로 낮은 스코빌 지수 * 2) 풀이 전략 우선...
힙(Heap)이란? 힙은 완전 이진트리를 기반으로 하는 자료구조이다. 특정한 조건을 만족하도록 설계된 구조로써 주로 우선순위 큐를 구현할 때 사용된다. 힙을 적절히 사용하기 위해 자세히 알아보도록 하자. 힙의 특징 힙 속성 최대 힙 부모 노드의 키 값이 자식 노드의 키보다 크거...
게임 맵 최단 거리 게임 맵에서 시작점에서 목표 지점까지의 최단 거리를 찾는 문제 풀이 전략 큐 초기화 시작점 (0, 0)에서 BFS를 시작한다. 큐에 [y좌표, x좌표, 거리]를 저장한다. 탐색 진행 큐에서 하나씩 꺼내 네 방향으로 이동 가능한 위치를 확인한다. ...
스택 (LIFO, pop & push) 1. 올바른 괄호 스택(Stack) 자료구조를 사용하여 괄호 문자열이 올바른지 판별하는 문제 풀이 전략 괄호를 저장하기 위해 스택 사용 문자열 순회 여는 괄호인 경우 스택에 추가 닫는 괄호인 경우 스택이 비어 있다면, fals...
1. 폰켓몬 최대 N/2 마리의 폰켓몬을 선택하면서, 폰켓몬 종류의 최대 개수를 구하는 문제 풀이 전략 중복을 제거한 폰켓몬 종류의 개수를 구한다. (set을 사용하여 중복 제거). 가능한 최대 폰켓몬 종류 수는 N/2입니다. 즉, nums에서 고를 수 있는 폰켓몬의 종류는 N/2마리입니다. 하지만 폰켓몬의 종류가 N/2보다 적으면 그 ...
스택과 큐는 데이터를 저장하고 처리하는 방법을 정의하는 가장 기본적인 자료구조이다. 둘 다 선형 자료구조지만, 데이터를 삽입하고 삭제하는 규칙이 다르다. 스택과 큐에 대한 정의와 차이점에 대해 자세히 알아보자. 스택(Stack) - LIFO(Last In First Out) 정의 스택은 후입선출(LIFO, Last In First Out) ...
⚡️ Socket을 사용한 Real-Time 채팅 구현하기 - (4) useInfiniteQuery Hook 구현하기 이전 글에서 다룬 내용 Socket.io 초기 설정 채팅 입력창 및 메시지 전송 API 구현 무한 스크롤을 지원하는 채팅 메시지 UI 구현 이번 글에서는 무한 스크롤을 지원하는 채팅 메시지 ...
★ 탐욕법(Greedy Algorithm) 최적의 선택을 위한 알고리즘 탐욕법(Greedy Algorithm)은 현재 상황에서 가장 좋아 보이는 선택을 반복적으로 수행하여 문제를 해결하는 알고리즘 설계 기법이다. 탐욕법은 최적해를 보장하기 위해 문제 자체가 특정 조건(탐욕적 선택 속성, 최적 부분 구조)을 만족해야 한다. 탐욕법의 핵심 개념...
K번째 수 배열 조작과 정렬을 포함한 간단한 알고리즘 구현 문제 풀이 전략 명령 처리 각 command의 값 i, j, k를 구조 분해 할당으로 꺼낸다. array.slice(i - 1, j)를 통해 i번째부터 j번째까지를 잘라낸다. 정렬: 자른 배열을 sliced.sort...
타겟 넘버 (DFS: 깊이 우선 탐색) 숫자 배열에서 각 숫자에 더하기(+)와 빼기(-)를 적용해 주어진 타겟 넘버를 만드는 방법의 수를 계산하는 문제 풀이 전략 DFS 함수 정의 dfs(index, currentSum) 형태로 정의. index는 현재 탐색 중인 숫자의 인덱스를 나타낸다. curre...
깊이 우선 탐색(DFS)과 너비 우선 탐색(BFS) DFS(Depth-First Search)와 BFS(Breadth-First Search)는 그래프 탐색 알고리즘 중 가장 기본적인 기법이다. 그래프는 정점(Vertex)과 간선(Edge)으로 구성되며, 두 탐색 알고리즘은 서로 다른 방식으로 그래프의 정점을 탐색한다. ★ DFS(Depth-F...
📢 Socket을 사용한 Real-Time 채팅 구현하기 - (3) 채팅 메시지 컴포넌트 구현하기 이전 글에서 했던 작업 (1) Socket IO 초기 세팅 (2) 채팅 입력창 및 메시지 전송 API 구현 이번 글에서는 실제로 채팅 메시지들을 렌더링하는 컴포넌트를 구현한다. 메시지를 불러올 때 페이징을 적용하여 성...
2️⃣ Socket으로 채팅 구현하기 이번 글에서는 Socket.IO를 활용한 실시간 채팅에서 메시지를 입력하고 서버로 전송하는 과정을 다룬다. 이전 글에서 Socket.IO를 초기 설정했으므로, 이제 실제 채팅 기능을 구현해보자. 1️⃣ Chat Input 컴포넌트 구현 Socket을 활용한 채팅 애플리케이션의 메시지를 입력받는 컴포넌트를 구현...
👩💻 Socket을 사용한 Real-Time 채팅 구현하기 실시간 채팅을 구현하기 위해서는 WebSocket을 활용해야 하며, 이를 보다 쉽게 다룰 수 있도록 해주는 라이브러리가 Socket.IO이다. 이번 글에서는 Next.js에서 Socket.IO를 활용하여 실시간 채팅을 구축하는 초기 설정 방법을 다룬다. 1️⃣ Socket.IO 초기 ...