Skip to content

[PERF] 성능 리포트 측정 오류 및 LCP 이미지 최적화 수정#126

Merged
kimminna merged 7 commits into
developfrom
perf/web/125-fix-performance-report
Jul 10, 2026
Merged

[PERF] 성능 리포트 측정 오류 및 LCP 이미지 최적화 수정#126
kimminna merged 7 commits into
developfrom
perf/web/125-fix-performance-report

Conversation

@kimminna

@kimminna kimminna commented Jul 8, 2026

Copy link
Copy Markdown
Member

ISSUE 🔗

close #125



What is this PR? 🔍

PR 성능 리포트 코멘트에서 Lighthouse가 항상 측정 실패로 표시되고 번들 크기가 모든 라우트에서 동일하게 나오던 문제를 수정했습니다. 함께 발견한 네비게이션 로고의 LCP 경고도 같이 처리했습니다.

배경

  • 기존 구조: lighthouserc.cjs는 로케일 프리픽스 없는 URL(/home 등)을 그대로 사용했고, 번들 분석 스크립트는 webpack 빌드 산출물(app-build-manifest.json, static/chunks/app/<route>/) 구조를 전제로 작성돼 있었습니다.
  • 발생 문제: next-intllocalePrefix: "always"로 모든 경로를 /en, /ko로 리다이렉트하면서 Lighthouse가 리다이렉트 중 NO_FCP로 9개 URL 전부 측정 실패했고, Next.js 16의 기본 번들러인 Turbopack은 webpack 전용 매니페스트를 생성하지 않아 번들 분석 스크립트가 모든 라우트를 공유 번들 크기로만 표시했습니다.
  • 해결 방향: Lighthouse URL에 로케일 프리픽스를 직접 포함시키고, 번들 분석 스크립트를 Turbopack이 실제로 생성하는 매니페스트 구조에 맞게 재작성했습니다.

네비게이션 로고 LCP

  • 변경 요약: NavigationSidebar.tsx의 로고 Imagepriority를 추가했습니다.
  • 이유: 브라우저가 이 이미지를 LCP 요소로 감지했는데, next/image의 기본 lazy loading으로 인해 로딩이 지연된다는 경고가 발생했습니다.
  • 구현 방식: 사이드바 상단에 항상 노출되는 로고이므로 priority를 적용해 eager loading + fetchpriority="high" + preload 힌트가 자동 적용되도록 했습니다.

Lighthouse 측정 URL

  • 변경 요약: lighthouserc.cjscollect.url 목록을 전부 /en 프리픽스 포함 경로로 변경하고, 존재하지 않던 /settings/term을 실제 라우트 /settings/policy로 수정했습니다.
  • 이유: 실제 CI 로그를 확인한 결과 requestedUrl: "http://localhost:3000/", finalDisplayedUrl: "http://localhost:3000/en"으로 리다이렉트가 발생하는 과정에서 Chrome이 NO_FCP(콘텐츠를 전혀 페인트하지 못함) 에러를 내며 9개 URL 전부 실패하고 있었습니다.
  • 구현 방식: 리다이렉트를 거치지 않도록 URL에 로케일을 직접 명시했습니다. ko는 의도적으로 제외했는데, JS 번들이 로케일과 무관하게 동일해 성능 점수 자체는 사실상 같고, 추가하면 numberOfRuns: 3과 곱해져 CI 시간이 2배로 늘어나기 때문입니다.

