앱 안에 WebView를 새로 붙였다. 앱 내에서 웹이 버벅이면 사용성이 매우 안 좋을 것이라 생각이 들었다!
“지금 웹이 잘 최적화돼 있나?”를 숫자로 확인해보려고 Web Vitals를 넣어 봄.
결과를 보고, 다음 단계에서 무엇을 고칠지 정리하는 게 목표.
브라우저에서 화면 속도 지표를 모아 서버로 보내도록 만듦.
서버는 Next App Router의 API 라우트로 간단히 받음.
아래 같이 만들어서 넣어주었음.
// src/providers/WebVitalsReporter.tsx
'use client';
import { useEffect } from 'react';
import axios from 'axios';
import { onCLS, onFCP, onINP, onLCP, onTTFB } from 'web-vitals';
const sent = new Set<string>();
function send(metric: any) {
const id = `${metric.name}-${metric.id}`;
if (sent.has(id)) return;
sent.add(id);
const payload = { ...metric, path: location.pathname, ts: Date.now() };
const ok = navigator.sendBeacon?.('/api/vitals', JSON.stringify(payload));
if (!ok) void axios.post('/api/vitals', payload, { headers: { 'content-type': 'application/json' } });
}
export default function WebVitalsReporter() {
useEffect(() => {
onTTFB(send);
onFCP(send);
onLCP(send, { reportAllChanges: false });
onCLS(send, { reportAllChanges: false });
onINP(send, { reportAllChanges: false });
}, []);
return null;
}
// src/app/api/vitals/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function POST(req: NextRequest) {
const metric = await req.json();
console.log('[WEB-VITALS]', metric); // 나중에 대시보드로 보내면 됨
return NextResponse.json({ ok: true });
}
// src/app/providers.tsx (발췌)
'use client';
import WebVitalsReporter from '@/providers/WebVitalsReporter';
export default function Providers({ children }: { children: React.ReactNode }) {
return (
<>
{children}
<WebVitalsReporter />
</>
);
}
• 같은 도메인이라 CORS 설정 불필요
• 브라우저에서 비밀키 노출 없이 서버에서만 외부 분석 툴로 전송 가능
• 별도 서버 없이 프로젝트 안에서 끝낼 수 있어 관리가 편함
• WebView에서도 추가 화이트리스트 없이 동작
어떤걸 하게 될 지 알 수 없지만 아래 같은 항목들을 살피고자 한다.