ํ๋ฐํธ์๋ ์ฑ๋ฅ ๋ฉํธ๋ฆญ ์ง๊ณ ๋ฐ ํต๊ณ ์์ง์ ์ํด Performance Observer API๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ์น์ฌ์ดํธ ์๋์ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ์ธ์.
ํ๋ฐํธ์๋ Performance Observer ๋ฉํธ๋ฆญ ์ง๊ณ: ํต๊ณ ์์ง ๋ง์คํฐํ๊ธฐ
์ค๋๋ ์ ์น ๊ฐ๋ฐ ํ๊ฒฝ์์ ๋ถ๋๋ฝ๊ณ ๋ฐ์์ด ๋น ๋ฅธ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ๋ ๊ฒ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ๋๋ฆฌ๊ฑฐ๋ ์ง์ฐ๋๋ ์น์ฌ์ดํธ๋ ์ฌ์ฉ์์ ๋ถ๋ง์ ์ฌ๊ณ , ์ดํ๋ฅ ์ ๋์ด๋ฉฐ, ๊ถ๊ทน์ ์ผ๋ก๋ ๋น์ฆ๋์ค ์์ค๋ก ์ด์ด์ง ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ํ๋ฐํธ์๋ ์ฑ๋ฅ์ ๋ชจ๋ํฐ๋งํ๊ณ ์ต์ ํํ๋ ๊ฒ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. Performance Observer API๋ ์ฑ๋ฅ ๋ฉํธ๋ฆญ์ ์์งํ๊ณ ์ง๊ณํ๋ ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํ์ฌ ๊ฐ๋ฐ์๊ฐ ๋ณ๋ชฉ ํ์์ ์๋ณํ๊ณ ์ ๋ฐ์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ ์ ์๋๋ก ํฉ๋๋ค.
Performance Observer API๋ ๋ฌด์์ธ๊ฐ?
Performance Observer API๋ ๋ธ๋ผ์ฐ์ ์์ ๋ฐ์ํ๋ ์ฑ๋ฅ ๊ด๋ จ ์ด๋ฒคํธ๋ฅผ ๊ตฌ๋ ํ ์ ์๊ฒ ํด์ฃผ๋ ์ต์ ์๋ฐ์คํฌ๋ฆฝํธ API์ ๋๋ค. ์ฑ๋ฅ ๋ฐ์ดํฐ๋ฅผ ์ง์์ ์ผ๋ก ํด๋งํ๋ ๋์ , ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋ ์๋์ ์ผ๋ก ๊ด์ฐฐํ ์ ์์ต๋๋ค. ์ด๋ฌํ ์ด๋ฒคํธ ๊ธฐ๋ฐ ์ ๊ทผ ๋ฐฉ์์ ๊ธฐ์กด์ ํด๋ง ๋ฐฉ์๋ณด๋ค ๋ ํจ์จ์ ์ด๊ณ ๋ ๋ฐฉํด์ ์ ๋๋ค.
Performance Observer API ์ฌ์ฉ์ ์ฃผ์ ์ด์ :
- ์ค์๊ฐ ๋ชจ๋ํฐ๋ง: ์ฑ๋ฅ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋ ๊ด์ฐฐํฉ๋๋ค.
- ๋น๋๊ธฐ ์์ : ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ์ง ์์ ๋ถ๋๋ฌ์ด ์ฌ์ฉ์ ๊ฒฝํ์ ๋ณด์ฅํฉ๋๋ค.
- ์ ์ฐํ ๊ตฌ์ฑ: ๊ด์ฐฐํ ์ฑ๋ฅ ํญ๋ชฉ ์ ํ์ ์ฌ์ฉ์ ์ ์ํ ์ ์์ต๋๋ค.
- ํ์คํ๋ API: ์ฌ๋ฌ ๋ธ๋ผ์ฐ์ ์์ ์ผ๊ด๋ ๋์์ ๋ณด์ ๋๋ค.
์ฑ๋ฅ ํญ๋ชฉ ์ ํ ์ดํดํ๊ธฐ
Performance Observer API๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค์ํ ์ ํ์ ์ฑ๋ฅ ํญ๋ชฉ์ ๊ด์ฐฐํ ์ ์์ผ๋ฉฐ, ๊ฐ ํญ๋ชฉ์ ํ๋ฐํธ์๋ ์ฑ๋ฅ์ ์ฌ๋ฌ ์ธก๋ฉด์ ๋ํ ๊ตฌ์ฒด์ ์ธ ํต์ฐฐ๋ ฅ์ ์ ๊ณตํฉ๋๋ค. ๊ฐ์ฅ ์ค์ํ ํญ๋ชฉ ์ ํ ์ค ์ผ๋ถ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
paint
: ๋ธ๋ผ์ฐ์ ๊ฐ ์ฒซ ๋ฒ์งธ ์ฝํ ์ธ ๊ฐ ์๋ ํ์ธํธ(FCP)์ ๊ฐ์ฅ ํฐ ์ฝํ ์ธ ๊ฐ ์๋ ํ์ธํธ(LCP)๋ฅผ ๋ ๋๋งํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ์ธก์ ํฉ๋๋ค. FCP๋ ๋ธ๋ผ์ฐ์ ๊ฐ DOM์์ ์ฒซ ๋ฒ์งธ ์ฝํ ์ธ ์กฐ๊ฐ์ ๋ ๋๋งํ์ฌ ์ฌ์ฉ์์๊ฒ ์ฒซ ์๊ฐ์ ํผ๋๋ฐฑ์ ์ ๊ณตํ๋ ์์ ์ ๋ํ๋ ๋๋ค. LCP๋ ๊ฐ์ฅ ํฐ ์ฝํ ์ธ ์์๊ฐ ๋ ๋๋ง๋์ด ํ์ด์ง์ ์ฃผ์ ์ฝํ ์ธ ๊ฐ ๋ก๋๋ ์์ ์ ๋ํ๋ ๋๋ค.resource
: ์ด๋ฏธ์ง, ์คํฌ๋ฆฝํธ, ์คํ์ผ์ํธ์ ๊ฐ์ ๊ฐ๋ณ ๋ฆฌ์์ค ๋ก๋ฉ์ ๋ํ ์์ธํ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด ํญ๋ชฉ ์ ํ์๋ DNS ์กฐํ ์๊ฐ, ์ฐ๊ฒฐ ์๊ฐ, ์์ฒญ ๊ธฐ๊ฐ ๋ฐ ์๋ต ํฌ๊ธฐ์ ๊ฐ์ ๋ฉํธ๋ฆญ์ด ํฌํจ๋ฉ๋๋ค.navigation
: ๋ค๋ฅธ ํ์ด์ง ๊ฐ์ ์ด๋ํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ์ธก์ ํฉ๋๋ค. ์ด ํญ๋ชฉ ์ ํ์๋ ๋ฆฌ๋๋ ์ ์๊ฐ, DNS ์กฐํ ์๊ฐ, ์ฐ๊ฒฐ ์๊ฐ ๋ฐ ์ฒซ ๋ฐ์ดํธ๊น์ง์ ์๊ฐ(TTFB)๊ณผ ๊ฐ์ ๋ฉํธ๋ฆญ์ด ํฌํจ๋ฉ๋๋ค.longtask
: ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ์ฌ ์ ์ฌ์ ์ผ๋ก ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์๋ ์ฅ๊ธฐ ์คํ ์์ ์ ์๋ณํฉ๋๋ค. ์ด๋ฌํ ์์ ์ ๋ ๋๋ง ์ ๋ฐ์ดํธ ๋ฐ ์ฌ์ฉ์ ์ํธ ์์ฉ ์๋ต์ ์ง์ฐ์ ์ ๋ฐํ ์ ์์ต๋๋ค.event
: ํด๋ฆญ, ํค ์ ๋ ฅ, ์คํฌ๋กค๊ณผ ๊ฐ์ ํน์ DOM ์ด๋ฒคํธ์ ๊ด๋ จ๋ ํ์ด๋ฐ ์ ๋ณด๋ฅผ ์บก์ฒํฉ๋๋ค.layout-shift
: ์ฌ์ฉ์ ๊ฒฝํ์ ๋ฐฉํดํ ์ ์๋ ํ์ด์ง์ ์๊ธฐ์น ์์ ๋ ์ด์์ ๋ณ๊ฒฝ์ ๊ฐ์งํฉ๋๋ค. ์ด๋ฌํ ๋ณ๊ฒฝ์ ์ข ์ข ๋์ ์ผ๋ก ์ฝํ ์ธ ๋ฅผ ๋ก๋ํ๊ฑฐ๋ ์์์ ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ ๋ ๋ฐ์ํฉ๋๋ค. ๋์ ๋ ์ด์์ ๋ณ๊ฒฝ(CLS)์ ์ด๋ฌํ ํญ๋ชฉ๋ค๋ก๋ถํฐ ๊ณ์ฐ๋ฉ๋๋ค.largest-contentful-paint
: ๋ทฐํฌํธ์์ ๋ณด์ด๋ ๊ฐ์ฅ ํฐ ์ฝํ ์ธ ์์์ ๋ ๋๋ง ์๊ฐ์ ์ธก์ ํฉ๋๋ค.first-input-delay
: ์ฌ์ฉ์ ์ํธ ์์ฉ๊ณผ ๋ธ๋ผ์ฐ์ ์ ์๋ต ์ฌ์ด์ ์ง์ฐ ์๊ฐ์ ์ธก์ ํฉ๋๋ค.
Performance Observer ์ค์ ํ๊ธฐ
Performance Observer API๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ์๋ก์ด PerformanceObserver
์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ ๊ด์ฐฐํ๋ ค๋ ํญ๋ชฉ ์ ํ์ ์ง์ ํด์ผ ํฉ๋๋ค. ๋ค์์ ๊ธฐ๋ณธ์ ์ธ ์์ ์
๋๋ค:
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
console.log(entry.name, entry.entryType, entry.startTime, entry.duration);
});
});
observer.observe({ entryTypes: ['paint', 'resource'] });
์ด ์์ ์์๋ paint
๋ฐ resource
์ด๋ฒคํธ๋ฅผ ์์ ํ๋ ์๋ก์ด PerformanceObserver
๋ฅผ ์์ฑํฉ๋๋ค. ์ฝ๋ฐฑ ํจ์๋ PerformanceEntry
๊ฐ์ฒด์ ๋ฐฐ์ด์ ํฌํจํ๋ PerformanceObserverEntryList
๋ฅผ ๋ฐ์ต๋๋ค. ๊ฐ PerformanceEntry
๋ ์ด๋ฆ, ํญ๋ชฉ ์ ํ, ์์ ์๊ฐ, ์ง์ ์๊ฐ๊ณผ ๊ฐ์ ๊ด์ฐฐ๋ ์ด๋ฒคํธ์ ๋ํ ์์ธํ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค.
๋ฉํธ๋ฆญ ์ง๊ณ ๋ฐ ํต๊ณ ์์ง
Performance Observer API๋ ์์ ์ฑ๋ฅ ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํ์ง๋ง, ์๋ฏธ ์๋ ํต์ฐฐ๋ ฅ์ ์ป๊ธฐ ์ํด์๋ ์ด ๋ฐ์ดํฐ๋ฅผ ์ง๊ณํ๊ณ ํต๊ณ๋ฅผ ๊ณ์ฐํด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ๋ค์์ ์ผ๋ฐ์ ์ธ ๋ฉํธ๋ฆญ ์ง๊ณ ๊ธฐ๋ฒ์ ๋๋ค:
1. ํ๊ท ๊ณ์ฐ
์ผ์ ๊ธฐ๊ฐ ๋์ ๋ฉํธ๋ฆญ์ ํ๊ท ๊ฐ์ ๊ณ์ฐํ๋ฉด ์ถ์ธ์ ์ด์ ์งํ๋ฅผ ์๋ณํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ํน์ ํ์ด์ง์ ์ด๋ฏธ์ง์ ๋ํ ํ๊ท ๋ก๋ ์๊ฐ์ ๊ณ์ฐํ ์ ์์ต๋๋ค. ์ด๋ฏธ์ง์ ๋ํ ๋ฆฌ์์ค ํ์ด๋ฐ ์ ๋ณด๋ฅผ ์ถ์ ํ๋ค๊ณ ๊ฐ์ ํด ๋ด
์๋ค. ๊ด๋ จ resource
ํญ๋ชฉ์ duration
์์ฑ์ ํ๊ท ๋ด๋ฉด ํ๊ท ์ด๋ฏธ์ง ๋ก๋ ์๊ฐ์ ์ป์ ์ ์์ต๋๋ค.
์์ (์๋ฐ์คํฌ๋ฆฝํธ):
let imageLoadTimes = [];
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
if (entry.entryType === 'resource' && entry.initiatorType === 'img') {
imageLoadTimes.push(entry.duration);
}
});
});
observer.observe({ entryTypes: ['resource'] });
// Function to calculate the average
function calculateAverage(array) {
if (array.length === 0) {
return 0;
}
const sum = array.reduce((a, b) => a + b, 0);
return sum / array.length;
}
// After a period of time, calculate the average image load time
setTimeout(() => {
const averageLoadTime = calculateAverage(imageLoadTimes);
console.log('Average Image Load Time:', averageLoadTime, 'ms');
}, 5000); // Collect data for 5 seconds
2. ๋ฐฑ๋ถ์์
๋ฐฑ๋ถ์์๋ ์ฑ๋ฅ ๋ฉํธ๋ฆญ์ ๋ถํฌ๋ฅผ ์ดํดํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ํ์ด์ง ๋ก๋ ์๊ฐ์ 95๋ฒ์งธ ๋ฐฑ๋ถ์์๋ ํ์ด์ง ๋ก๋์ 95%๊ฐ ์ด ๊ฐ ์๋์ ํด๋นํจ์ ๋ํ๋ ๋๋ค. ์ด๋ ์ด์์น๋ฅผ ์๋ณํ๊ณ ๋๋ค์์ ์ฌ์ฉ์๊ฐ ์ข์ ๊ฒฝํ์ ํ๋๋ก ๋ณด์ฅํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค. ๋ฐฑ๋ถ์์๋ฅผ ์ฌ์ฉํ๋ฉด ์์์ ์ฌ์ฉ์๊ฐ ๋๋ค์๋ณด๋ค ํจ์ฌ ๋๋ฆฐ ๊ฒฝํ์ ํ๊ณ ์๋์ง ์๋ณํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค. 95๋ฒ์งธ ๋ฐฑ๋ถ์์๋ ์ผ๋ฐ์ ์ธ ๋ฒค์น๋งํฌ์ ๋๋ค.
์์ (์๋ฐ์คํฌ๋ฆฝํธ - ๋ฐฑ๋ถ์์ ๊ณ์ฐ์ ์ํ ์ ํธ๋ฆฌํฐ ํจ์ ํ์):
// Utility function to calculate percentile (example implementation)
function calculatePercentile(arr, percentile) {
const sortedArr = arr.slice().sort((a, b) => a - b);
const index = (percentile / 100) * (sortedArr.length - 1);
if (Number.isInteger(index)) {
return sortedArr[index];
} else {
const lower = Math.floor(index);
const upper = Math.ceil(index);
const weight = index - lower;
return sortedArr[lower] * (1 - weight) + sortedArr[upper] * weight;
}
}
let pageLoadTimes = [];
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
if (entry.entryType === 'navigation') {
pageLoadTimes.push(entry.duration);
}
});
});
observer.observe({ entryTypes: ['navigation'] });
// After a period of time, calculate the 95th percentile page load time
setTimeout(() => {
const p95LoadTime = calculatePercentile(pageLoadTimes, 95);
console.log('95th Percentile Page Load Time:', p95LoadTime, 'ms');
}, 5000); // Collect data for 5 seconds
3. ํ์คํ ๊ทธ๋จ
ํ์คํ ๊ทธ๋จ์ ์ฑ๋ฅ ๋ฉํธ๋ฆญ์ ๋ถํฌ๋ฅผ ์๊ฐ์ ์ผ๋ก ํํํฉ๋๋ค. ๋ฐ์ดํฐ๋ฅผ ๋ฒํท์ผ๋ก ๊ทธ๋ฃนํํ๊ณ ๊ฐ ๋ฒํท ๋ด ๊ฐ์ ๋น๋๋ฅผ ๋ณด์ฌ์ค๋๋ค. ์ด๋ ๋จ์ํ ํ๊ท ์ด๋ ๋ฐฑ๋ถ์์๋ก๋ ๋ช ํํ์ง ์์ ์ ์๋ ํจํด๊ณผ ์ถ์ธ๋ฅผ ์๋ณํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ด๋ฏธ์ง ํฌ๊ธฐ์ ํ์คํ ๊ทธ๋จ์ ๋ถํ์ํ๊ฒ ํฐ ์ด๋ฏธ์ง๊ฐ ๋ง์์ง ์ ์ํ๊ฒ ๋๋ฌ๋ผ ์ ์์ต๋๋ค.
์์ (๊ฐ๋ ์ - ํ์คํ ๊ทธ๋จ ์๊ฐํ๋ฅผ ์ํด ์ฐจํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์):
// Conceptual Example (requires a charting library like Chart.js)
let imageSizes = [];
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
if (entry.entryType === 'resource' && entry.initiatorType === 'img') {
// Assuming 'decodedBodySize' represents the image size
imageSizes.push(entry.decodedBodySize);
}
});
});
observer.observe({ entryTypes: ['resource'] });
// After a period of time, create a histogram
setTimeout(() => {
// 1. Define bucket ranges (e.g., 0-100KB, 100-200KB, etc.)
const buckets = [
{ min: 0, max: 100 * 1024, count: 0 }, // 0-100KB
{ min: 100 * 1024, max: 200 * 1024, count: 0 }, // 100-200KB
{ min: 200 * 1024, max: Infinity, count: 0 } // 200KB+
];
// 2. Populate the buckets
imageSizes.forEach(size => {
for (const bucket of buckets) {
if (size >= bucket.min && size <= bucket.max) {
bucket.count++;
break;
}
}
});
// 3. Use a charting library (e.g., Chart.js) to visualize the histogram
console.log('Histogram Data:', buckets);
// Example: You would then use Chart.js to create a bar chart
// representing the count for each bucket.
}, 5000); // Collect data for 5 seconds
4. ์ค๋ฅ์จ
์คํจํ ๋ฆฌ์์ค ์์ฒญ๊ณผ ๊ฐ์ ์ค๋ฅ ๋น๋๋ฅผ ์ถ์ ํ๋ฉด ์น์ฌ์ดํธ์ ์ ์ฌ์ ์ธ ๋ฌธ์ ๋ฅผ ์๋ณํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค. ์ด๋ ๋คํธ์ํฌ ์ํ๋ ์๋ฒ ๊ฐ์ฉ์ฑ์ด ์ฑ๋ฅ์ ์ํฅ์ ๋ฏธ์น ์ ์๋ ๋ถ์ฐ ์์คํ ์์ ํนํ ์ ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์คํจํ ์ด๋ฏธ์ง ์์ฒญ ์๋ฅผ ๋ชจ๋ํฐ๋งํ๋ฉด CDN์ ๋ฌธ์ ๊ฐ ์์์ ๋ํ๋ผ ์ ์์ต๋๋ค. ๋์ ์ค๋ฅ์จ์ ์ข์ง ์์ ์ฌ์ฉ์ ๊ฒฝํ๊ณผ ์๊ด๊ด๊ณ๊ฐ ์์ต๋๋ค.
์์ (์๋ฐ์คํฌ๋ฆฝํธ):
let failedResourceCount = 0;
let totalResourceCount = 0;
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
if (entry.entryType === 'resource') {
totalResourceCount++;
if (entry.responseStatus >= 400) { // Consider 4xx and 5xx as errors
failedResourceCount++;
}
}
});
});
observer.observe({ entryTypes: ['resource'] });
// After a period of time, calculate the error rate
setTimeout(() => {
const errorRate = (totalResourceCount > 0) ? (failedResourceCount / totalResourceCount) * 100 : 0;
console.log('Resource Error Rate:', errorRate.toFixed(2), '%');
}, 5000); // Collect data for 5 seconds
์ค์ฉ์ ์ธ ์์ ๋ฐ ์์ฉ
1. ์ด๋ฏธ์ง ๋ก๋ฉ ์ต์ ํ
resource
ํญ๋ชฉ ์ ํ์ ์ถ์ ํจ์ผ๋ก์จ ๋๋ฆฌ๊ฒ ๋ก๋๋๋ ์ด๋ฏธ์ง๋ฅผ ์๋ณํ๊ณ ์ ๋ฌ์ ์ต์ ํํ ์ ์์ต๋๋ค. ์ฌ๊ธฐ์๋ ์ด๋ฏธ์ง ์์ถ, ์ ์ ํ ์ด๋ฏธ์ง ํ์(์: WebP) ์ฌ์ฉ ๋๋ ์ง์ฐ ๋ก๋ฉ ๊ตฌํ์ด ํฌํจ๋ ์ ์์ต๋๋ค. ๊ตญ์ ์ ์ธ ์ฌ์ฉ์๋ฅผ ์ํด, ์ฌ์ฉ์์ ์์น์ ๊ด๊ณ์์ด ๋น ๋ฅธ ์ด๋ฏธ์ง ์ ๋ฌ์ ๋ณด์ฅํ๊ธฐ ์ํด ๊ธ๋ก๋ฒ CDN ์ฌ์ฉ์ ๊ณ ๋ คํ์ญ์์ค.
2. ๋ ์ด์์ ๋ณ๊ฒฝ ์ค์ด๊ธฐ
layout-shift
ํญ๋ชฉ ์ ํ์ ๋ชจ๋ํฐ๋งํ๋ฉด ์๊ธฐ์น ์์ ๋ ์ด์์ ๋ณ๊ฒฝ์ ์ ๋ฐํ๋ ์์๋ฅผ ์๋ณํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ CSS ๋๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์กฐ์ ํ์ฌ ์ด๋ฌํ ๋ณ๊ฒฝ์ ๋ฐฉ์งํ๊ณ ํ์ด์ง์ ์๊ฐ์ ์์ ์ฑ์ ํฅ์์ํฌ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ด๋ฏธ์ง์ ๊ด๊ณ ๊ฐ ๋ก๋๋ ๋ ์ฝํ
์ธ ๊ฐ ์์ง์ด์ง ์๋๋ก ์์ฝ๋ ๊ณต๊ฐ์ ํ๋ณดํด์ผ ํฉ๋๋ค.
3. ์ฒซ ์ ๋ ฅ ์ง์ฐ(FID) ๊ฐ์
first-input-delay
ํญ๋ชฉ ์ ํ์ ์ถ์ ํ๋ฉด ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ๋ ์ฅ๊ธฐ ์คํ ์์
์ ์๋ณํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ์ต์ ํํ์ฌ ์ด๋ฌํ ์์
์ ์์๋๋ ์๊ฐ์ ์ค์ผ ์ ์์ต๋๋ค. FID๋ฅผ ๊ฐ์ ํ๊ธฐ ์ํด ์ฝ๋ ๋ถํ ๋ฐ ์ค์ํ์ง ์์ ์์
์ ์ง์ฐ ์คํ์ ๊ณ ๋ คํ์ญ์์ค. ์ด๋ ํนํ ์ํธ์์ฉ์ด ๋ง์ ์น ์ ํ๋ฆฌ์ผ์ด์
์ ์ค์ํฉ๋๋ค. ์น์ฌ์ดํธ๊ฐ ์ ์ธ๊ณ์ ์ผ๋ก ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ, ๋์ญํญ์ด ๋ฎ๊ฑฐ๋ ์ค๋๋ ์ฅ์น๋ฅผ ์ฌ์ฉํ๋ ์ง์ญ์ ์ํด ์๋ฐ์คํฌ๋ฆฝํธ ๋ฒ๋ค์ ์ต์ ํํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค.
4. ์๋ํํฐ ์คํฌ๋ฆฝํธ ๋ชจ๋ํฐ๋ง
์๋ํํฐ ์คํฌ๋ฆฝํธ๋ ์ข
์ข
ํ๋ฐํธ์๋ ์ฑ๋ฅ์ ์๋นํ ์ํฅ์ ๋ฏธ์น ์ ์์ต๋๋ค. ์ด๋ฌํ ์คํฌ๋ฆฝํธ์ ๋ํ resource
ํญ๋ชฉ ์ ํ์ ์ถ์ ํจ์ผ๋ก์จ ์น์ฌ์ดํธ ์๋๋ฅผ ์ ํ์ํค๋ ์คํฌ๋ฆฝํธ๋ฅผ ์๋ณํ ์ ์์ต๋๋ค. ์ด ์ ๋ณด๋ ์ด๋ฌํ ์คํฌ๋ฆฝํธ์ ๋ก๋ฉ์ ์ต์ ํํ๊ฑฐ๋ ์์ ํ ์ ๊ฑฐํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค. ๊ฐ ์๋ํํฐ ์คํฌ๋ฆฝํธ์ ์ฑ๋ฅ ์ํฅ์ ๋ถ์ํ๊ณ ํ์ํ ๊ฒฝ์ฐ ๋์์ ๊ณ ๋ คํ์ญ์์ค.
5. ์ฑ๋ฅ ๊ฐ์ A/B ํ ์คํธ
Performance Observer API๋ ์ฑ๋ฅ ์ต์ ํ์ ์ํฅ์ ์ธก์ ํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค. ๋ณ๊ฒฝ ์ฌํญ์ ๊ตฌํํ๊ธฐ ์ ๊ณผ ํ์ ์ฑ๋ฅ ๋ฉํธ๋ฆญ์ ๋น๊ตํจ์ผ๋ก์จ ๋ณ๊ฒฝ ์ฌํญ์ด ๊ธ์ ์ ์ธ ์ํฅ์ ๋ฏธ์น๋์ง ๋ถ์ ์ ์ธ ์ํฅ์ ๋ฏธ์น๋์ง ํ๋จํ ์ ์์ต๋๋ค. A/B ํ ์คํธ๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์ํ ์ต์ ํ ์ ๋ต์ ๋น๊ตํ๊ณ ๊ฐ์ฅ ํจ๊ณผ์ ์ธ ๊ฒ์ ์๋ณํ์ญ์์ค. ์ด๋ ๋ฐ์ดํฐ ๊ธฐ๋ฐ ์ฑ๋ฅ ๊ฐ์ ์ ํ์์ ์ ๋๋ค.
๊ณ ๊ธ ๊ธฐ๋ฒ
1. ์ฅ๊ธฐ ๋ถ์์ ์ํ ๋ฒํผ๋ง ์ฌ์ฉ
observe
๋ฉ์๋์ buffered
์ต์
์ ์ฌ์ฉํ๋ฉด ๊ด์ฐฐ์๊ฐ ์์ฑ๋๊ธฐ ์ ์ ๋ฐ์ํ ์ฑ๋ฅ ํญ๋ชฉ์ ์ ๊ทผํ ์ ์์ต๋๋ค. ์ด๋ ๊ณผ๊ฑฐ ์ฑ๋ฅ ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ณ ์๊ฐ ๊ฒฝ๊ณผ์ ๋ฐ๋ฅธ ์ถ์ธ๋ฅผ ์๋ณํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
const observer = new PerformanceObserver((list) => {
// Process entries
});
observer.observe({ entryTypes: ['navigation'], buffered: true });
2. ๋ถ์ ํ๋ซํผ๊ณผ ํตํฉ
Performance Observer API๋ฅผ ๊ธฐ์กด ๋ถ์ ํ๋ซํผ๊ณผ ํตํฉํ์ฌ ๋ค๋ฅธ ์ฌ์ฉ์ ํ๋ ๋ฐ์ดํฐ์ ํจ๊ป ์ฑ๋ฅ ๋ฉํธ๋ฆญ์ ์ถ์ ํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ์ ํ์จ ๋ฐ ์์ต๊ณผ ๊ฐ์ ๋น์ฆ๋์ค ๋ฉํธ๋ฆญ๊ณผ ์ฐ๊ด์ํฌ ์ ์์ต๋๋ค. Google Analytics, Adobe Analytics ๋๋ ๋ง์ถคํ ๋์๋ณด๋์ ๊ฐ์ ์ธ๊ธฐ ์๋ ๋ถ์ ๋๊ตฌ์์ ํตํฉ์ ๊ณ ๋ คํ์ญ์์ค. ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ณ ์ ์กํ ๋ GDPR๊ณผ ๊ฐ์ ๊ฐ์ธ ์ ๋ณด ๋ณดํธ ๊ท์ ์ ์ค์ํด์ผ ํฉ๋๋ค.
3. ๋ฉ์ธ ์ค๋ ๋ ์ธ๋ถ ๋ถ์์ ์ํ ์น ์์ปค ์ฌ์ฉ
๋ณต์กํ ๋ฉํธ๋ฆญ ์ง๊ณ ๋๋ ๋ถ์์ ์ํด ์น ์์ปค๋ฅผ ์ฌ์ฉํ์ฌ ์ฒ๋ฆฌ๋ฅผ ๋ณ๋์ ์ค๋ ๋๋ก ์คํ๋ก๋ํ ์ ์์ต๋๋ค. ์ด๋ ๋ฉ์ธ ์ค๋ ๋๊ฐ ์ฐจ๋จ๋๋ ๊ฒ์ ๋ฐฉ์งํ๊ณ ๋ถ๋๋ฌ์ด ์ฌ์ฉ์ ๊ฒฝํ์ ๋ณด์ฅํฉ๋๋ค. ์น ์์ปค๋ ๋ณต์กํ ํต๊ณ ๊ณ์ฐ์ด๋ ์์ธ ๋ณด๊ณ ์ ์์ฑ๊ณผ ๊ฐ์ ๊ณ์ฐ ์ง์ฝ์ ์ธ ์์ ์ ํนํ ์ ์ฉํฉ๋๋ค. ์ด๋ ๋จ์ผ ํ์ด์ง ์ ํ๋ฆฌ์ผ์ด์ (SPA)์์ ๋ฐ์์ฑ์ ์ ์งํ๋ ๋ฐ ์ค์ํฉ๋๋ค.
๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ์ํ ๊ณ ๋ ค ์ฌํญ
๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ์ํด ํ๋ฐํธ์๋ ์ฑ๋ฅ์ ์ต์ ํํ ๋ ๋ค์ ์ฌํญ์ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค:
- ๋คํธ์ํฌ ์กฐ๊ฑด: ๋ค๋ฅธ ์ง์ญ์ ์ฌ์ฉ์๋ ๋คํธ์ํฌ ์๋์ ์ง์ฐ ์๊ฐ์ด ๋ค๋ฅผ ์ ์์ต๋๋ค. ์ ๋์ญํญ ์ฐ๊ฒฐ์ ๋ง๊ฒ ์น์ฌ์ดํธ๋ฅผ ์ต์ ํํ์ญ์์ค.
- ์ฅ์น ๊ธฐ๋ฅ: ์ฌ์ฉ์๋ ๊ณ ๊ธ ์ค๋งํธํฐ๋ถํฐ ์ ๊ฐํ ํผ์ฒํฐ์ ์ด๋ฅด๊ธฐ๊น์ง ๋ค์ํ ์ฅ์น์์ ์น์ฌ์ดํธ์ ์ ์ํ ์ ์์ต๋๋ค. ๋ค์ํ ์ฅ์น ๊ธฐ๋ฅ์ ๋ง๊ฒ ์น์ฌ์ดํธ๋ฅผ ์ต์ ํํ์ญ์์ค.
- ์ฝํ ์ธ ์ ์ก ๋คํธ์ํฌ(CDN): CDN์ ์ฌ์ฉํ์ฌ ์ ์ธ๊ณ์ ์์นํ ์๋ฒ์์ ์น์ฌ์ดํธ ์ฝํ ์ธ ๋ฅผ ์ ๋ฌํ์ญ์์ค. ์ด๋ ๋ค๋ฅธ ์ง์ญ ์ฌ์ฉ์์ ์ง์ฐ ์๊ฐ์ ์ค์ด๊ณ ํ์ด์ง ๋ก๋ ์๊ฐ์ ๊ฐ์ ํฉ๋๋ค.
- ํ์งํ: ๋ค๋ฅธ ์ธ์ด์ ๋ฌธํ์ ๋ง๊ฒ ์น์ฌ์ดํธ๋ฅผ ์ต์ ํํ์ญ์์ค. ์ฌ๊ธฐ์๋ ์ฝํ ์ธ ๋ฒ์ญ, ์ ์ ํ ๋ ์ง ๋ฐ ์๊ฐ ํ์ ์ฌ์ฉ, ๋์์ธ์์์ ๋ฌธํ์ ์ฐจ์ด ๊ณ ๋ ค๊ฐ ํฌํจ๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ๊ฐ์ธ ์ ๋ณด ๋ณดํธ: ์ ๋ฝ์ GDPR ๋ฐ ์บ๋ฆฌํฌ๋์์ CCPA์ ๊ฐ์ ์ฌ๋ฌ ๊ตญ๊ฐ์ ๋ฐ์ดํฐ ๊ฐ์ธ ์ ๋ณด ๋ณดํธ ๊ท์ ์ ์์งํ์ญ์์ค. ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ณ ์ฒ๋ฆฌํ ๋ ์ด๋ฌํ ๊ท์ ์ ์ค์ํด์ผ ํฉ๋๋ค.
๊ฒฐ๋ก
Performance Observer API๋ ํ๋ฐํธ์๋ ์ฑ๋ฅ ๋ฉํธ๋ฆญ์ ์์งํ๊ณ ์ง๊ณํ๋ ๊ฐ๋ ฅํ๊ณ ์ ์ฐํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ๋ค์ํ ํญ๋ชฉ ์ ํ, ๋ฉํธ๋ฆญ ์ง๊ณ ๊ธฐ๋ฒ ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ดํดํจ์ผ๋ก์จ ์น์ฌ์ดํธ ์ฑ๋ฅ์ ํจ๊ณผ์ ์ผ๋ก ๋ชจ๋ํฐ๋งํ๊ณ ์ต์ ํํ์ฌ ์ฌ์ฉ์ ๊ฒฝํ๊ณผ ๋น์ฆ๋์ค ์ฑ๊ณผ๋ฅผ ํฅ์์ํฌ ์ ์์ต๋๋ค. ์ฑ๋ฅ์ ์ต์ ํํ ๋ ๊ธ๋ก๋ฒ ์ฌ์ฉ์์ ์๊ตฌ๋ฅผ ๊ณ ๋ คํ๊ณ ๋ชจ๋ ์ฌ์ฉ์์๊ฒ ๋น ๋ฅด๊ณ ๋ฐ์์ด ๋น ๋ฅธ ๊ฒฝํ์ ์ ๊ณตํ๊ธฐ ์ํด ํญ์ ๋ ธ๋ ฅํด์ผ ํฉ๋๋ค.
Performance Observer API๋ฅผ ํ์ฉํ๊ณ ๊ฐ๋ ฅํ ๋ฉํธ๋ฆญ ์ง๊ณ ์ ๋ต์ ๊ตฌํํจ์ผ๋ก์จ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์ฌ์ ์ ์๋ณํ๊ณ ํด๊ฒฐํ์ฌ ๋ชจ๋ ์ฅ์น์ ์์น์์ ์ผ๊ด๋๊ฒ ์ฐ์ํ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ณด์ฅํ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ ๊ธฐ๋ฐ ์์ฌ ๊ฒฐ์ ์ ์ฑํํ๊ณ ์น์ฌ์ดํธ ์ฑ๋ฅ์ ์ง์์ ์ผ๋ก ๋ชจ๋ํฐ๋งํ์ฌ ๊ฒฝ์์์ ์์๋๊ฐ๊ณ ์ฌ์ฉ์์๊ฒ ํ์ํ ๊ฐ์น๋ฅผ ์ ๊ณตํ์ญ์์ค.