번들 크기 분석 스크립트

  • 변경 요약: .github/scripts/performance-report.jsanalyzeBundle()을 Turbopack 산출물 구조에 맞게 재작성했습니다.
  • 이유: 로컬에서 pnpm turbo run build --filter=timo-web으로 실제 프로덕션 빌드를 돌려 확인한 결과, Turbopack은 app-build-manifest.jsonstatic/chunks/app/ 디렉터리도 생성하지 않아 기존 스크립트가 모든 라우트를 pageBytes = 0, firstLoad = sharedBytes로만 계산하고 있었습니다.
  • 구현 방식: 대신 server/app-paths-manifest.json으로 라우트 → 파일 경로를 매핑하고, 각 라우트의 page_client-reference-manifest.js(Turbopack이 생성하는 RSC 클라이언트 레퍼런스 매니페스트)에서 entryJSFiles["[project]/apps/timo-web/app<라우트키>"]를 읽어 해당 페이지가 실제로 필요로 하는 청크 목록을 가져옵니다. 이 목록은 페이지 자신의 청크와 상위 레이아웃 청크가 이미 누적되어 있어, 공유 루트 청크(rootMainFiles)와 겹치는 파일만 제외하면 정확한 페이지별 First Load JS가 나옵니다. 로컬 빌드로 검증한 결과 /[locale]/home은 53.81kB, 클라이언트 컴포넌트가 없는 /[locale]/settings는 0B로 라우트마다 다르게 측정되는 것을 확인했습니다.
  • 경계 · 제약: page_client-reference-manifest.jsglobalThis.__RSC_MANIFEST[...] = {...} 형태의 JS 파일이라 JSON이 아니며, 내부 포맷은 Next.js가 공식 문서화하지 않은 빌드 산출물입니다. 정규식으로 마지막 "] = {...}; 블록을 추출해 파싱하므로, 향후 Next.js 버전에서 이 산출물 구조가 바뀌면 다시 깨질 수 있습니다.



To Reviewers

번들 분석 스크립트가 Next.js의 비공식 내부 빌드 산출물(page_client-reference-manifest.js)에 의존하는 구조라, Next.js 버전을 올릴 때 이 부분이 깨지지 않는지 한번 확인해 주세요.
Lighthouse는 en만 측정하고 ko는 의도적으로 제외했는데, 이 판단이 맞는지도 봐주시면 좋겠습니다.



Screenshot 📷



Test Checklist ✔

  • pnpm --filter timo-web check-types 통과
  • pnpm --filter timo-web lint 통과
  • pnpm turbo run build --filter=timo-web로 실제 프로덕션 빌드 후 번들 분석 로직을 로컬에서 재현·검증 (라우트별 크기가 서로 다르게 나옴을 확인)
  • CI에서 Lighthouse가 실제로 9개 URL 모두 정상 측정되는지 확인 — 미실행: 이번 PR 병합 후 CI 워크플로우 실행 결과로 확인 예정
  • 브라우저에서 로고 이미지 LCP 개선 여부 시각 확인 — 미실행: 코드 변경만 확인, 실제 렌더링 검증은 하지 않음

kimminna added 3 commits July 9, 2026 00:31
- LCP로 감지된 로고 이미지에 priority를 적용해 지연 로딩 경고를 해결했습니다
- localePrefix: always 설정에 맞춰 URL에 /en 프리픽스를 추가해 리다이렉트로 인한 측정 실패(NO_FCP)를 해결했습니다
- 존재하지 않는 /settings/term 경로를 실제 라우트 /settings/policy로 수정했습니다
- Turbopack이 더 이상 생성하지 않는 webpack 전용 매니페스트(app-build-manifest.json) 대신 app-paths-manifest.json과 라우트별 page_client-reference-manifest.js를 파싱하도록 변경했습니다
- 모든 라우트가 공유 번들 크기로만 표시되던 문제를 해결했습니다
@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
timo Ready Ready Preview, Comment Jul 10, 2026 3:56pm

@github-actions github-actions Bot added the ⏰ Timo-web Timo 웹 서비스 label Jul 8, 2026
@github-actions github-actions Bot requested review from ehye1 and jjangminii July 8, 2026 15:35
@github-actions github-actions Bot added ✨ Feature 새로운 기능(기능성) 구현 ♦️ 민아 민아상 labels Jul 8, 2026
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kimminna, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 48 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8365e5c1-a728-4593-a3fc-25f892ab7338

📥 Commits

Reviewing files that changed from the base of the PR and between 1eac69b and 1ed63af.

📒 Files selected for processing (3)
  • .github/scripts/performance-report.js
  • .github/workflows/performance.yml
  • apps/timo-web/lighthouserc.cjs

Walkthrough

Next.js Turbopack 산출물 구조에 맞춰 performance-report.js의 번들 크기 분석 로직을 client-reference-manifest 파싱 방식으로 재작성했습니다. 네비게이션 로고 이미지 props를 분리 표기하고, lighthouserc.cjs의 측정 URL을 en 로케일 프리픽스 경로로 갱신했습니다.

Changes

성능 리포트 및 LCP 최적화

