McMaster-fast은(는) 무엇을 하나요?
다른 사이트를 mcmaster.com처럼 만듭니다: 첫 페인트를 수십 밀리초 단위로, 다음 페이지를 URL 표시줄 업데이트 전에 로드.
사용하는 기술 스택은 중요하지 않습니다. McMaster는 ASP.NET, YUI, ScriptCombiner로 이 모든 것을 해냅니다. 명령 순서와 요청 수가 중요합니다. 프레임워크 유행은 중요하지 않습니다.
그들이 실제로 하는 일
라이브 사이트(2026-09-13) 및 Wes Bos 분석(klinke.studio 노트)에서 관찰된 내용:
| 계층 | McMaster가 하는 일 | 즉각적으로 느껴지는 이유 |
|---|---|---|
| 첫 바이트 | 서버 렌더링 HTML. JS 전에 브라우저가 페인트. 웜 쉘에서 FCP ~64ms, TTFB ~19ms. | 사용자가 번들을 기다리며 스피너를 보는 대신 페이지를 봄. |
| 쉘 | #ShellLayout_Cntnr + #MainContent. 헤더/장바구니가 마운트된 상태 유지. history.pushState. | 카테고리 클릭 시 같은 헤더 노드를 유지하고 35ms 안에 콘텐츠 교체. |
| 예측 | 호버/의도가 클릭 전에 다음 HTML을 가져옴. | 클릭은 캐시 적중 + DOM 교체. |
| 재방문 | 서비스 워커가 GET 네비게이션(PDF 제외)에 대해 캐시 우선. 첫 로드 후 / 캐시 유지. | 원본 HTML은 ~200ms(mc-turn); SW가 로컬에서 제공. |
| 워터폴 | 이미지 호스트 dns-prefetch. woff2 폰트, 로고, LCP 스프라이트, 페이지 JS/CSS, ShellDynamic.aspx preload. | 브라우저가 CSS에서 발견하기 전에 폰트/LCP 로딩 시작. |
| CSS | ~32KB 공통 CSS를 <head>의 <style>에 인라인. 나머지는 페이지별 컴바이너로 처리. | 첫 레이아웃에 추가 CSS 요청 불필요. |
| JS | 페이지별 ScriptCombiner 번들(?files=…). Async. 웹파트는 페인트 후 로드. | 카탈로그 페이지가 체크아웃 코드를 다운로드하지 않음. |
| 에셋 | 버전 관리된 URL(/mv1789156784/, ?ver=). Cache-Control: public,immutable,max-age=31536000. 이미지 호스트 images1.mcmaster.com. 타일 그리드용 스프라이트. | 1년 캐시, 무효화 문제 없음, 요청 수 적음. |
| 안정성 | 예약된 박스/스프라이트. 측정된 CLS 0. | 이미지 도착 시 리플로우 없음. |
| 무게 | 자사 분석(/trk/). 광고 없음. CSP가 *.mcmaster.com으로 고정. | 페이지가 곧 제품. |
HTML 문서 자체는 Cache-Control: no-cache이고 Akamai에서 x-check-cacheable: NO입니다. "모든 HTML을 CDN에 캐시"하지 마십시오. 브라우저에서 쉘을 캐시하고, 엣지에서 불변 정적 파일을 캐시합니다.
우선순위 사다리
웜 캐시에서 페이지 LCP를 ~200ms 미만으로 만드는 첫 번째 단계에서 멈추십시오. 하나의 PR에서 Workbox, 스프라이트 파이프라인, 그리고 Speculation Rules를 모두 설치하지 마십시오.
- 브라우저가 페인트할 수 있는 HTML을 제공하십시오. SSR 또는 정적 HTML. 첫 번째 뷰를 클라이언트 전용 렌더링하지 마십시오. 첫 화면을 구성하는 JS를 없애십시오.
- 첫 페인트를 차단 해제하십시오. 접힌 부분 위의 CSS만 인라인(또는 하나의 작은 차단 시트)하십시오. LCP 이미지와 woff2 폰트(
crossorigin)를preload하십시오. 모든 이미지에width/height(또는 CSS aspect-ratio)를 지정하십시오. - 불변 정적 파일. 핑거프린트 또는 버전 쿼리.
Cache-Control: public, immutable, max-age=31536000. - 지속적 크롬 + 콘텐츠 교체. 공유 레이아웃. 다음 네비게이션이 하나의 콘텐츠 노드를 교체하고
pushState를 수행합니다. 헤더를 다시 마운트하지 마십시오. - 의도 프리페치. 호버/뷰포트에서 다음 문서를 추측합니다. 제한을 두십시오. 체크아웃, 검색 API, 또는 인증된 HTML은 절대 프리페치하지 마십시오.
- 네비게이션 SW (선택 사항). 공개 쉘/홈에 대한 GET 네비게이션을 캐시 우선 처리합니다. 배포 시 비웁니다. 영리한 SW가 아니라 페이지에서 무효화합니다. 사이트가 대부분 비공개이면 건너뜁니다.
- 페이지별 JS. 경로 분할. 분석은 유휴 시간까지 지연합니다. 제품이 아닌 타사 태그를 삭제합니다.
- 스프라이트 / 이미지 호스트는 하나의 뷰에 수십 개의 작은 아이콘이 있는 경우에만 사용합니다. 그 이하에서는 HTTP/2 + 몇 개의 압축 이미지면 충분합니다.
에이전트 워크플로우
이런 방식으로 사이트를 빠르게 만들라는 요청을 받으면:
- 실제 첫 로드 및 앱 내 네비게이션 하나를 추적합니다(네트워크 + 페인트 내용). 현재 LCP 요소와 이를 차단하는 JS를 식별합니다.
- 누락된 가장 낮은 사다리 단계를 적용합니다. 사용자가 일괄 처리를 요청하지 않는 한 패스당 한 번의 변경.
- 새 라이브러리보다 리포지토리에 이미 있는 플랫폼 기능(Next
<Link>,next/font, App Router 레이아웃)을 선호합니다. - 패스 후 하나의 확인을 남깁니다: LCP / FCP 수치, 또는 클라이언트 네비게이션에서 쉘 노드가 재사용되었는지 확인하는 작은 어설션.
- 구현 중인 단계의 정확한 레시피는 techniques.md를 읽으십시오. Next.js / 바닐라 / 기존 SPA 매핑은 recipes.md를 읽으십시오.
엄격한 규칙
- HTML이 제품입니다. JS는 선택적 개선 사항입니다.
- 프리페치는 힌트이지 크롤러가 아닙니다. 동일 출처 GET 문서만 가능합니다.
- 개인화된 HTML은
no-store이거나 짧은 TTL의 SW 전용입니다. 장바구니/계정 HTML을 공유 CDN 캐시에 절대 두지 마십시오. - 모든 에셋을 가로채는 서비스 워커를 추가하지 마십시오. McMaster의
ServiceWorkerJS.aspx와 일치하게 네비게이션 문서만 처리합니다. - YUI, 스프라이트, ASP.NET을 복사하지 마십시오. 작동 순서를 복사하십시오.
- 빠른 HTML 페이지를 클라이언트 SPA로 "현대화"하는 것을 수정책으로 사용하지 마십시오.
- 타사 스크립트(광고, 태그 관리자, 채팅)는 유죄로 간주됩니다. 첫 페인트에서 제외하거나 제거하십시오.
- 가치가 낮은 단계를 건너뛸 때는
ponytail:로 단축키를 표시하십시오.
완료 조건
- 첫 방문: HTML이 앱 번들 실행 전에 페인트됩니다. LCP는 클라이언트 렌더링 요소가 아닌 서버 전송 요소입니다.
- 다음 클릭: 크롬이 마운트된 상태로 유지되고 콘텐츠 영역만 교체됩니다.
- 홈/쉘 재방문: 로컬 또는 메모리 캐시에서 제공됩니다.
- 폰트와 LCP 이미지가 첫 1~2 왕복 내에 로드되고, CSS 이후에 발견되지 않습니다.
- 수정한 페이지에서 CLS가 0에 가깝게 유지됩니다.