브라우저 리소스 요청 과 캐싱 프로세스 흐름
·
FrontEnd/web
CORS, 캐시, CDN을 이해하려고 웹 요청 흐름부터 다시 정리해봤다CORS는 "갑자기 뜨는 에러"가 아니라,브라우저가 리소스를 가져오고, 캐시를 확인하고, 응답 헤더를 검사하는 과정 안에서 발생하는 정책 체크다.CORS 문제를 보다가 오히려 더 헷갈렸던 건 에러 문구 자체보다 흐름이었다.브라우저는 HTML을 받고 나서 뭘 하는지CSS나 JS는 언제 다시 요청하는지캐시는 언제 쓰고, 언제 안 쓰는지CDN이 끼면 응답이 어떻게 달라지는지그리고 CORS는 정확히 어느 시점에 막히는지처음엔 CORS 에러가 났다 = 서버 문제인가? 정도로만 생각했는데, 찾아보면 볼수록 단순한 얘기가 아니었다.그래서 이번엔 CORS만 따로 보지 않고,"사용자가 사이트에 접속해서 브라우저가 화면을 그릴 때까지 어떤 일이 일어나는..
[실무 기록] 브라우저 캐시와 CORS 에러
·
FrontEnd/web
페이지 이동할 때만 간헐적으로 터지던 그 CORS, 왜 강력 새로고침하면 사라졌을까가끔 이런 경우가 있다.처음 들어왔을 때는 멀쩡하다.직접 URL을 치고 들어와도 정상이다.그런데 어떤 페이지를 거쳐 다른 페이지로 이동하면, 갑자기 CSS나 폰트에서 CORS 에러가 난다.심지어 더 헷갈리는 건 Ctrl + Shift + R로 강력 새로고침하면 또 멀쩡해진다는 점이다.처음에는 preload가 문제인가 싶었고, 브라우저 캐시가 어딘가 꼬였나 싶기도 했는데, 결론부터 말하면 핵심은 preload 자체가 아니라 같은 URL을 서로 다른 방식으로 요청하고 있었다는 점이었다.이번 글은 페이지 이동 시 간헐적으로 발생하던 CORS 에러를 추적하면서, 왜 이런 현상이 생겼는지 정리해 둔 기록이다.결론 먼저핵심만 먼저 정..
[실무 기록] 렌더링 차단(Render‑blocking) 줄이려고 preconnect / preload를 썼는데… 진짜 뭐가 좋아지나?
·
FrontEnd/web
[실무 기록] 렌더링 차단(Render‑blocking) 줄이려고 preconnect / preload를 썼는데… 진짜 뭐가 좋아지나?Lighthouse 돌리면 가끔 꼭 뜨는 애들이 있다.Eliminate render‑blocking resources(참고: Chrome 공식 문서) → https://developer.chrome.com/docs/lighthouse/performance/render-blocking-resourcesPreconnect to required origins(리소스 힌트 개념) → https://web.dev/learn/performance/resource-hints대충 "CSS가 렌더링 막고 있어요" "외부 도메인 연결을 미리 하세요" 이런 뜻인데, 막상 적용하려고 보면 헷갈..
[실무 기록] (2탄) macOS에서 adb가 "개발자 신원을 확인할 수 없습니다"로 막혀 Chrome Inspect가 또 안 될 때
·
FrontEnd/web
[실무 기록] (2탄) macOS에서 adb가 "개발자 신원을 확인할 수 없습니다"로 막혀 Chrome Inspect가 또 안 될 때1탄: Chrome Inspect에서 Pending authentication만 뜨고 안드로이드 디버깅이 안 될 때[FrontEnd/web] - [실무 기록] Chrome Inspect에서 Pending authentication만 뜨고 안드로이드 디버깅이 안 될 때 간만에 웹뷰에서 이슈가 있는 것 같다는 얘기를 듣고 테스트용 안드로이드 폰으로 디버깅을 하려는데, 또 연결이 안 됐다.예전에 정리해둔 1탄 글을 보고 따라 했는데도 안 됐고(사실 기억이 잘 안 남…), 결국 처음부터 다시 세팅을 해봤다.이번에 걸린 포인트는 이거였다.1탄에서 받았던 Platform-Tools(A..
Next.js 서버사이드 다국어(SSR) + SEO 테스트 기록 (next-intl, Vercel)
·
FrontEnd/Next.js
개요회사에서 “Next.js에서 서버사이드로 다국어를 어떻게 처리하는지, SEO까지 포함해서 실제로 동작하는지” 확인해달라는 요청을 받았다.우리 회사 환경은 다르지만 Next.js에서 관례적으로 어떻게 하는지를 먼저 정리하고, 최소 규모로 PoC(검증용 데모)를 만들어서 직접 테스트해봤다.1. 회사 요청사항을 내가 이해한 방식요구사항을 “검증 가능한 체크리스트”로 바꾸면 아래 정도였다.서버사이드 렌더링(SSR) 시점에 이미 해당 언어 콘텐츠가 HTML로 내려오는가?검색엔진(특히 Google)이 언어별 페이지를 각각 인덱싱할 수 있는 구조인가?같은 페이지라도 언어가 다르면 URL이 다르게 존재해야 한다.hreflang / canonical / sitemap 같은 SEO 신호가 제대로 나가는지 확인클라이언트..
제미나이 나노바나나로 로고/파비콘 처음 만들어본 후기
·
FrontEnd/A.I
티스토리랑 개인 포트폴리오 사이트를 만들면서로고를 업데이트해야 했고, 파비콘도 새롭게 필요해졌다.요즘 나노바나나가 핫하다는 얘기는 많이 들었는데,솔직히 나는 “좋다더라” 정도만 알고 있었지 직접 써본 적은 없었다.그래서 이번 기회에 한 번 사용해보게 됐다.배경: 왜 로고/파비콘이 필요했나이번에 티스토리 블로그랑 개인 포트폴리오 사이트를 정리하면서전체적인 느낌을 조금 더 통일하고 싶었다.기존에도 이름은 있었지만,브라우저 탭에서 보이는 파비콘까지 포함해서 내 아이덴티티를 보여줄 수 있는 요소가 필요했다.블로그용 로고포트폴리오용 로고브라우저 탭용 파비콘이 3가지를 한 번에 정리하고 싶었던 상황이었다.구글 제미나이라고 검색하여 접속하기좌측 하단에 이미지 만들기 클릭하여 채팅 시작하면된다.나노바나나에 보낸 첫 요..
[실무 기록] <link rel="stylesheet">로 CSS 불러오는데 간헐적으로 CORS 에러가 나던 이유 (해결: crossorigin 제거)
·
FrontEnd/web
어느 날부터 서비스에서 CSS가 간헐적으로 안 먹는 현상이 생겼다콘솔을 보면 CORS 관련 에러가 뜨고, 화면은 스타일이 빠진 채로 깨져 보였다힘들었던 포인트는 이거였다어떤 브라우저에서는 안 터지고어떤 브라우저/디바이스에서는 터지고같은 환경에서도 가끔은 되고, 가끔은 실패원인 파악이 너무 어려웠다.결론우리는 써드파티 라이브러리/CSS를 버저닝 + 캐싱 목적 때문에 회사 S3에 올려두고, 서비스에서는 그 S3 주소로 직접 로드하고 있었다.그런데 로 CSS를 불러올 때 예전에 넣어둔crossorigin="anonymous" 이 속성 때문에, 브라우저가 CSS를 CORS 모드로 요청하면서 간헐적인 CORS 에러가 발생했다.그래서 나는 crossorigin="anonymous"를 제거했고, 그 뒤로 문제는 멈췄..
[실무 기록] Chrome Inspect에서 Pending authentication만 뜨고 안드로이드 디버깅이 안 될 때
·
FrontEnd/web
회사 테스트폰(안드로이드)으로 모바일 웹/웹뷰 디버깅을 하려고 chrome://inspect/#devices를 열었는데, 기기가 연결된 것처럼 보이면서도 실제로는 계속 이 메시지에서 멈췄다Pending authentication: please accept debugging session on the device. 보통은 폰 화면에 USB 디버깅(RSA) 허용 팝업이 떠야 하고, 거기서 허용을 누르면 끝난다그런데 문제는…팝업이 아예 안 뜨거나뜨더라도 허용했는데 다시 연결하면 또 Pending무엇보다 회사에서 쓰는 테스트폰들이 전부 똑같이 이러는 상황결국 “폰 설정 문제”라기보다 PC 쪽 디버깅 도구(ADB) 문제일 확률이 높다고 판단했다결론폰에서 USB 디버깅을 껐다 켜는 걸로 안 풀리면, PC의 ADB(..
TypeScript as const 이게 뭘까
·
FrontEnd/TypeScript
타입스크립트는 값을 보고 타입을 추론한다문제는, 우리가 "이 값은 고정값"이라고 생각해도 타입스크립트가 그렇게 봐주지 않을 때가 있다는 것그래서 as const가 필요해진다.1) 문제 직면 – 값은 'GET'인데 타입이 string이 된다예를 들어 메서드를 "GET" | "POST"로 제한하고 싶다고 해보자type Method = "GET" | "POST";function request(method: Method) {}그리고 요청 정보를 객체로 만들고 값을 꺼내서 넘기면,const req = { method: "GET" };request(req.method);이런 코드가 상황에 따라 타입 에러로 이어질 수 있다겉으로는 "GET"을 넘기는 것처럼 보여도, 타입스크립트가 req.method를 더 넓게(예: ..
TypeScript 유틸리티 타입 Partial<T> – 부분만 채워도 되는 타입 만들기
·
FrontEnd/TypeScript
이번에는 Partial를 정리해 본다앞에서Pick는 필요한 필드만 골라서 쓰는 타입Omit는 필요 없는 필드만 빼고 쓰는 타입이었다면,Partial는 한 줄로 이렇게 볼 수 있다."이 타입에 있는 모든 프로퍼티를 전부 optional로 바꿔 줘" 1. Partial 한 줄 정의Partial는타입 T에 있는 모든 프로퍼티를"있어도 되고, 없어도 되는" 상태로 만들어 주는 유틸리티 타입이다.type User = { id: number name: string email: string}type UserUpdate = Partial// 아래와 같은 구조로 인식된다// {// id?: number// name?: string// email?: string// } UserUpdate 타입은id만 있어..