본문 바로가기

Frontend (153)

반응형
Frontend/React

[React] 이미지 로딩 최적화로 LCP 50% 개선하기 (WebP, srcset, Intersection Observer)

웹 서비스에서 가장 많은 트래픽 용량을 차지하는 리소스는 단연 이미지입니다. 고화질 이미지가 많아질수록 로딩 속도는 느려지고, 이는 곧 사용자의 이탈(Bounce Rate)로 이어집니다. 오늘은 프론트엔드 성능 최적화의 핵심인 대표적인 이미지 최적화 기법들(WebP, srcset, Intersection Observer)을 프로젝트에 적용하여 로딩 속도와 사용자 경험을 개선한 과정을 정리해보았습니다. 1. 차세대 이미지 포맷 WebP 도입 (feat. )JPG나 PNG는 범용성이 좋지만 용량이 큽니다. 구글이 개발한 WebP 포맷을 사용하면 동일 화질 대비 용량을 30~50% 까지 줄일 수 있습니다. 하지만, IE 같은 구형 브라우저는 WebP를 지원하지 않습니다. 이를 해결하기 위해 HTML5의 태그..

2026. 2. 1.
Frontend/Next.js

[Next.js] Turborepo와 pnpm을 사용하여 Monorepo 구축

최근 Frontend 생태계에서 Monorepo는 선택이 아닌 '필수'가 되어가고 있는 추세입니다. 여러 개의 프로젝트와 라이브러리를 하나의 저장소에서 관리하면 코드 재사용성이 높아지고, 의존성 관리가 쉬워지는게 주된 이유입니다. 오늘은 그 중에서도 가장 핫한 조합인 Turborepo와 pnpm을 사용하여 Monorepo를 구축해보겠습니다.1. pnpm과 Turborepo를 선택한 이유모노레포 도구에는 우리가 알지 못하는 다양한 것들이 있습니다. 예를 들면, Nx나 Lerna 등이 있습니다. 그런데 저는 왜 pnpm과 Turborepo를 골랐을까요? pnpm(Performant npm) Phantom Dependency 해결: npm이나 yarn과 달리, package.json에 명시되지 ..

2026. 1. 31.
Frontend/React

[React] 리액트가 빠른 진짜 이유: Virtual DOM부터 Fiber까지 완벽 해부

프론트엔드 개발자라면 누구나 리액트(React)를 사용합니다. 하지만 면접장에서 "리액트는 왜 빠르죠?" 혹은 "Virtual DOM이 정확히 뭔가요?" 라는 질문을 받으면 의외로 말문이 막히는 경우가 많습니다. 오늘은 리액트의 핵심 엔진인 Virtual DOM의 정체와, 리액트가 어떻게 브라우저 렌더링 성능을 극한으로 끌어올리는지 그 내부 원리(Reconciliation, Fiber)를 아주 깊이 있게 파헤쳐 보겠습니다.1. 문제의 시작: DOM은 너무 비싸다 우리가 웹사이트에서 "좋아요" 버튼 하나를 누를 때마다 브라우저 내부에서는 엄청난 일이 벌어집니다.// 기존의 방식 (Vanilla JS)document.getElementById('container').innerHTML = 'New Conten..

2026. 1. 25.
Frontend/Javascript

[Javascript] 이벤트 루프 도대체 어떻게 돌아가는 걸까? (완전 정복)

