[Observer API ํํค์น๊ธฐ] 5. PerformanceObserver
- 1. PerformanceObserver
- 1.1. options
- 1.1.1. ๊ด์ฐฐ ๋์ (type)
- 1.1.2. ๊ด์ฐฐ ๋์ ๋ชฉ๋ก (entryTypes)
- 1.1.3. ๊ธฐ์กด ์ฑ๋ฅ ํญ๋ชฉ ํฌํจ ์ฌ๋ถ (buffered)
- 1.2. callback
- 1.2.1. entries
- 1.2.2. observer
- 2. React์์ ์ปค์คํ ํ ์ผ๋ก ๊ฐํธํ๊ฒ ์ฌ์ฉํ๊ธฐ
- 2.1. ์ ์ฒด ์ฝ๋
- 2.2. CodeSandbox๋ก ํตํ ์์
- 3. ๋ง์น๋ฉฐ
PerformanceObserver
๋ ์ฑ๋ฅ ์ด๋ฒคํธ๋ฅผ ๊ด์ธกํ๋ ์ต์ ๋ฒ API๋ค. F12๋ฅผ ๋๋ฅด๋ฉด ๋์ค๋ ๊ฐ๋ฐ์๋๊ตฌ์ ์ฑ๋ฅ ํญ๊ณผ ์ฐ๊ด๋๋ค.
TYPESCRIPT1 2 3
const po = new PerformanceObserver(callback); po.observer(options);
ํ์ด์ง ์ฑ๋ฅ๊ณผ ๊ด๋ จ๋ ์ต์ ๋ฒ๋ผ๋ ํน์ง์ผ๋ก์ธํด, ํ ์ต์ ๋ฒ์ ๋ฌ๋ฆฌ ํ๊ทธ๋ฅผ ๋ฑ๋กํ๋ ๊ณผ์ ์ด ์๋ค.
์ต์ ๋ฒ ๋ฑ๋ก ์ options
๋ฅผ ์ ๋ฌํ์ฌ ์ธ๋ถ ์ต์
์ ์กฐ์ ํ ์ ์๋ค. PerformanceObserverInit
ํ์
์ ๊ฐ์ง๋ค.
์ต์ ๋ฒ๊ฐ ๊ด์ฐฐํ ์ฑ๋ฅ ์์๋ฅผ ์ง์ ํ๋ค. ๊ฐ ์์๋ ์๋์ ๊ฐ๋ค.
navigation
- ํ์ด์ง ๋ก๋์ ์ฐ๊ด๋ ์ฑ๋ฅ ์งํ. ํ์ด์ง ์ฒซ ๋ก๋ ์์ ํ์ด๋ฐ ์ ๋ณด ๋ฑ์ ์์งํ ์ ์๋ค.resource
- ํ์ด์ง์ ๋ก๋๋ ๋ฆฌ์์ค์ ์ฐ๊ด๋ ์ฑ๋ฅ ์งํ. ์ด๋ฏธ์ง,js
,css
๋ฑ์ด ๋์์ ํด๋น๋๋ค.mark
- ๊ฐ๋ฐ์๊ฐ ์ง์ ํ ์์์ ํ์ด๋ฐ ์ ๋ณด.measure
- ์ง์ ํ ๋mark
์ฌ์ด์ ์๊ฐ ์ธก์ .paint
- ํ์ด์ง์ ๋ ๋๋ง ๋ฐ ํ์ธํธ์ ๊ด๋ จ๋ ์ฑ๋ฅ ์งํ. ์ฒซ ํ์ด์ง ํ์ธํ (FP), ์ต์ด์ ์ ์๋ฏธํ ํ์ธํ (FMP) ๋ฑ์ด ํด๋นํ๋ค.longtask
- 50ms ์ด์์ ๊ธด ํ๋ก์ธ์ค ์๋ณelement
- DOM ์์ ๋ ๋๋ง๊ณผ ์ฐ๊ด๋ ์ฑ๋ฅ ์งํ.frame
- ์ ๋๋ฉ์ด์ ํ๋ ์๊ณผ ๋ จ๊ด๋ ์ฑ๋ฅ ์งํ. ์ ๋๋ฉ์ด์ ๋ฐ ์คํฌ๋กค ์ฑ๋ฅ ๋ถ์๊ณผ ๊ด๋ จ๋ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ค.event
- ์ด๋ฒคํธ ๋ฐ์๊ณผ ์ฐ๊ด๋ ์ฑ๋ฅ ์งํ.first-input
- ์ฌ์ฉ์์ ์ก์ ๊ณผ ๊ด๋ จ๋ ์ฑ๋ฅ ์งํ.largest-contentful-paint
- ๋์ฉ๋ ์์์ ๋ ๋๋ง ์ฑ๋ฅ ์งํ.layout-shift
- ํ์ด์ง์ ์์ ์ด๋ ์ฑ๋ฅ ์งํ.
type
์ ํ์ ํ entryTypes
์ ๋ณํํ์ฌ ์ฌ์ฉํ ์ ์๋ค.
์ต์ ๋ฒ๊ฐ ๊ด์ฐฐํ ์ฑ๋ฅ ์์๋ฅผ ๋ฐฐ์ด๋ก ์ง์ ํ๋ค. ์ฌ๋ฌ ์ฑ๋ฅ ์งํ๋ฅผ ์ธก์ ํ ๋ ์ฉ์ดํ๋ค.
๊ธฐ์กด ์ฑ๋ฅ ์งํ ํฌํจ ์ฌ๋ถ๋ฅผ ์ง์ ํ๋ ์ต์
์ด๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก false
๋ก ์ ์ธ๋์ด์๋ค.
์ฝ๋ฐฑ ๋ฉ์๋๋ฅผ ํตํด ์ฑ๋ฅ ๊ด๋ จ ์งํ๋ฅผ ๋ค๋ฃฐ ์ ์๋ค. PerformanceObserverCallback
ํ์
์ ๊ฐ์ง๋ค.
์ฑ๋ฅ ์งํ ๊ฐ์ฒด PerformanceObserverEntryList
๋ฅผ ๋ฐํํ๋ค. getEntries
, getEntriesByName
, getEntriesByType
๋ฉ์๋๋ฅผ ํตํด ์ํ๋ ๋ชฉ๋ก์ ๋ฝ์๋ผ ์ ์๋ค.
๊ฐ ์์๋ type
ํน์ entryTypes
์ ์ง์ ํ ์์์ ๋ฐ๋ฅธ ์ฑ๋ฅ ๊ฐ์ฒด๋ค. ์ธก์ ๋ ์ฑ๋ฅ ์์์ ๋ฐ๋ผ ์์ดํ ๊ฐ์ฒด๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
PerformanceObserver
๊ฐ์ฒด๋ฅผ ๋ฐํํด์ค๋ค. ์ด๋ฅผ ํตํด ์ฝ๋ฐฑ ๋ฉ์๋ ๋ด์์๋ PerformanceObserver
๋ฅผ ์ฐ์์ ์ผ๋ก ๋ค๋ฃฐ ์ ์๋ค.
PerformanceObserver
๋ฅผ ์ปค์คํ
ํ
์ ํตํด ๊ฐํธํ๊ฒ ์ฌ์ฉํด๋ณด์.
TYPESCRIPT1 2 3 4
export function usePerformanceObserver(): void { // }
์์ ๊ฐ์ด usePerformanceObserver
๋ฉ์๋๋ฅผ ์ ์ํ๋ค.
useMutationObserver
๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ ์๋์ ๋ ์์๊ฐ ํ์ํ๋ค.
- ์ฝ๋ฐฑ ๋ฉ์๋
- ์ต์
์ง๊ธ๊น์ง์ ์ต์ ๋ฒ์ ๋ฌ๋ฆฌ DOM์ด ํ์ํ์ง ์๋ค.
TYPESCRIPT1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
import { useEffect } from "react"; export type UsePerformanceObserverCallback = (entry: PerformanceEntry) => void; /** * PerformanceObserver ์ ์ฉ ํ ๋ฉ์๋ * * @param {UsePerformanceObserverCallback} callback: ์ฝ๋ฐฑ ๋ฉ์๋ * @param {PerformanceObserverInit} options: ์ต์ */ export function usePerformanceObserver( callback: UsePerformanceObserverCallback, options?: PerformanceObserverInit ): void { useEffect(() => { const po = new PerformanceObserver((entries) => { entries.getEntries().forEach(callback); }); }, [callback, options]); }
PerformanceObserver
๋ฅผ ์ด๊ธฐํํ์ฌ po
๋ณ์๋ก ํ ๋นํ๋ค.
po.observe()
๋ฉ์๋๋ฅผ ํตํด ํ๊ทธ๋ฅผ ๋ฑ๋กํ ์ ์๋ค.
TYPESCRIPT1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
import { useEffect } from "react"; export type UsePerformanceObserverCallback = (entry: PerformanceEntry) => void; /** * PerformanceObserver ์ ์ฉ ํ ๋ฉ์๋ * * @param {UsePerformanceObserverCallback} callback: ์ฝ๋ฐฑ ๋ฉ์๋ * @param {PerformanceObserverInit} options: ์ต์ */ export function usePerformanceObserver( callback: UsePerformanceObserverCallback, options?: PerformanceObserverInit ): void { useEffect(() => { const po = new PerformanceObserver((entries) => { entries.getEntries().forEach(callback); }); po.observe(options); }, [callback, options]); }
๋ง์ง๋ง์ผ๋ก, ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง ๋ ๋๋ง๋ค PerformanceObserver
์ ๋ฑ๋ก์ด ์ค์ฒฉ๋์ง ์๋๋ก, ์ด๊ธฐํ ์ฝ๋๋ฅผ ๋ฃ์ด์ค๋ค.
po.disconnect()
๋ฉ์๋๋ฅผ ํตํด PerformanceObserver
๋ฅผ ์ ๊ฑฐํ ์ ์๋ค.
TYPESCRIPT1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
import { useEffect } from "react"; export type UsePerformanceObserverCallback = (entry: PerformanceEntry) => void; /** * PerformanceObserver ์ ์ฉ ํ ๋ฉ์๋ * * @param {UsePerformanceObserverCallback} callback: ์ฝ๋ฐฑ ๋ฉ์๋ * @param {PerformanceObserverInit} options: ์ต์ */ export function usePerformanceObserver( callback: UsePerformanceObserverCallback, options?: PerformanceObserverInit ): void { useEffect(() => { const po = new PerformanceObserver((entries) => { entries.getEntries().forEach(callback); }); po.observe(options); return () => { po.disconnect(); }; }, [callback, options]); }
์ ์ฒด ์ฝ๋๋ ์์ ๊ฐ๋ค.
CodeSandbox๋ก ๊ฐ๋จํ ์์๋ฅผ ๊ตฌํํ๋ค.
Lighthouse ์ฑ๋ฅ ์ธก์
PerformanceObserver
๋ฅผ ํตํด ํ์ด์ง์ ์ฑ๋ฅ ์งํ๋ฅผ ์ธก์ ํ ์ ์๋ค. ์ด๋ฅผ ์ ์ ํ ๊ตฌ์ฑํ๋ฉด Lighthouse์ ๊ฐ์ ์น ์ฑ๋ฅ ์ธก์ ์๋น์ค๋ฅผ ์ ์ฌํ๊ฒ ๊ตฌํํ ์ ์์ ๊ฒ์ด๋ค.
ํ์ง๋ง ์ด๋ฏธ ๋น์ทํ๊ฑฐ๋, ๋ ์ฐ์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ์ฌ๋ฌ ์คํ/์์ฉ ๋๊ตฌ๋ค์ด ๋ง์ ๊ฒ์ด ํ์ค์ด๋ค. ๋ํ ์์ ๋ค๋ฃฌ ์ธ ์ต์ ๋ฒ์ ๋ฌ๋ฆฌ, ๊ธฐ๋ฅ ๊ฐ๋ฐ์ ์์ด ๋ฒ์ฉ์ฑ์ด ๋ง์ด ๋จ์ด์ง๋ ํ์, ๊ด๋ จ ์ ๋ณด๊ฐ ๋ง์ด ์๋ค๋ ๊ฒ์ด ๋จ์ ์ด๋ค.
๋ง์ง๋ง์ผ๋ก ๋ค๋ฃฐ ์ต์ ๋ฒ๋ ReportingObserver
๋ค.