Layer / File(s) Summary
번들 크기 분석 로직 재작성
.github/scripts/performance-report.js
routes-manifest.json/app-build-manifest.json/디렉터리 순회 기반 방식을 제거하고, app-paths-manifest.json과 라우트별 *_client-reference-manifest.js를 파싱해 entryJSFiles 기반으로 pageFiles gzip 합과 firstLoad를 계산하도록 변경했습니다. stripRouteGroups로 route group 세그먼트를 제거합니다.
LCP 및 Lighthouse 측정 경로 수정
apps/timo-web/components/layout/sidebar/navigation/NavigationSidebar.tsx, apps/timo-web/lighthouserc.cjs
로고 Imagesrc/alt/width/height/priority props를 다중 라인으로 분리 표기하고, ci.collect.url을 기존 루트/비-EN 경로에서 en 로케일 프리픽스 경로 목록으로 교체했습니다.

Estimated code review effort: 2 (Simple) | ~12 minutes

Possibly related PRs

  • Team-Timo/Timo-client#16: 동일하게 performance-report.js에서 빌드 매니페스트 기반 라우트별 gzip/First Load JS 계산 로직을 다룹니다.
  • Team-Timo/Timo-client#31: performance-report.js의 번들 크기 파싱 로직과 lighthouserc.cjs의 측정 URL을 함께 조정한 이전 통합 리포팅 워크플로우 변경입니다.
  • Team-Timo/Timo-client#32: lighthouserc.cjsci.collect.url 설정을 동일하게 수정한 변경입니다.

Suggested labels: 😎 DevOps

Suggested reviewers: ehye1, yumin-kim2, jjangminii

로고 props를 줄줄이 나열한 정성이 눈에 띄네요 — 가독성 점수 +1점입니다! 📸

참고로 next/image의 priority 속성 관련 공식 문서는 다음과 같습니다: https://nextjs.org/docs/app/api-reference/components/image#priority

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed 제목이 성능 리포트 측정 오류와 LCP 이미지 최적화라는 핵심 변경을 정확히 요약합니다.
Description check ✅ Passed 설명이 변경 내용과 문제 원인을 잘 맞추고 있어 PR 내용과 일치합니다.
Linked Issues check ✅ Passed 링크된 이슈의 4개 요구사항이 모두 반영되었습니다: 로고 priority, 로케일 URL, 정책 경로 수정, Turbopack 번들 분석 재작성.
Out of Scope Changes check ✅ Passed 요구사항과 무관한 변경은 보이지 않으며, 보이는 수정은 모두 성능 리포트/LCP 개선 범위 안입니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/web/125-fix-performance-report

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

Timo Performance Report

Bundle Size — timo-web
라우트 크기 First Load JS
/[locale]/home 71.08 kB 🟡 276.87 kB
/[locale]/today 52.14 kB 🟡 257.93 kB
/[locale]/focus 51.29 kB 🟡 257.08 kB
/[locale]/settings/account 0 B 🟡 205.79 kB
/[locale]/settings 0 B 🟡 205.79 kB
/[locale]/settings/policy 0 B 🟡 205.79 kB
/[locale]/statistics 49.24 kB 🟡 255.03 kB
/[locale]/onboarding 0 B 🟡 205.79 kB
/[locale] 0 B 🟡 205.79 kB

공유 번들: 205.79 kB
🟢 < 200kB  |  🟡 < 350kB  |  🔴 ≥ 350kB (First Load JS · gzip)

Lighthouse — timo-web
URL Perf A11y LCP CLS TBT
/en/home 🔴 69 🟢 96 🔴 13.4s 🟢 0.000 🟡 297ms
/en/today 🟡 74 🟢 96 🔴 13.4s 🟢 0.000 🟢 125ms
/en/focus 🟡 74 🟡 91 🔴 13.3s 🟢 0.000 🟢 116ms
/en/statistics 🟡 74 🟢 95 🔴 13.1s 🟢 0.000 🟢 135ms

Perf ≥ 70 / A11y ≥ 85 목표
LCP 🟢 < 2.5s 🟡 < 4s 🔴 ≥ 4s  |  CLS 🟢 < 0.1 🟡 < 0.25 🔴 ≥ 0.25  |  TBT 🟢 < 200ms 🟡 < 600ms 🔴 ≥ 600ms

Image Optimization — timo-web

