Query Key는 캐시 주소이자 계정 경계다 — BI 서비스의 React Query 캐시 규칙
Query Key 설계 규칙, mutation 이후 cancel → invalidate 순서, 삭제 시 remove가 필요한 이유, 그리고 계정 전환·늦은 401을 다루는 세션 세대 스코프까지. BI 서비스 두 앱이 공유하는 캐시 정책을 정리했다.
개발하면서 배운 것들을 주제별로 정리합니다.
Query Key 설계 규칙, mutation 이후 cancel → invalidate 순서, 삭제 시 remove가 필요한 이유, 그리고 계정 전환·늦은 401을 다루는 세션 세대 스코프까지. BI 서비스 두 앱이 공유하는 캐시 정책을 정리했다.
초기 번들이 왜 성능을 좌우하는지부터, 코드 스플리팅(React.lazy·동적 import)·트리 셰이킹(ESM·sideEffects)·의존성 다이어트(경량 대체·부분 import)·번들 분석까지 정리한다. 압축·폴리필 같은 흔히 놓치는 포인트와 React/Next 관점의 적용까지.
구글의 핵심 사용자 경험 지표 LCP(로딩)·INP(반응성)·CLS(시각 안정성)를 각각 측정 대상·기준선·원인·개선법으로 정리한다. 2024년 FID를 대체한 INP, lab vs 필드 데이터 측정 방식, 그리고 next/image·next/font·useTransition 같은 React/Next 관점의 개선 연결까지.
XSS는 코드를 주입하는 공격, CSRF는 요청을 위조하는 공격이다. 둘은 본질이 달라 방어도 다르다. React의 자동 escape와 dangerouslySetInnerHTML·DOMPurify, SameSite 쿠키와 CSRF 토큰, 그리고 마지막 안전망인 CSP까지 — 무엇이 무엇을 막는지 정리한다.
세 버전의 차이를 'HOL 블로킹이 어느 계층에서 일어나느냐'는 한 축으로 정리한다. HTTP/2의 멀티플렉싱이 HTTP 계층 HOL을, HTTP/3의 QUIC이 TCP 계층 HOL까지 없애는 과정과, 그 결과 도메인 샤딩·CSS 스프라이트·과한 번들 같은 1.1식 최적화가 왜 안티패턴이 되는지까지.
react-dom의 리소스 힌트 API(prefetchDNS·preconnect·preload·preinit)가 각각 DNS·연결·다운로드·실행 어디까지 처리하는지 정리한다. 멱등이라 렌더 중에 직접 호출하는 게 기본이고(useEffect 불필요), 이벤트 핸들러·Server Component에서도 호출 가능한 이유와 호출 위치별 패턴까지.
네 키워드를 두 그룹으로 나눠 정리한다. async/defer는 스크립트의 실행 타이밍(받는 즉시 vs 파싱 후 순서대로)을, preload/prefetch는 리소스를 미리 받는 우선순위(현재 페이지 높음 vs 다음 페이지 낮음)를 다룬다. 타임라인 비교와 preconnect 같은 친척 힌트까지.
주소창에 URL을 입력한 순간부터 픽셀이 그려지기까지의 전 과정을 정리한다. DNS·TCP·TLS·HTTP 네트워크 단계와, DOM·CSSOM·Render Tree·Layout·Paint·Composite로 이어지는 Critical Rendering Path. reflow와 repaint의 차이, transform·opacity가 싼 이유와 렌더링 최적화 팁까지.
HttpOnly·Secure·SameSite가 각각 무슨 공격을 막고 무엇은 못 막는지, localStorage와 HttpOnly 쿠키의 트레이드오프, __Host- 접두사, 그리고 액세스 토큰은 메모리·리프레시 토큰은 HttpOnly 쿠키에 두는 실무 패턴까지. 핵심은 'XSS는 HttpOnly, CSRF는 SameSite'라는 두 축이다.
transform·opacity가 싸다는 건 알아도 '왜'를 설명하긴 어렵다. 핵심은 GPU가 아니라 메인 스레드 경합에서 벗어난다는 점이다. 렌더링 파이프라인의 어느 단계를 건너뛰는지, 레이어 합성과 레이어 승격이 무엇인지, will-change가 정확히 무슨 일을 하는지, 그리고 왜 남용하면 안 되는지를 정리한다.
Cache-Control·ETag·Last-Modified가 동작하는 방식을 강한 캐시(요청조차 안 보냄)와 조건부 캐시(stale 시 검증 → 304 재사용) 두 단계로 정리한다. no-cache와 no-store의 차이, immutable·stale-while-revalidate, 그리고 '해시 자산은 영구 캐시, HTML은 no-cache'라는 실무 배포 전략까지.
React 19의 핵심을 Actions(useActionState·useFormStatus·useOptimistic)와 보일러플레이트 제거(forwardRef·Context.Provider 사라짐)로 정리한다. use API, 문서 메타데이터, 제거된 API와 함께, Server Components가 무엇이고 SSR과 어떻게 다른지 경계·조합 규칙까지 자세히 다룬다.
React 17까지 렌더링은 중단 불가능했고, 무거운 렌더가 입력 반응성을 잡아먹었다. Concurrent 렌더링의 우선순위·중단 가능 개념을 짚고, useTransition(내가 호출하는 setState)과 useDeferredValue(제어 못 하는 값)의 차이와 사용처, '빨라지는 게 아니라 반응성을 지킨다'는 핵심까지 정리한다.
tsconfig의 strict: true가 한꺼번에 켜는 하위 플래그들을 정리한다. 타입 안전의 두 축인 strictNullChecks·noImplicitAny부터 strictFunctionTypes·strictPropertyInitialization·useUnknownInCatchVariables까지, 각 플래그가 무엇을 막는지와 JS→TS 마이그레이션 시 점진 적용 전략.
T extends U ? X : Y 조건부 타입과 infer 키워드로 함수 반환·배열 요소·Promise 내부 타입을 추출하는 원리를 정리한다. 헷갈리는 분배(distributive) 동작, 재귀 조건부 타입, 템플릿 리터럴 추출, infer 제약까지. ReturnType·Awaited의 정체를 직접 읽어본다.
ESM과 CommonJS의 문법·동작 차이를 '정적 vs 동적'이라는 한 축으로 정리한다. import/export가 정적이기에 가능해지는 트리 셰이킹의 원리(실행 없이 미사용 제거)와 비동기 로딩의 원리(파싱→병렬 다운로드→평가 3단계)를, CommonJS의 동기 require와 대비해 자세히 설명.
싱글 스레드인 자바스크립트가 비동기를 처리하는 원리. 콜스택·Web API·태스크 큐·마이크로태스크 큐의 관계와 이벤트 루프의 실행 규칙을, setTimeout vs Promise·await의 동작과 실행 순서 예제로 정리한다.
React가 state를 참조로 비교한다는 사실에서 출발해, 직접 수정의 함정과 '바뀐 경로만 얕게 펼치는' 불변 업데이트 정석을 정리한다. 구조적 공유(structural sharing) 관점에서 structuredClone·깊은 복사가 성능과 메모이제이션을 깨뜨리는 이유, 그리고 Immer까지.
클로저가 '값이 아니라 변수를 기억한다'는 원리에서 출발해, React에서 리렌더마다 새 클로저가 생기는 멘탈 모델과 stale closure 문제를 짚는다. setInterval·디바운스·비동기 콜백에서 옛 state에 갇히는 원인과, 함수형 업데이트·ref·useReducer 등 해결책을 정리.
Partial·Pick·Omit·Record·ReturnType 등 자주 쓰는 유틸리티 타입을 분류별로 정리하고, 이들이 매핑 타입(`[K in keyof T]`)으로 어떻게 구현되는지 직접 만들어 본다. 타입 중복을 없애고 단일 출처를 유지하는 실무 조합 패턴까지.
변성(variance)을 '이 자리에 넣어도 호출이 안전한가'라는 한 기준으로 정리한다. 반환 타입·배열이 공변인 이유, 함수 매개변수가 반공변인 이유를 Dog/Animal 치환 예제로 풀고, TypeScript의 이변(bivariance)과 strictFunctionTypes까지 짚는다.
클로저의 정의를 '함수 + 렉시컬 환경의 조합'이라는 표준 정의에서 출발해 정확히 풀어낸다. 렉시컬 환경·렉시컬 스코프·스코프 체인이라는 용어를 정리하고, makeCounter 예제로 makeCounter가 끝나도 변수가 살아남는 이유를 그림과 함께 설명.
div에 role="button" 붙이면 접근성이 끝일까. 모달을 예로 ARIA가 무엇을 하고 무엇을 안 하는지, aria-modal·aria-labelledby·aria-hidden의 함정과 inert까지 정리한다.
WAI-ARIA APG 기준으로 탭·아코디언·disclosure·스위치·메뉴·라이브 리전을 필요한 ARIA + 키보드 동작 + 흔한 실수 중심으로 정리한다. 핵심은 roving tabindex와 화살표 키.
알스솔루션의 여러 레포가 어떻게 결합돼 있는지 분석. 앱끼리는 서로 의존하지 않고 모든 결합이 공유 라이브러리(부트스트랩·API 계약·린트)로 단방향 fan-in 하는 구조, 그리고 처음 식별했던 정확버전 핀·툴체인 drift 리스크가 이후 어떻게 해소됐는지까지 정리.
als-bi 프로젝트에서 서버 상태(React Query)와 클라이언트 전역 상태(Zustand)를 어떻게 나누고 어디서 연결하는지, 그리고 SessionBootstrap이 풀어주는 쿠키 ↔ store 정합성 문제까지 정리.
사내 백오피스(admin-als) 프론트엔드 빌드 산출물을 Persistent Volume에 적재하고, Kubernetes Nginx Pod가 정적 파일을 서빙하는 배포 구조. Jenkins 빌드 → PV 전송 → GitOps 반영 흐름 정리.
PWA에서 푸시 알림을 띄우려면 왜 서버가 필요한지, 그리고 직접 서버를 운영하지 않고 Firebase Cloud Messaging으로 같은 효과를 내는 방법. VAPID 키 발급부터 firebase-messaging-sw.js까지.
CRA의 PWA 템플릿 대신 Vite 환경에서 PWA를 구성한 과정. serviceWorkerRegistration vs registerSW, service-worker.ts의 역할, manifest.json 옵션, autoUpdate/prompt 모드와 skipWaiting까지 정리.
partners-2에서 aws-amplify를 v4에서 v6로 올리며 바뀐 Storage API 정리. config 타입, put/get/remove 호출 방식의 Before/After.
4자리 쿠폰 코드 입력 컴포넌트를 만들면서 마주친 키패드·포커스·마스킹·리셋 등 다양한 요구사항과 AOS·iOS의 입력 동작 차이로 인한 트러블슈팅 정리.
ui-kit 1.0.80 → 1.0.81 업데이트 후 포스 화면의 border 색상이 모두 검정으로 바뀐 사건. extends.colors가 theme.colors로 덮어씌워지면서 currentColor가 적용되어버린 원인 분석과 해결.
pm2로 운영하던 엣지 프로젝트를 nginx 정적 콘텐츠 서비스로 이관하고, Ansible Semaphore + Jenkins + AWS S3를 잇는 단일 배포 파이프라인을 구축한 과정. yaml/Configure 변경 디테일과 트러블슈팅까지.
엣지 배포 프로젝트의 WebServer를 pm2 serve에서 nginx로 변경하면서 가장 오래 걸렸던 권한 설정 정리. 파일 권한 표기, chmod/chown/chgrp, 그리고 실제 nginx 실행 시 만난 500 에러와 해결 과정.
이전 tech talk에서 발췌된 Virtual DOM에 대해 정리. 정의, 사용 이유, 직접 구현 자료까지.
react-query v5로 업그레이드하면서 발견한 mutate/mutateAsync의 onSuccess 동작 차이. 코드를 직접 뜯어보며 정리한 가설과 결론.
React 18로 업그레이드하면서 마주친 ReactDOM.render → createRoot 변경. 왜 새로운 Root API가 도입되었는지 정리.
uikit 라이브러리에서 Modal과 Bottom Sheet를 useContext 기반으로 전역 관리하도록 설계한 과정. 구현·사용·고려해야 할 점·적용 결과까지.
바이비 포스 기능에서 서로 다른 브라우저 탭 사이 실시간 통신이 필요했던 사례. localStorage, BroadcastChannel, Service Worker, Window postMessage 4가지 옵션을 비교하고 BroadcastChannel을 채택한 이유.