자바스크립트는 싱글 스레드 언어입니다. 개발 공부를 하다 보면 귀에 딱지가 앉도록 듣는 말입니다. 그런데 이상하지 않나요? 싱글 스레드는 '손이 하나'라는 뜻인데, 어떻게 우리는 웹사이트에서 데이터를 불러오면서 동시에 애니메이션을 보고, 버튼도 클릭할 수 있는 걸까요? 이 마법 같은 동시성의 비밀, 이벤트 루프(Event Loop)를 아주 상세하게 뜯어보겠습니다.1. 등장인물 소개: 런타임 4대장자바스크립트가 돌아가는 환경(브라우저)은 거대한 공장과 같습니다. 이 공장에는 4가지 핵심 구역이 있습니다.JS Engine (Call Stack)역할: 실제 코드를 실행하는 작업대특징: 싱글 스레드이므로 작업대가 딱 하나입니다. 한 번에 한 가지 일만 처리할 수 있습니다. (LIFO: 나중에 들어온게 먼저 나감..

2026. 1. 24.
Frontend/Next.js

[Next.js] OG 태그 설정 (feat. 카톡 링크 설정)

분명 다른 멋진 사이트들은 링크만 올려도 예쁜 썸네일 이미지와 제목이 뜨는데, 내 사이트는 왜 휑하게 URL만 덩그러니 뜨는 걸까요? 범인은 바로 OG(Open Graph) 태그의 부재입니다. 오늘은 내 사이트를 '프로페셔널하게' 보이게 만드는 가장 쉬운 방법, OG 태그에 대해 알아봅니다.1. 오픈 그래프(Open Graph)가 뭔가요?오픈 그래프(OG)는 쉽게 말해 "내 웹사이트의 디지털 명함"입니다. 카카오톡, 슬랙, 페이스북, 트위터(X) 같은 SNS 봇들은 링크가 공유되면, 그 사이트에 잽싸게 접속해서 "이 사이트를 어떻게 요약해서 보여줄까?" 하고 정보를 긁어갑니다. 이때 봇들이 참고하는 표준 규약이 바로 og:로 시작하는 메타 태그들입니다. 이 명함을 제대로 파놓지 않으면, 봇들은 무엇을 보..

2026. 1. 18.
Frontend/Next.js

[Next.js] LCP 1초대로 줄이고 구글 점수 따내기

우리가 어떤 링크를 클릭하고 화면이 하얗게 멈춰있을 때, '뒤로 가기'를 누르고 싶은 충동이 들기까지 걸리는 시간은 얼마나 될까요? 놀랍게도 평균 3초라고 합니다. 아무리 디자인이 예쁘고(FOUC 해결), 화면이 안 흔들려도(CLS 해결), 일단 화면에 뭐가 떠야 사용자가 머무릅니다. 오늘은 사용자의 인내심이 바닥나기 전에 메인 화면을 '탁!' 하고 띄워주는 핵심 지표, LCP(Largest Contentful Paint)를 공략해 봅니다.1. LCP (Largest Contentful Paint)가 뭔가요?LCP는 단어 그대로 "가장 큰(Largest) 콘텐츠가 그려지는(Paint) 시간"입니다. 브라우저는 화면을 그릴 때 로고, 메뉴, 텍스트 등을 순차적으로 보여줍니다. 사용자는 자잘한 메뉴가 떴을 ..

2026. 1. 17.
Frontend/Javascript

[Javascript] 구글이 싫어하는 CLS(Cumulative Layout Shift) 공략하기

기사를 읽고 있는데 갑자기 텍스트가 훅 내려가서 읽던 줄을 놓치거나, '취소' 버튼을 누르려던 찰나에 위에 이미지가 로딩되면서 버튼이 밀려나고 실수로 '결제' 버튼을 눌러버리는 경험. 다들 한 번쯤 있으시죠? 이 끔찍한 사용자 경험의 이름이 바로 CLS(누적 레이아웃 이동)입니다. 오늘은 웹사이트 '화면 깨짐 3대장'의 마지막 보스, CLS를 완벽하게 공략해 봅니다.1. CLS (Cumulative Layout Shift)가 도대체 뭔가요?CLS는 쉽게 말해 "사용자가 예상치 못한 시점에 웹 페이지의 요소들이 얼마나 덜컥거리며 위치를 바꾸는지"를 점수로 매긴 것입니다. 웹페이지는 리소스(이미지, 폰트, 광고 스크립트 등)를 비동기적으로 다운로드합니다. 브라우저가 "아, 여기엔 이따가 이미지가 들어올 거야..

2026. 1. 11.
Frontend/Next.js

[Next.js] Text content does not match server-rendered HTML 해결 방법

지난 포스팅에서 CSS 로딩 순서를 고쳐 FOUC를 완벽하게(일부분) 잡았습니다. 그런데, Next.js로 마이그레이션을 마쳤는데 버벅이더라구요? 정말 개발은 끝이없음을 다시 한 번 느낍니다... "Text content does not match server-rendered HTML" 분명 CSS는 멀쩡한데 화면이 미묘하게 깜빡이거나 스타일이 튀는 현상. 이건 단순한 스타일 문제가 아닙니다. 바로 하이드레이션 불일치(Hydration Mismatch), 개발자들 사이에서는 일명 '모던 웹의 FOUC'라고 불리는 녀석입니다. 도대체 '하이드레이션'이 뭐길래 우리를 괴롭힐까요?1. 하이드레이션(Hydration): 마른 오징어를 물에 불리는 과정?Next.js와 같은 SSR(Server-Side Rend..

2026. 1. 10.
Frontend/Javascript

[Javascript] FOUC, Flash Of Unstyled Content 완전 정복

웹사이트에 접속했을 때, 아주 짧은 순간 동안 레이아웃이 깨져 보이거나 기본 폰트(굴림, Times New Roman 등)로 내용이 보였다가 갑자기 정상적인 디자인으로 '탁'하고 바뀌는 경험, 해보신 적 있나요? 개발자나 디자이너 입장에서는 등골이 서늘해지는 이 순간, 바로 FOUC 현상입니다. 오늘은 웹 사용자 경험(UX)을 해치는 주범 중 하나인 FOUC가 도대체 왜 발생하며, 어떻게 하면 깔끔하게 해결할 수 있는지 '기가 막히게' 정리해 드립니다.1. FOUC란 무엇인가요?FOUC: Flash Of Unstyled Content. 이름 그대로 해석하면 스타일이 입혀지지 않은 콘텐츠가 순간적으로 번쩍하고 나타나는 현상을 말합니다. 웹 브라우저는 우리가 작성한 HTML(뼈대)과 CSS(디자인)를 읽어서..

2026. 1. 4.
Frontend/Javascript

[Javacsript] <script>의 async와 defer, 차이점 완벽 정리 (feat. 렌더링 성능 최적화)

프론트엔드 개발자 면접 단골 질문이자, 웹 성능 최적화의 가장 기초가 되는 1. 브라우저는 HTML 파싱을 즉시 중단(Block)합니다.2. 스크립트를 다운로드하고 실행합니다.3. 실행이 끝나면 다시 HTML 파싱을 재개합니다. 만약 스크립트 파일이 무겁거나 인터넷이 느리다면, 사용자는 그 시간 동안 하얗게 멈춘 화면만 보게 됩니다. 이것이 바로 우리가 피해야 할 Render Blocking 입니다. 2. 한 눈에 보는 동작 방식이 문제를 해결하기 위해 등장한 것이 async와 defer입니다. 두 속성 모두 HTML 파싱과 스크립트 다운로드를 병렬(Parellel)로 처리하지만, 실행 시점에서 결정적인 차이가 있습니다. 아래 이미지를 참고해주세요. 1) - 다운로드: HTML 파싱과 동시에 진행..

2026. 1. 3.
Frontend/Debug Log

[에러 해결] Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.

이번 글에서는 아래 에러에 대해서 다루어 보겠습니다.Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.  [에러 원인]위 에러 메시지는 React 컴포넌트의 타입이 잘못되었음을 의미합니다. 즉, React는 문자열(내장 컴포넌트)이나 클래스/함수(사용자 정의 컴포..

2024. 9. 1.
Frontend/Debug Log

[에러 해결] Prop `className` did not match ~ in Next Js

Next.js로 토이프로젝트를 진행하던 도중에 아래와 같은 오류가 발생하였습니다.warning: Prop `className` did not match. Server: "MuiFormControl-root sc-iKTcqh gwSKiw css-1nrlq1o-MuiFormControl-root" Client: "MuiFormControl-root sc-gJhJTp gehcyX css-1nrlq1o-MuiFormControl-root"  [발생 원인]저는 Next.js로 styled-components와 Material-UI를 사용하고 있었습니다. 그런데 왜 이런 경고가 발생했을까요?이 경고는 서버에서 렌더링된 클래스 이름과 클라이언트에서 렌더링된 클래스 이름이 일치하지 않아서 발생합니다. 주로 SSR환경에..

2024. 8. 24.
Frontend/Javascript

ESLint와 Prettier로 코드 자동 정렬 설정 with Airbnb

코드를 저장할 때 자동으로 정렬하거나 포맷팅해주는 기능을 적용하려면 ESLint와 Prettier를 함께 사용해야 합니다. 이번 글에서는 Next.js와 TypeScript 프로젝트에 ESLint와 Prettier를 설정하는 방법에 대해 작성해보겠습니다.1. ESLint 및 Prettier 설치먼저 필요한 패키지들을 설치합니다.npm info "eslint-config-airbnb@latest" peerDependencies;2. Prettier 설정 파일 생성프로젝트 루트에 .prettierrc 파일을 생성하여 Prettier 설정을 추가합니다.{ "endOfLine": "lf", "singleQuote": true, "semi": true, "useTabs": false, "tabWidth"..

2024. 8. 10.
Frontend/React

[React] Compound Pattern 파헤치기

이번 글에서는 Compound Pattern에 대해 알아보겠습니다. 그러기 위해선 먼저 Compound(합성)에 대해 알아볼 필요가 있습니다. 합성에 대해 익숙하지 않은 분은 아래의 포스팅을 보시고 돌아와서 다시 글을 읽는 것을 권장드립니다.링크 바로가기 ➔ [React] 컴포넌트 합성이란?Compund Pattern이란?Compund(합성) 컴포넌트 패턴은 컴포넌트 합성의 장점을 활용하기 위해서 구안된 패턴입니다.즉, “하나의 컴포넌트를 여러 가지 집합체로 분리한 뒤, 분리된 각 컴포넌트를 사용하는 쪽에서 조합해 사용하는 방식” 이라고 볼 수 있습니다. 저희가 즐겨 쓰는 select 컴포넌트가 바로 합성 컴포넌트 패턴의 형태를 잘 띈 대표적인 예시라고 볼 수 있습니다.select 컴포넌트는 변경에 대한..

2024. 7. 13.
Frontend/React

[React] 컴포넌트 합성이란?

모던 웹 개발에서 컴포넌트 기반 아키텍처는 빠르게 표준이 되었습니다. 특히 React와 같은 라이브러리를 사용하면 UI를 작은, 재사용 가능한 컴포넌트로 분리하여 개발하는 것이 일반적입니다. 하지만 이 과정에서 단순히 컴포넌트를 나누는 것만으로는 부족합니다. 여기서 중요한 개념이 바로 컴포넌트 합성입니다. 컴포넌트 합성은 여러 개의 작은 컴포넌트를 조합하여 더 큰 기능을 수행하는 컴포넌트를 만드는 방법을 의미합니다. 이 접근 방식은 코드의 재사용성을 높이고, 유지보수를 쉽게 하며, 복잡한 UI를 관리하는 데 매우 유용합니다. 따라서 컴포넌트 합성은 단순히 좋은 습관이 아니라, 효율적이고 확장 가능한 애플리케이션을 개발하는 데 필수적인 기술입니다. 이번 글에서는 컴포넌트 합성이 왜 중요한지, 어떻게 적용할..

2024. 7. 6.
Frontend/Debug Log

ERR_PNPM_ADDING_TO_ROOT 해결 방법

Pnpm으로 의존성 패키지를 설치 하였는데 아래와 같은 오류가 발생하였습니다. ERR_PNPM_ADDING_TO_ROOT  Running this command will add the dependency to the workspace root, which might not be what you want - if you really meant it, make it explicit by running this command again with the -w flag (or --workspace-root). If you don't want to see this warning anymore, you may set the ignore-workspace-root-check setting to true.  [에러 원인..

2024. 6. 23.
Frontend/Debug Log

img is a self-closing tag and must neither have `children` nor use `dangerouslySetInnerHTML`. 해결 방법

사이드 프로젝트로 코딩하던 도중, 일반적인 img태그와 Next.js에서 제공하는 Image태그를 비교하다가 아래와 같은 에러가 발생하였습니다.img is a self-closing tag and must neither have `children` nor use `dangerouslySetInnerHTML`. 해석하자면, "img는 자동 닫힘 태그로 자식을 두거나 속성으로 dangeroslySetInnerHTML을 사용해서는 안 됩니다."인데 여기서 자동 닫힘 태그란 간단하게 자식이 없는 태그입니다.// 자동 닫힘 태그// 자동 닫힘 태그 아님블라블라 // dangerouslySetInnerHTML 속성 사용 불가Example' }} /> 에러 원인이미지 태그에서 컨텐츠를 가져서 그렇습니다. 작업하다가 ..

2024. 6. 1.
Frontend/React

[React] Flux 패턴과 Elm 아키텍처

이번 글에서는 React 상태 관리의 근간이 되는 Flux 패턴의 등장 배경과 핵심 원리를 살펴보고, 이를 더욱 견고하게 발전시킨 Elm 아키텍처가 현대 프론트엔드 개발에 남긴 유산에 대해 깊이 있게 다뤄보겠습니다. 이를 통해 복잡해 보이는 상태 관리 코드가 사실은 얼마나 우아한 수학적 모델 위에서 동작하는지 알아보겠습니다.Flux 패턴의 등장 배경아래 그림에서 보실 수 있듯이 기존의 MVC 패턴은 상태를 변경하는데 추적하고 이해하기가 매우 어려운 상황이였습니다.페이스북 팀은 이러한 문제의 원인을 양방향 데이터 바인딩으로 봤습니다. 뷰(HTML)가 모델(자바스크립트)을 변경할 수 있으며, 반대의 경우 모델도 뷰를 변경할 수 있습니다. 이는 코드를 작성하는 입장에서는 간단할 수 있지만 코드의 양이 많아지고..

2024. 5. 18.
반응형