public/ 디렉토리에 이미지가 없습니다.

측정 커밋: d6dcc75

kimminna added 2 commits July 9, 2026 00:45
- /en 루트 페이지가 빈 프래그먼트만 반환해 콘텐츠가 전혀 없어 NO_FCP로 항상 실패하던 URL을 측정 목록에서 제외했습니다
- pull_request 트리거에 synchronize를 추가해 새 커밋 push 시에도 워크플로우가 재실행되고 기존 코멘트가 업데이트되도록 했습니다

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/scripts/performance-report.js:
- Around line 35-44: The greedy regex in extractClientReferenceManifest can
capture too much when the manifest contains multiple assignments, causing
JSON.parse to fail and silently return null. Replace the regex-based extraction
with a more robust approach in extractClientReferenceManifest, such as locating
the target assignment using lastIndexOf and slicing only the intended JSON
object before parsing. Keep the null fallback for missing files or parse errors,
but ensure the captured substring is limited to the actual manifest payload.
- Around line 56-75: The bundle analysis in analyzeBundle currently assumes the
current Turbopack manifest shape for build-manifest.json and
app-paths-manifest.json, so add a lightweight CI schema check for those build
artifacts before performance-report.js relies on rootMainFiles, entryJSFiles,
and the app-paths entries. Update the performance-report pipeline around
analyzeBundle/extractClientReferenceManifest to validate the expected manifest
keys and fail fast or warn clearly when the structure changes, so silent
near-zero size calculations do not slip through.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: af036656-3ec4-4f9f-9cfa-9a0f252bc8b8

📥 Commits

Reviewing files that changed from the base of the PR and between 47e91db and 1eac69b.

📒 Files selected for processing (3)
  • .github/scripts/performance-report.js
  • apps/timo-web/components/layout/sidebar/navigation/NavigationSidebar.tsx
  • apps/timo-web/lighthouserc.cjs

