[G1-Sync] Manual knowledge update

This commit is contained in:
Antigravity Agent
2026-05-10 22:08:15 +09:00
parent 21ac3ed255
commit 504fd5fb42
3011 changed files with 380280 additions and 206977 deletions
@@ -2,101 +2,188 @@
id: wiki-2026-0508-성능-및-seo-최적화-프로젝트
title: 성능 및 SEO 최적화 프로젝트
category: 10_Wiki/Topics
status: needs_review
status: verified
canonical_id: self
aliases: []
aliases: [Performance and SEO Project, Web Vitals Optimization Project]
duplicate_of: none
source_trust_level: A
confidence_score: 0.92
tags: [uncategorized]
confidence_score: 0.9
verification_status: applied
tags: [project, performance, seo, web-vitals, lighthouse]
raw_sources: []
last_reinforced: 2026-05-08
last_reinforced: 2026-05-10
github_commit: pending
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
tech_stack:
language: unspecified
framework: unspecified
language: typescript
framework: nextjs
---
# [[성능 및 SEO 최적화 프로젝트]]
# 성능 및 SEO 최적화 프로젝트
## 📌 한 줄 통찰 (The Karpathy Summary)
성능 및 SEO 최적화 프로젝트는 애플리케이션의 초기 로드 속도와 반응성을 개선하고 검색 엔진 크롤러에 대한 접근성을 높여 최적의 사용자 경험과 비즈니스 성과를 달성하기 위한 목적을 가집니다. 브라우저의 중요 렌더링 경로(CRP)를 이해하여 불필요한 Reflow와 Repaint를 최소화하며, 프로젝트의 성격에 맞게 CSR, SSR, SSG, ISR 등 적절한 웹 렌더링 전략을 선택하는 것이 중요합니다. 더불어, React 기반 애플리케이션에서는 [[Virtual DOM]]과 Fiber 아키텍처, 자동 배칭([[Automatic Batching]]), [[React Compiler]] 및 [[React Server Components]](RSC)를 활용하여 렌더링 효율성을 극대화하고 [[JavaScript]] 번들 크기를 줄이는 최적화 작업을 수행합니다.
## 한 줄
> **"매 Web Vitals + SEO 의 simultaneous improvement project"**. 매 Lighthouse 60→95+ 의 typical scope — LCP/INP/CLS 의 budget 의 set, render-blocking 의 eliminate, structured data 의 add, Core Web Vitals 의 Google ranking signal 의 secure.
## 📖 구조화된 지식 (Synthesized Content)
**브라우저 렌더링 메커니즘과 렌더링 최적화**
* **중요 렌더링 경로 ([[Critical Rendering Path]], CRP):** 브라우저가 HTML, CSS, JavaScript를 화면의 픽셀로 변환하는 과정입니다 [1, 2]. HTML을 파싱하여 DOM을 만들고 CSS를 파싱하여 [[CSSOM]]을 생성한 후, 두 개를 결합하여 화면에 보일 요소만 담은 렌더 트리([[Render Tree]])를 구성합니다 [2-4]. 이후 각 요소의 크기와 위치를 계산하는 Layout(Reflow) 단계와 화면에 실제 픽셀을 그리는 Paint(Repaint) 단계를 거칩니다 [5-8].
* **Reflow 및 Repaint 최소화:** DOM 노드의 추가/제거나 요소의 크기 및 위치(width, height, margin 등)를 변경하면 막대한 비용이 드는 Reflow가 발생합니다 [9-11]. 성능 최적화를 위해서는 불필요한 DOM 깊이를 줄이고, 레이아웃 계산을 피할 수 있도록 `position: absolute``position: fixed`를 사용하며, 애니메이션에는 Reflow를 유발하지 않는 `transform` 속성을 사용해야 합니다 [12-14].
## 매 핵심
**전략적 웹 렌더링 방식 (CSR, SSR, SSG, ISR)**
* **CSR (Client-Side Rendering):** 서버에서 빈 HTML 뼈대와 자바스크립트를 보내고 브라우저가 모든 렌더링을 처리합니다. 페이지 전환이 부드럽고 상호작용성이 뛰어나지만, 초기에 화면이 비어 있어 FCP(First Contentful Paint)가 늦고 검색 엔진 최적화(SEO)에 불리합니다 [15-19].
* **SSR (Server-Side Rendering):** 요청 시 서버에서 완전한 HTML을 렌더링하여 클라이언트에 제공합니다. 검색 엔진이 즉시 콘텐츠를 읽을 수 있어 SEO에 탁월하고 초기 화면을 빠르게 띄울 수 있습니다 [20-23]. 단, 자바스크립트가 다운로드되어 이벤트를 연결하는 하이드레이션([[Hydration]]) 단계가 완료될 때까지 상호작용(TTI, Time to Interactive)이 지연될 수 있습니다 [20, 24-26].
* **SSG (Static Site Generation) 및 ISR (Incremental Static Regeneration):** SSG는 빌드 타임에 HTML을 생성하여 CDN으로 배포하므로 로딩 속도와 SEO 측면에서 최상의 성능을 냅니다 [27-29]. ISR은 SSG의 성능을 유지하면서도 설정된 주기마다 백그라운드에서 페이지를 업데이트하여 최신 콘텐츠를 제공하는 하이브리드 방식입니다 [27, 30-32].
### 매 project goals (KPI)
- **LCP** ≤ 2.5s (good).
- **INP** ≤ 200ms (replaces FID, 2024+).
- **CLS** ≤ 0.1.
- **Lighthouse Performance** ≥ 90.
- **organic traffic** +30% (post 1Q).
- **conversion** +10%.
**React 아키텍처를 통한 렌더링 최적화 전략**
* **Virtual DOM과 [[Reconciliation]]:** React는 메모리상에 가상의 DOM을 유지하고, 상태 변경 시 O(n) 복잡도를 갖는 휴리스틱 Diffing 알고리즘을 통해 이전 트리와 변경된 트리를 비교하여 실제 DOM에는 변경된 부분만 최소한으로 업데이트합니다 [33-36].
* **Fiber 아키텍처와 동시성 렌더링 ([[Concurrent Rendering]]):** React 16부터 도입된 Fiber는 렌더링 작업을 중단하고 재개할 수 있는 작은 '작업 단위'로 나눕니다 [37-39]. 사용자 입력과 같은 긴급한 작업을 우선 처리하는 우선순위 라인(Priority Lanes)과 [[Time Slicing]] 기술을 활용하여 무거운 연산 중에도 UI가 멈추지 않고 반응성을 유지하도록 돕습니다 [38, 40-43].
* **자동 배칭과 React Compiler:** [[React 18]]의 자동 배칭(Automatic [[Batching]])은 여러 번의 상태 업데이트를 묶어 한 번의 리렌더링만 발생하도록 하여 불필요한 렌더링을 줄입니다 [44-47]. 나아가 [[React 19]]의 React Compiler는 빌드 타임에 코드를 분석해 `useMemo``useCallback`과 같은 수동 처리 없이도 자동으로 최적화된 메모이제이션을 삽입하여 개발자의 인지적 부담과 성능 이슈를 동시에 해결합니다 [48-51].
* **[[React [[Server Components]] (RSC)]]:** RSC는 클라이언트로 다운로드되는 자바스크립트 번들에 포함되지 않고 전적으로 서버에서 실행됩니다 [52, 53]. 하이드레이션 과정을 생략할 수 있어 클라이언트가 부담해야 할 번들 크기를 제로(Zero)에 가깝게 만들며, 서버에 직접 접근해 효율적으로 데이터를 패칭할 수 있어 초기 로드와 상호작용 속도를 모두 개선합니다 [53-57].
### 매 phase plan
1. **Audit** (week 1): Lighthouse + WebPageTest + RUM (CrUX) baseline.
2. **Quick wins** (week 2-3): image lazy + dimensions, font-display, defer JS.
3. **Architecture** (week 4-6): RSC migration, route-split, edge caching.
4. **SEO** (week 4-6): meta + OG + JSON-LD + sitemap + canonical.
5. **Monitoring** (ongoing): Vercel Speed Insights / SpeedCurve / Sentry.
## 🔗 지식 연결 (Graph)
- **Related Topics:** [[Critical Rendering Path]], [[Reflow와 Repaint]], [[Server-Side Rendering (SSR)]], [[Virtual DOM과 Reconciliation]], [[React Server Components (RSC)]]
- **Projects/Contexts:** [[대규모 콘텐츠 기반 애플리케이션 및 전자상거래 플랫폼 구축]], [[프론트엔드 성능 최적화 및 SEO 개선 프로젝트]]
- **Contradictions/Notes:** 클라이언트 사이드 렌더링(CSR)은 로드 후 동적 상호작용에는 강점이 있으나 초기 FCP 저하 및 SEO 크롤링 측면에서 불리합니다. 반대로 서버 사이드 렌더링(SSR)은 뛰어난 SEO 및 초기 화면 노출을 보장하지만, 하이드레이션(Hydration) 병목으로 인해 TTI(Time to Interactive)가 지연되어 사용자가 버튼을 클릭해도 즉시 반응하지 않는 현상이 발생할 수 있다는 렌더링 방식 간의 명확한 트레이드오프가 존재합니다 [15, 20, 25, 58, 59].
### 매 SEO checklist
- `<title>` (50-60 chars), `<meta description>` (150-160).
- Open Graph + Twitter Card.
- JSON-LD (Article / Product / Breadcrumb).
- canonical, hreflang, robots.
- sitemap.xml + robots.txt.
- semantic HTML (h1 unique, landmark).
- internal link graph.
---
*Last updated: 2026-04-25*
## 💻 패턴
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
**언제 이 지식을 쓰는가:**
- *(TODO)*
**언제 쓰면 안 되는가:**
- *(TODO)*
## 🧪 검증 상태 (Validation)
- **정보 상태:** needs_review
- **출처 신뢰도:** A
- **검토 이유:** *(P-Reinforce Phase 1 자동 정규화. 본문 검증 필요.)*
## 🧬 중복 검사 (Duplicate Check)
- **기존 유사 문서:** *(TODO: 인덱서 클러스터 리포트 참조)*
- **처리 방식:** UPDATE (자동 정규화)
- **처리 이유:** Phase 1 정규화 — 옛 템플릿/누락 필드 보강.
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
- **과거 데이터와의 충돌:** 없음
- **정책 변화:** 없음
## 🕓 변경 이력 (Changelog)
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|------|-----------|-----------|--------|
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
## 💻 코드 패턴 (Code Patterns)
**패턴 1:** *(TODO: 이 프로젝트 컨벤션 반영한 구조 스켈레톤)*
```text
# TODO
### Performance budget (CI)
```js
// lighthouserc.js
module.exports = {
ci: {
collect: { url: ['https://staging.example.com/'], numberOfRuns: 3 },
assert: {
assertions: {
'categories:performance': ['error', { minScore: 0.9 }],
'largest-contentful-paint': ['error', { maxNumericValue: 2500 }],
'cumulative-layout-shift': ['error', { maxNumericValue: 0.1 }],
'interaction-to-next-paint': ['error', { maxNumericValue: 200 }],
},
},
upload: { target: 'temporary-public-storage' },
},
};
```
## 🤔 의사결정 기준 (Decision Criteria)
### Next.js metadata (App Router)
```tsx
// app/blog/[slug]/page.tsx
export async function generateMetadata({ params }): Promise<Metadata> {
const post = await getPost(params.slug);
return {
title: `${post.title} | MySite`,
description: post.excerpt,
alternates: { canonical: `https://mysite.com/blog/${post.slug}` },
openGraph: {
title: post.title,
description: post.excerpt,
images: [{ url: post.cover, width: 1200, height: 630 }],
type: 'article',
},
twitter: { card: 'summary_large_image' },
};
}
```
**선택 A를 써야 할 때:**
- *(TODO)*
### JSON-LD structured data
```tsx
function ArticleJsonLd({ post }: { post: Post }) {
const ld = {
'@context': 'https://schema.org',
'@type': 'Article',
headline: post.title,
image: [post.cover],
datePublished: post.publishedAt,
author: [{ '@type': 'Person', name: post.author }],
};
return <script type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(ld) }} />;
}
```
**선택 B를 써야 할 때:**
- *(TODO)*
### Image optimization
```tsx
import Image from 'next/image';
<Image src="/hero.jpg" alt="hero" width={1200} height={630}
priority sizes="(max-width: 768px) 100vw, 1200px"
placeholder="blur" blurDataURL={post.lqip} />
```
**기본값:**
> *(TODO)*
### Font optimization (Next.js)
```tsx
import { Inter } from 'next/font/google';
const inter = Inter({ subsets: ['latin'], display: 'swap', preload: true });
export default function Layout({ children }) {
return <html className={inter.className}>{children}</html>;
}
```
## ❌ 안티패턴 (Anti-Patterns)
### Web Vitals reporting
```tsx
// app/web-vitals.tsx
'use client';
import { useReportWebVitals } from 'next/web-vitals';
export function WebVitals() {
useReportWebVitals((m) => {
fetch('/api/vitals', { method: 'POST', body: JSON.stringify(m), keepalive: true });
});
return null;
}
```
- **[안티패턴]:** *(TODO: 무엇을 하면 안 되는가 + 이유 + 대신 무엇을)*
### Sitemap (Next.js 15)
```tsx
// app/sitemap.ts
export default async function sitemap() {
const posts = await getAllPosts();
return posts.map(p => ({
url: `https://mysite.com/blog/${p.slug}`,
lastModified: p.updatedAt,
changeFrequency: 'weekly',
priority: 0.7,
}));
}
```
## 매 결정 기준
| 문제 | Action |
|---|---|
| LCP 느림 | hero image preload + `priority` + RSC streaming |
| INP 느림 | hydration 의 reduce (RSC), long task 의 break |
| CLS 발생 | image/font dimensions, ad slot reserve |
| 매 SSR 필요 | Next.js App Router (RSC) |
| 매 SEO 우선 | static generation (`generateStaticParams`) |
| 매 대량 page | ISR (`revalidate`) |
**기본값**: 매 Next.js 15 (App Router) + Image/Font 의 use, Lighthouse CI 의 budget enforce, JSON-LD 의 add.
## 🔗 Graph
- 부모: [[브라우저 렌더링 파이프라인(Critical Rendering Path)]] · [[SEO 기초]]
- 변형: [[Web Vitals]] · [[Lighthouse CI]]
- 응용: [[Next.js App Router]] · [[Edge Caching]]
- Adjacent: [[Schema.org]] · [[Open Graph]]
## 🤖 LLM 활용
**언제**: Lighthouse report 의 prioritize, regression 의 diagnose, meta tag 의 generate.
**언제 X**: real RUM data analysis (BigQuery/CrUX 의 use).
## ❌ 안티패턴
- **Lighthouse 만 의 measure**: 매 lab data — 매 RUM (CrUX) 의 substitute.
- **`priority` 의 모든 image**: 매 LCP 의 confused — 매 hero 만.
- **Empty meta description**: 매 SERP 의 random snippet.
- **Duplicate H1**: 매 SEO penalty — 매 unique 의 keep.
## 🧪 검증 / 중복
- Verified (web.dev/learn/performance, Next.js 15 docs, Google Search Central, Lighthouse CI docs).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Web Vitals + Next.js metadata + Lighthouse CI 의 정리 |