Comment on lines +35 to 44
const extractClientReferenceManifest = (jsFilePath) => {
if (!jsFilePath || !fs.existsSync(jsFilePath)) return null;
try {
const content = fs.readFileSync(jsFilePath, 'utf8');
const match = content.match(/"\]\s*=\s*(\{[\s\S]*\});\s*$/);
return match ? JSON.parse(match[1]) : null;
} catch {
return null;
}
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

정규식 파싱의 안정성 개선을 권장합니다

extractClientReferenceManifest의 정규식 "\]\s*=\s*(\{[\s\S]*\});\s*$에서 [\s\S]*가 greedy하게 동작합니다. 매니페스트 파일에 여러 할당문이 존재할 경우, 첫 번째 {부터 마지막 }까지 모두 캡처하여 중간 할당문 내용이 포함되고 JSON.parse가 실패합니다. 실패 시 null이 반환되어 해당 라우트의 크기가 0바이트로 보고되는 침묵 오류가 발생합니다.

lastIndexOf를 활용한 방식이 더 견고합니다.

♻️ 제안하는 리팩터
 const extractClientReferenceManifest = (jsFilePath) => {
   if (!jsFilePath || !fs.existsSync(jsFilePath)) return null;
   try {
     const content = fs.readFileSync(jsFilePath, 'utf8');
-    const match = content.match(/"\]\s*=\s*(\{[\s\S]*\});\s*$/);
-    return match ? JSON.parse(match[1]) : null;
+    const lastAssign = content.lastIndexOf('"]');
+    if (lastAssign === -1) return null;
+    const jsonStart = content.indexOf('{', lastAssign);
+    const jsonEnd = content.lastIndexOf('}');
+    if (jsonStart === -1 || jsonEnd === -1 || jsonStart > jsonEnd) return null;
+    return JSON.parse(content.slice(jsonStart, jsonEnd + 1));
   } catch {
     return null;
   }
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const extractClientReferenceManifest = (jsFilePath) => {
if (!jsFilePath || !fs.existsSync(jsFilePath)) return null;
try {
const content = fs.readFileSync(jsFilePath, 'utf8');
const match = content.match(/"\]\s*=\s*(\{[\s\S]*\});\s*$/);
return match ? JSON.parse(match[1]) : null;
} catch {
return null;
}
};
const extractClientReferenceManifest = (jsFilePath) => {
if (!jsFilePath || !fs.existsSync(jsFilePath)) return null;
try {
const content = fs.readFileSync(jsFilePath, 'utf8');
const lastAssign = content.lastIndexOf('"]');
if (lastAssign === -1) return null;
const jsonStart = content.indexOf('{', lastAssign);
const jsonEnd = content.lastIndexOf('}');
if (jsonStart === -1 || jsonEnd === -1 || jsonStart > jsonEnd) return null;
return JSON.parse(content.slice(jsonStart, jsonEnd + 1));
} catch {
return null;
}
};
🧰 Tools
🪛 ast-grep (0.44.1)

[warning] 37-37: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFileSync(jsFilePath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/scripts/performance-report.js around lines 35 - 44, The greedy regex
in extractClientReferenceManifest can capture too much when the manifest
contains multiple assignments, causing JSON.parse to fail and silently return
null. Replace the regex-based extraction with a more robust approach in
extractClientReferenceManifest, such as locating the target assignment using
lastIndexOf and slicing only the intended JSON object before parsing. Keep the
null fallback for missing files or parse errors, but ensure the captured
substring is limited to the actual manifest payload.

Comment thread .github/scripts/performance-report.js
- onboarding, settings, settings/account, settings/policy가 전부 빈 프래그먼트만 반환하는 placeholder 페이지임을 확인해 측정 목록에서 제외했습니다
- 실제 콘텐츠가 있는 home/today/focus/statistics만 남겼습니다

@jjangminii jjangminii left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어느 순간부터 Lighthouse가 아예 동작하지 않고 있었는데 원인 찾아주셔서 감사해요 😊
ko locale 제외 판단도 적절한 것 같아요! JS 번들이 로케일과 무관하게 동일하니 굳이 두 번 측정할 필요는 없을 것 같아요. 간단한 코멘트 남겨뒀으니 확인 부탁드려요~

Comment thread .github/scripts/performance-report.js Outdated
const appPathsManifest = readJson(path.join(BUILD_DIR, 'server', 'app-paths-manifest.json'));
if (!buildManifest || !appPathsManifest) return null;

const sharedFiles = new Set(buildManifest.rootMainFiles ?? []);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR 설명에도 적어주셨듯이 page_client-reference-manifest.js는 Next.js 비공식 내부 산출물이라, rootMainFiles나 entryJSFiles 키가 바뀌면 번들 크기가 조용히 0으로 계산돼요. CI에서 명시적으로 감지할 수 있도록 최소한의 검증을 추가하는 게 어떨까요?

const analyzeBundle = () => {
  const buildManifest = readJson(...);
  if (!Array.isArray(buildManifest?.rootMainFiles)) {
    console.warn('[bundle] rootMainFiles 없음 ');
    return null;
  }
  // ...
};

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네 그게 좋을 것 같네요! 반영했습니다

Comment on lines +12 to +15
"http://localhost:3000/en/home",
"http://localhost:3000/en/today",
"http://localhost:3000/en/focus",
"http://localhost:3000/en/statistics",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR 설명에 존재하지 않던 /settings/term을 실제 라우트 /settings/policy로 수정했습니다" 라고 적어주셨는데 해당 페이지가 아직 머지되지않아 의도적으로 뺴두신게 맞을까요?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

옙`~~ 페이지 내부에 아무 콘텐츠가 없으면 CI가 실패하는 문제가 있어서, 퍼블리싱 시작되는 대로 추가해야 할 것 같아요.

@ehye1 ehye1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lighthouse 실패 이유가 리다이렉트 때문이었군요!! 원인 파악해서 수정해주신 덕분에 이제 CI에서도 성능 리포트를 확인할 수 있겠다 ~~ 수고하셨습니다👀⭐

- rootMainFiles가 배열이 아니면 경고를 남기고 리포트 생성을 중단했습니다
- 라우트별 entryJSFiles를 찾지 못하면 경고를 남기도록 했습니다
@kimminna kimminna merged commit 2a79174 into develop Jul 10, 2026
9 checks passed
@kimminna kimminna deleted the perf/web/125-fix-performance-report branch July 10, 2026 16:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 새로운 기능(기능성) 구현 ⏰ Timo-web Timo 웹 서비스 ♦️ 민아 민아상

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[PERF] 성능 리포트 측정 오류 및 LCP 이미지 최적화 수정

3 participants