Performance Observer APIãæŽ»çšããå®è¡äžã®ãŠã§ãããã©ãŒãã³ã¹ãç£èŠãã³ã¢ãŠã§ããã€ã¿ã«ã远跡ããå šäžçã®ãŠãŒã¶ãŒäœéšãæé©åãã匷åãã€éäŸµå ¥çãªæ¹æ³ã解説ããŸãã
ãŠã§ãããã©ãŒãã³ã¹ãè§£ãæããïŒPerformance Observer API 詳现解説
仿¥ã®ããŒã¹ã®éãããžã¿ã«ã®äžçã«ãããŠããŠã§ãããã©ãŒãã³ã¹ã¯èŽ æ²¢åã§ã¯ãªããå¿ éåã§ãããŠã§ããµã€ããé ãããŸãã¯åå¿ããªããšããŠãŒã¶ãŒã®äžæºãçŽåž°çã®äžæããããŠå£²äžãåºååå ¥ããŠãŒã¶ãŒãšã³ã²ãŒãžã¡ã³ããšãã£ãããžãã¹ç®æšãžã®çŽæ¥çãªæªåœ±é¿ã«ã€ãªãããŸããé·å¹Žãéçºè ã¯éåžžãæåã®ããŒãžèªã¿èŸŒã¿æãšããåäžã®æç¹ã§ã®ããã©ãŒãã³ã¹ã枬å®ããããŒã«ã«é Œã£ãŠããŸãããããã¯æçšã§ã¯ãããã®ã®ããŠãŒã¶ãŒãããŒãžãšå¯Ÿè©±ããäžã§ã®å šäœçãªäœéšãšãããç©èªã®éèŠãªéšåãèŠéããŠããŸããŸããããã§ã©ã³ã¿ã€ã ã®ããã©ãŒãã³ã¹ç£èŠãç»å Žãããã®æã匷åãªããŒã«ãPerformance Observer APIã§ãã
åŸæ¥ã®æ¹æ³ã§ã¯ãperformance.getEntries()ã®ãããªé¢æ°ã§ããã©ãŒãã³ã¹ããŒã¿ãããŒãªã³ã°ããããšããããããŸãããããã¯éå¹ççã§ãããŒãªã³ã°ã®åéã«çºçããéèŠãªã€ãã³ããèŠéããã¡ã§ãããæž¬å®ããããšããŠããããã©ãŒãã³ã¹ãªãŒããŒãããèªäœãå¢å ãããããšãããããŸããPerformance Observer APIã¯ãããã©ãŒãã³ã¹ã€ãã³ããçºçãããšãã«ããã賌èªããããã®ãéåæçã§äœãªãŒããŒãããã®ã¡ã«ããºã ãæäŸããããšã§ããã®ããã»ã¹ã«é©åœããããããŸãããã®ã¬ã€ãã§ã¯ããã®äžå¯æ¬ ãªAPIãæ·±ãæãäžãããã®åãæŽ»çšããŠã³ã¢ãŠã§ããã€ã¿ã«ãç£èŠããããã«ããã¯ãç¹å®ããæçµçã«ã¯äžçäžã®ãŠãŒã¶ãŒã®ããã«ããéããããå¿«é©ãªãŠã§ãäœéšãæ§ç¯ããæ¹æ³ã瀺ããŸãã
Performance Observer APIãšã¯ïŒ
ãã®æ žå¿ã«ãããŠãPerformance Observer APIã¯ãããã©ãŒãã³ã¹ãšã³ããªãšããŠç¥ãããããã©ãŒãã³ã¹æž¬å®ã€ãã³ããç£èŠããåéããæ¹æ³ãæäŸããã€ã³ã¿ãŒãã§ãŒã¹ã§ãããã©ãŠã¶å ã§ã®ããã©ãŒãã³ã¹é¢é£ã®ã¢ã¯ãã£ããã£å°çšã®ãªã¹ããŒãšèããŠãã ãããããªããç©æ¥µçã«ãã©ãŠã¶ã«ãäœãèµ·ãããŸãããïŒããšå°ãã代ããã«ããã©ãŠã¶ãç©æ¥µçã«ãæ°ããããã©ãŒãã³ã¹ã€ãã³ããçºçããŸããïŒè©³çްã¯ãã¡ãã§ãããšæããŠãããã®ã§ãã
ããã¯ãªãã¶ãŒããŒãã¿ãŒã³ã«ãã£ãŠå®çŸãããŸãããªãã¶ãŒããŒã®ã€ã³ã¹ã¿ã³ã¹ãäœæããã©ã®ã¿ã€ãã®ããã©ãŒãã³ã¹ã€ãã³ãã«èå³ããããïŒäŸïŒå€§ããªãã€ã³ãããŠãŒã¶ãŒå ¥åãã¬ã€ã¢ãŠãã·ãããªã©ïŒãäŒããã³ãŒã«ããã¯é¢æ°ãæäŸããŸããæå®ãããã¿ã€ãã®æ°ããã€ãã³ãããã©ãŠã¶ã®ããã©ãŒãã³ã¹ã¿ã€ã ã©ã€ã³ã«èšé²ããããã³ã«ãããªãã®ã³ãŒã«ããã¯é¢æ°ãæ°ãããšã³ããªã®ãªã¹ããšãšãã«åŒã³åºãããŸãããã®éåæçãªããã·ã¥ããŒã¹ã®ã¢ãã«ã¯ãperformance.getEntries()ãç¹°ãè¿ãåŒã³åºãå€ããã«ããŒã¹ã®ã¢ãã«ãããã¯ããã«å¹ççã§ä¿¡é Œæ§ããããŸãã
å€ãæ¹æ³ vs. æ°ããæ¹æ³
Performance Observerã®é©æ°æ§ãçè§£ããããã«ã2ã€ã®ã¢ãããŒãã察æ¯ããŠã¿ãŸãããïŒ
- å€ãæ¹æ³ïŒããŒãªã³ã°ïŒïŒ setTimeoutãrequestAnimationFrameã䜿çšããŠå®æçã«performance.getEntriesByName('my-metric')ãåŒã³åºããã¡ããªãã¯ãèšé²ããããã©ããã確èªãããããããŸãããããã¯ããã§ãã¯ãé ãããŠã€ãã³ããèŠéããããé »ç¹ã«ãã§ãã¯ããããŠCPUãµã€ã¯ã«ãç¡é§ã«ãããããå¯èœæ§ããããããåé¡ããããŸãããŸãã宿çã«ãšã³ããªãã¯ãªã¢ããªããšããã©ãŠã¶ã®ããã©ãŒãã³ã¹ãããã¡ãäžæ¯ã«ããŠããŸããªã¹ã¯ããããŸãã
- æ°ããæ¹æ³ïŒç£èŠïŒïŒ PerformanceObserverãäžåºŠèšå®ããŸããããã¯ããã¯ã°ã©ãŠã³ãã§éãã«åŸ æ©ããæå°éã®ãªãœãŒã¹ãæ¶è²»ããŸããé¢é£ããããã©ãŒãã³ã¹ãšã³ããªãèšé²ããããšããã«ïŒãããããŒãžèªã¿èŸŒã¿åŸ1ããªç§ã§ããããšããŠãŒã¶ãŒã»ãã·ã§ã³éå§åŸ10åã§ããããšïŒãããªãã®ã³ãŒãã¯å³åº§ã«éç¥ãããŸããããã«ãããã€ãã³ããèŠéãããšããªããªããç£èŠã³ãŒãã¯å¯èœãªéãå¹ççã«ãªããŸãã
ãªãPerformance Observerã䜿ãã¹ããªã®ã
Performance Observer APIãéçºã¯ãŒã¯ãããŒã«çµ±åããããšã¯ãã°ããŒãã«ãªå±éãç®æãçŸä»£ã®ãŠã§ãã¢ããªã±ãŒã·ã§ã³ã«ãšã£ãŠäžå¯æ¬ ãªå€ãã®å©ç¹ãæäŸããŸãã
- éäŸµå ¥çãªã¢ãã¿ãªã³ã°ïŒ ãªãã¶ãŒããŒã®ã³ãŒã«ããã¯ã¯éåžžãã¢ã€ãã«æéäžã«å®è¡ããããããããã©ãŒãã³ã¹ç£èŠã³ãŒãããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã劚ããããã¡ã€ã³ã¹ã¬ããããããã¯ãããããããšããããŸããã軜éã§ãããã©ãŒãã³ã¹ãžã®åœ±é¿ãç¡èŠã§ããã»ã©å°ãããªãããã«èšèšãããŠããŸãã
- å æ¬çãªã©ã³ã¿ã€ã ããŒã¿ïŒ ãŠã§ãã¯åçã§ããããã©ãŒãã³ã¹ã®åé¡ã¯èªã¿èŸŒã¿æã«ã ãçºçããããã§ã¯ãããŸããããŠãŒã¶ãŒã¯è€éãªã¢ãã¡ãŒã·ã§ã³ãããªã¬ãŒããããã¹ã¯ããŒã«ããŠããã«ã³ã³ãã³ããèªã¿èŸŒãã ããæåã®ããŒãžãèœã¡çãããã£ãšåŸã§éãã³ã³ããŒãã³ããšå¯Ÿè©±ããããããããããŸãããPerformance Observerã¯ãããã®ã©ã³ã¿ã€ã ã€ãã³ãããã£ããã£ãããŠãŒã¶ãŒã»ãã·ã§ã³å šäœã®å®å šãªç¶æ³ãæäŸããŸãã
- å°æ¥æ§ãããæšæºåãããŠããïŒ ããã¯W3Cãæšå¥šããããã©ãŒãã³ã¹ããŒã¿åéã®æšæºã§ããæ°ããããã©ãŒãã³ã¹ã¡ããªãã¯ãAPIã¯ãããšçµ±åããããã«èšèšãããŠããããããžã§ã¯ãã«ãšã£ãŠæç¶å¯èœã§å°æ¥ãèŠæ®ããéžæè¢ãšãªããŸãã
- ãªã¢ã«ãŠãŒã¶ãŒã¢ãã¿ãªã³ã°ïŒRUMïŒã®åºç€ïŒ ããŸããŸãªåœãããã€ã¹ããããã¯ãŒã¯æ¡ä»¶ã®ãŠãŒã¶ãŒã«ãšã£ãŠãµã€ããã©ã®ããã«åäœããããçã«çè§£ããããã«ã¯ãå®éã®ã»ãã·ã§ã³ããã®ããŒã¿ãå¿ èŠã§ããPerformance Observerã¯ãå ç¢ãªRUMãœãªã¥ãŒã·ã§ã³ãæ§ç¯ããããã®çæ³çãªããŒã«ã§ãããéèŠãªã¡ããªãã¯ãåéããéèšãšåæã®ããã«åæãµãŒãã¹ã«éä¿¡ããããšãã§ããŸãã
- ç«¶åç¶æ ã®æé€ïŒ ããŒãªã³ã°ã§ã¯ãããã©ãŒãã³ã¹ãšã³ããªãèšé²ãããåã«ã¢ã¯ã»ã¹ããããšããããšããããŸãããªãã¶ãŒããŒã¢ãã«ã¯ããšã³ããªãå©çšå¯èœã«ãªã£ãåŸã«ã®ã¿ã³ãŒããå®è¡ãããããããã®ç«¶åç¶æ ãå®å šã«æé€ããŸãã
ã¯ããã«ïŒPerformance Observerã®åºæ¬
APIã®äœ¿çšã¯ç°¡åã§ããããã»ã¹ã«ã¯äž»ã«3ã€ã®ã¹ããããå«ãŸããŸãïŒãªãã¶ãŒããŒã®äœæãã³ãŒã«ããã¯ã®å®çŸ©ããããŠãªãã¶ãŒããŒã«äœãç£èŠããããäŒããããšã§ãã
1. ã³ãŒã«ããã¯ãæã€ãªãã¶ãŒããŒã®äœæ
ãŸããPerformanceObserverãªããžã§ã¯ããã€ã³ã¹ã¿ã³ã¹åããã³ãŒã«ããã¯é¢æ°ãæž¡ããŸãããã®é¢æ°ã¯ãæ°ãããšã³ããªãæ€åºããããã³ã«å®è¡ãããŸãã
const observer = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { console.log('ãšã³ããªãŒã¿ã€ã:', entry.entryType); console.log('ãšã³ããªãŒå:', entry.name); console.log('éå§æé:', entry.startTime); console.log('æç¶æé:', entry.duration); } });
ã³ãŒã«ããã¯ã¯PerformanceObserverEntryListãªããžã§ã¯ããåãåããŸãããã®ãªã¹ãã®getEntries()ã¡ãœãããåŒã³åºãããšã§ãæ°ããç£èŠããããã¹ãŠã®ããã©ãŒãã³ã¹ãšã³ããªã®é åãååŸã§ããŸãã
2. ç¹å®ã®ãšã³ããªã¿ã€ããç£èŠãã
ãªãã¶ãŒããŒã¯ãäœãç£èŠããããæç€ºããããŸã§äœãããŸãããããã«ã¯.observe()ã¡ãœããã䜿çšããŸãããã®ã¡ãœããã¯ãç£èŠãããããã©ãŒãã³ã¹ãšã³ããªã¿ã€ãã衚ãæååã®é åã§ããentryTypesããããã£ïŒãŸãã¯çŸä»£çãªã±ãŒã¹ã§ã¯åäžã¿ã€ãã®å ŽåtypeïŒãæã€ãªããžã§ã¯ããåãåããŸãã
// 2çš®é¡ã®ãšã³ããªã®ç£èŠãéå§ observer.observe({ entryTypes: ['mark', 'measure'] });
æãäžè¬çãªãšã³ããªã¿ã€ãã«ã¯ä»¥äžã®ãããªãã®ããããŸãïŒ
- 'resource': ã¹ã¯ãªãããç»åãã¹ã¿ã€ã«ã·ãŒããªã©ã®ã¢ã»ããã«å¯Ÿãããããã¯ãŒã¯ãªã¯ãšã¹ãã®è©³çްã
- 'paint': first-paintããã³first-contentful-paintã®ã¿ã€ãã³ã°ã
- 'largest-contentful-paint': äœæçãªèªã¿èŸŒã¿é床ã«é¢ããã³ã¢ãŠã§ããã€ã¿ã«ã®ã¡ããªãã¯ã
- 'layout-shift': èŠèŠçãªå®å®æ§ã«é¢ããã³ã¢ãŠã§ããã€ã¿ã«ã®ã¡ããªãã¯ã
- 'first-input': First Input Delayãšããã³ã¢ãŠã§ããã€ã¿ã«ã«äœ¿çšããããæåã®ãŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ã«é¢ããæ å ±ã
- 'longtask': ã¡ã€ã³ã¹ã¬ããäžã§50ããªç§ä»¥äžãããã¿ã¹ã¯ãç¹å®ããå¿çæ§ã®äœäžãåŒãèµ·ããå¯èœæ§ããããŸãã
- 'mark' & 'measure': User Timing APIã䜿çšããŠç¬èªã®ã³ãŒãã§å®çŸ©ããã«ã¹ã¿ã ããŒã«ãŒãšæž¬å®ã
3. ãªãã¶ãŒããŒã®åæ¢
ããŒã¿ã®åéãäžèŠã«ãªã£ãå Žåã¯ããªãœãŒã¹ãè§£æŸããããã«ãªãã¶ãŒããŒãåæããããšãè¯ãç¿æ £ã§ãã
observer.disconnect();
å®è·µçãªãŠãŒã¹ã±ãŒã¹ïŒã³ã¢ãŠã§ããã€ã¿ã«ã®ã¢ãã¿ãªã³ã°
ã³ã¢ãŠã§ããã€ã¿ã«ã¯ãGoogleããŠã§ãããŒãžã®å šäœçãªãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã«ãããŠéèŠãšèããç¹å®ã®èŠå ã®ã»ããã§ããããããç£èŠããããšã¯ãPerformance Observer APIã®æã匷åãªå¿çšäŸã®äžã€ã§ãããããããæž¬å®ããæ¹æ³ãèŠãŠãããŸãããã
Largest Contentful Paint (LCP) ã®ã¢ãã¿ãªã³ã°
LCPã¯èªã¿èŸŒã¿ããã©ãŒãã³ã¹ã枬å®ããŸããããã¯ãããŒãžèªã¿èŸŒã¿ã®ã¿ã€ã ã©ã€ã³äžã§ã¡ã€ã³ã³ã³ãã³ããããããèªã¿èŸŒãŸããæç¹ã瀺ããŸããè¯å¥œãªLCPã¹ã³ã¢ã¯2.5ç§ä»¥äžã§ãã
LCPèŠçŽ ã¯ããŒãžã®èªã¿èŸŒã¿äžã«å€ããããšããããŸããæåã¯èŠåºããLCPèŠçŽ ãããããŸããããåŸã§ãã倧ããªç»åãèªã¿èŸŒãŸããŠæ°ããLCPèŠçŽ ã«ãªãããšããããŸãããããPerformance Observerãå®ç§ã§ããçç±ã§ãâã¬ã³ããªã³ã°ããããã³ã«ãããããã®æœåšçãªLCPåè£ãéç¥ããŠãããŸãã
// LCPãç£èŠããæçµçãªå€ããã°ã«åºåãã let lcpValue = 0; const lcpObserver = new PerformanceObserver((entryList) => { const entries = entryList.getEntries(); // æåŸã®ãšã³ããªãææ°ã®LCPåè£ const lastEntry = entries[entries.length - 1]; lcpValue = lastEntry.startTime; console.log(`LCPãæŽæ°ãããŸãã: ${lcpValue.toFixed(2)}ms`, lastEntry.element); }); lcpObserver.observe({ type: 'largest-contentful-paint', buffered: true }); // ãŠãŒã¶ãŒãã€ã³ã¿ã©ã¯ã·ã§ã³ãè¡ããšæ°ããLCPåè£ã®ãã£ã¹ãããã忢ããããšãããããã // ãŠãŒã¶ãŒã®ã€ã³ã¿ã©ã¯ã·ã§ã³åŸã«ãªãã¶ãŒããŒãåæããã®ãè¯ãç¿æ £ã§ãã // window.addEventListener('beforeunload', () => lcpObserver.disconnect());
buffered: trueã®äœ¿çšã«æ³šæããŠãã ãããããã¯ãobserve()ã¡ãœãããåŒã³åºããã*å*ã«èšé²ããããšã³ããªãå«ããããã«ãªãã¶ãŒããŒã«æç€ºããéèŠãªãªãã·ã§ã³ã§ããããã«ãããåæã®LCPã€ãã³ããèŠéãã®ãé²ããŸãã
First Input Delay (FID) ãš Interaction to Next Paint (INP) ã®ã¢ãã¿ãªã³ã°
ãããã®ã¡ããªãã¯ã¯ã€ã³ã¿ã©ã¯ãã£ããã£ã枬å®ããŸãããŠãŒã¶ãŒãæåã«ããŒãžãšå¯Ÿè©±ããããšãããšãã®äœéšãå®éåããŸãã
First Input Delay (FID) ã¯ããŠãŒã¶ãŒãæåã«ããŒãžãšå¯Ÿè©±ããæïŒäŸïŒãã¿ã³ãã¯ãªãã¯ïŒããããã©ãŠã¶ãå®éã«ãã®ã€ã³ã¿ã©ã¯ã·ã§ã³ã«å¿çããŠã€ãã³ããã³ãã©ãåŠçãå§ãããŸã§ã®æéãæž¬å®ããŸããè¯å¥œãªFIDã¯100ããªç§ä»¥äžã§ãã
Interaction to Next Paint (INP) ã¯ã2024幎3æã«FIDã«ä»£ãã£ãŠã³ã¢ãŠã§ããã€ã¿ã«ãšãªã£ããããæ°ããå æ¬çãªã¡ããªãã¯ã§ããFIDã*æå*ã®ã€ã³ã¿ã©ã¯ã·ã§ã³ã®*é å»¶*ã®ã¿ã枬å®ããã®ã«å¯ŸããINPã¯ããŒãžã®ã©ã€ããµã€ã¯ã«å šäœã«ããã*ãã¹ãŠ*ã®ãŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ã®*ç·ã¬ã€ãã³ã·*ãè©äŸ¡ããæãæªããã®ãå ±åããŸããããã«ãããå šäœçãªå¿çæ§ã®ããè¯ãå šäœåãåŸãããŸããè¯å¥œãªINPã¯200ããªç§ä»¥äžã§ãã
'first-input'ãšã³ããªã¿ã€ãã䜿çšããŠFIDãç£èŠã§ããŸãïŒ
// FIDãç£èŠãã const fidObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { const fid = entry.processingStart - entry.startTime; console.log(`FID: ${fid.toFixed(2)}ms`); // æåã®å ¥åãå ±åããããåæãã fidObserver.disconnect(); } }); fidObserver.observe({ type: 'first-input', buffered: true });
INPã®ç£èŠã¯ãã€ãã³ãã®å šæéãèŠããããå°ãè€éã«ãªããŸãã'event'ãšã³ããªã¿ã€ããç£èŠããæç¶æéãèšç®ããæãé·ããã®ã远跡ããŸãã
// INPç£èŠã®ç°¡ç¥åãããäŸ let worstInp = 0; const inpObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { // INPã¯ã€ãã³ãã®æç¶æé const inp = entry.duration; // çŸåšã®ææªå€ãããé·ãã€ã³ã¿ã©ã¯ã·ã§ã³ã«ã®ã¿é¢å¿ããã if (inp > worstInp) { worstInp = inp; console.log(`æ°ããææªã®INP: ${worstInp.toFixed(2)}ms`); } } }); inpObserver.observe({ type: 'event', durationThreshold: 16, buffered: true }); // durationThresholdã¯ãéåžžã«çããããããéèŠã§ãªãã€ãã³ããé€å€ããã®ã«åœ¹ç«ã¡ãŸãã
Cumulative Layout Shift (CLS) ã®ã¢ãã¿ãªã³ã°
CLSã¯èŠèŠçãªå®å®æ§ã枬å®ããŸãããŠãŒã¶ãŒãäºæããªãã¬ã€ã¢ãŠãã®ããïŒèŠåãªãã«ããŒãžäžã®ã³ã³ãã³ããç§»åããã€ã©ã€ã©ããäœéšïŒãã©ããããã®é »åºŠã§çµéšããããå®éåããã®ã«åœ¹ç«ã¡ãŸããè¯å¥œãªCLSã¹ã³ã¢ã¯0.1以äžã§ãã
ã¹ã³ã¢ã¯ãåã ã®ãã¹ãŠã®ã¬ã€ã¢ãŠãã·ããã¹ã³ã¢ã®éèšã§ããPerformance Observerã¯ãåã·ãããçºçãããã³ã«å ±åãããããããã§ã¯äžå¯æ¬ ã§ãã
// åèšCLSã¹ã³ã¢ãç£èŠããã³èšç®ãã let clsScore = 0; const clsObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { // ãŠãŒã¶ãŒå ¥åã«ãã£ãŠåŒãèµ·ããããã·ããã¯ã«ãŠã³ãããããªã if (!entry.hadRecentInput) { clsScore += entry.value; console.log(`çŸåšã®CLSã¹ã³ã¢: ${clsScore.toFixed(4)}`); } } }); clsObserver.observe({ type: 'layout-shift', buffered: true });
hadRecentInputããããã£ã¯éèŠã§ãããŠãŒã¶ãŒã®ã¢ã¯ã·ã§ã³ïŒã¡ãã¥ãŒãå±éãããã¿ã³ãã¯ãªãã¯ãããªã©ïŒã«å¿çããŠçºçããæ£åœãªã¬ã€ã¢ãŠãã·ãããé€å€ããã®ã«åœ¹ç«ã¡ããããã¯CLSã¹ã³ã¢ã«ã«ãŠã³ããããã¹ãã§ã¯ãããŸããã
ã³ã¢ãŠã§ããã€ã¿ã«ãè¶ ããŠïŒãã®ä»ã®åŒ·åãªãšã³ããªã¿ã€ã
ã³ã¢ãŠã§ããã€ã¿ã«ã¯çŽ æŽãããåºçºç¹ã§ãããPerformance Observerã¯ããã«å€ãã®ããšãç£èŠã§ããŸããããã§ã¯ãä»ã«éåžžã«äŸ¿å©ãªãšã³ããªã¿ã€ããããã€ã玹ä»ããŸãã
ãã³ã°ã¿ã¹ã¯ã®è¿œè·¡ïŒ`longtask`ïŒ
Long Tasks APIã¯ãã¡ã€ã³ã¹ã¬ããã50ããªç§ä»¥äžå æããã¿ã¹ã¯ãå ¬éããŸããã¡ã€ã³ã¹ã¬ãããããžãŒç¶æ ã®éãããŒãžã¯ãŠãŒã¶ãŒå ¥åã«å¿çã§ããªãããããããã¯åé¡ãšãªããé å»¶ãããªãŒãºãããããªäœéšã«ã€ãªãããŸãããããã®ã¿ã¹ã¯ãç¹å®ããããšã¯ãINPãæ¹åããããã®éµã§ãã
// ãã³ã°ã¿ã¹ã¯ãç£èŠãã const longTaskObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { console.log(`ãã³ã°ã¿ã¹ã¯ãæ€åº: ${entry.duration.toFixed(2)}ms`); // 'attribution'ããããã£ã¯ããã³ã°ã¿ã¹ã¯ã®åå ãæããŠãããããšããã console.log('åž°å±:', entry.attribution); } }); longTaskObserver.observe({ type: 'longtask', buffered: true });
ãªãœãŒã¹ã¿ã€ãã³ã°ã®åæïŒ`resource`ïŒ
ã¢ã»ãããã©ã®ããã«èªã¿èŸŒãŸããŠããããçè§£ããããšã¯ãããã©ãŒãã³ã¹ãã¥ãŒãã³ã°ã®åºæ¬ã§ãã'resource'ãšã³ããªã¿ã€ãã¯ãDNSã«ãã¯ã¢ãããTCPæ¥ç¶ãã³ã³ãã³ãããŠã³ããŒãæéãªã©ãããŒãžäžã®ãã¹ãŠã®ãªãœãŒã¹ã«é¢ãã詳现ãªãããã¯ãŒã¯ã¿ã€ãã³ã°ããŒã¿ãæäŸããŸãã
// ãªãœãŒã¹ã¿ã€ãã³ã°ãç£èŠãã const resourceObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { // èªã¿èŸŒã¿ã®é ãç»åãèŠã€ãã if (entry.initiatorType === 'img' && entry.duration > 500) { console.warn(`èªã¿èŸŒã¿ã®é ãç»åãæ€åº: ${entry.name}`, `æèŠæé: ${entry.duration.toFixed(2)}ms`); } } }); // ãã®ã¹ã¯ãªãããå®è¡ãããåã«èªã¿èŸŒãŸããã¢ã»ããããã£ããããããã«ã // ãªãœãŒã¹ã¿ã€ãã³ã°ã«ã¯'buffered: true'ãã»ãŒåžžã«å¿ èŠã§ãã resourceObserver.observe({ type: 'resource', buffered: true });
ã«ã¹ã¿ã ããã©ãŒãã³ã¹ããŒã¯ã®æž¬å®ïŒ`mark`ãš`measure`ïŒ
æã«ã¯ãã¢ããªã±ãŒã·ã§ã³åºæã®ããžãã¯ã®ããã©ãŒãã³ã¹ã枬å®ããå¿ èŠããããŸããUser Timing APIã䜿çšãããšãã«ã¹ã¿ã ã®ã¿ã€ã ã¹ã¿ã³ããäœæãããããã®éã®æç¶æéãæž¬å®ã§ããŸãã
- performance.mark('start-operation'): 'start-operation'ãšããååã®ã¿ã€ã ã¹ã¿ã³ããäœæããŸãã
- performance.mark('end-operation'): å¥ã®ã¿ã€ã ã¹ã¿ã³ããäœæããŸãã
- performance.measure('my-operation', 'start-operation', 'end-operation'): 2ã€ã®ããŒã¯éã®æž¬å®ãäœæããŸãã
Performance Observerã¯ããããã®ã«ã¹ã¿ã ã®'mark'ããã³'measure'ãšã³ããªããªãã¹ã³ã§ããŸããããã¯ãJavaScriptãã¬ãŒã ã¯ãŒã¯ã§ã®ã³ã³ããŒãã³ãã®ã¬ã³ããªã³ã°æéããéèŠãªAPIåŒã³åºããšãã®åŸã®ããŒã¿åŠçã®æç¶æéãªã©ã®ã¿ã€ãã³ã°ããŒã¿ãåéããã®ã«æé©ã§ãã
// ã¢ããªã±ãŒã·ã§ã³ã³ãŒãå : performance.mark('start-data-processing'); // ... äœããã®è€éãªããŒã¿åŠç ... performance.mark('end-data-processing'); performance.measure('data-processing-duration', 'start-data-processing', 'end-data-processing'); // ç£èŠã¹ã¯ãªããå : const customObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntriesByName('data-processing-duration')) { console.log(`ã«ã¹ã¿ã æž¬å® '${entry.name}': ${entry.duration.toFixed(2)}ms`); } }); customObserver.observe({ entryTypes: ['measure'] });
é«åºŠãªæŠå¿µãšãã¹ããã©ã¯ãã£ã¹
ãããã§ãã·ã§ãã«ãªæ¬çªç°å¢ã§Performance Observer APIã广çã«äœ¿çšããããã«ã¯ããããã®ãã¹ããã©ã¯ãã£ã¹ãèæ ®ããŠãã ããã
- åžžã«`buffered: true`ãæ€èšãã: 'resource'ã'paint'ã'largest-contentful-paint'ã®ããã«ãããŒãžèªã¿èŸŒã¿ã®æ©ã段éã§çºçããå¯èœæ§ã®ãããšã³ããªã¿ã€ãã®å Žåãbufferedãã©ã°ã䜿çšããããšã¯ãããããèŠéããªãããã«äžå¯æ¬ ã§ãã
- ãã©ãŠã¶ã®ãµããŒãã確èªããïŒ çŸä»£ã®ãã©ãŠã¶ã§ã¯åºããµããŒããããŠããŸããã䜿çšããåã«ãã®ååšã確èªããããšã¯åžžã«è³¢æã§ãããŸããç¹å®ã®ãã©ãŠã¶ã§ã©ã®ãšã³ããªã¿ã€ãããµããŒããããŠãããã確èªããããšãã§ããŸãã
- if ('PerformanceObserver' in window && PerformanceObserver.supportedEntryTypes.includes('longtask')) { // ãã³ã°ã¿ã¹ã¯ã«å¯ŸããŠPerformanceObserverãå®å šã«äœ¿çšã§ãã }
- ããŒã¿ãåæãµãŒãã¹ã«éä¿¡ããïŒ ããŒã¿ãã³ã³ãœãŒã«ã«ãã°åºåããããšã¯éçºã«ã¯æé©ã§ãããå®éã®ç£èŠã®ããã«ã¯ãã®ããŒã¿ãéèšããå¿ èŠããããŸããã¯ã©ã€ã¢ã³ããããã®ãã¬ã¡ããªãéä¿¡ããæè¯ã®æ¹æ³ã¯ãnavigator.sendBeacon() APIã䜿çšããããšã§ããããã¯ãå°éã®ããŒã¿ããµãŒããŒã«éä¿¡ããããã«èšèšãããéããããã³ã°ã®ã¡ã«ããºã ã§ãããããŒãžãã¢ã³ããŒãããããšãã§ã確å®ã«æ©èœããŸãã
- é¢å¿äºããšã«ãªãã¶ãŒããŒãã°ã«ãŒãåããïŒ è€æ°ã®ãšã³ããªã¿ã€ãã«åäžã®ãªãã¶ãŒããŒã䜿çšããããšãã§ããŸãããç°ãªãé¢å¿äºïŒäŸïŒã³ã¢ãŠã§ããã€ã¿ã«çšããªãœãŒã¹ã¿ã€ãã³ã°çšãã«ã¹ã¿ã ã¡ããªãã¯çšïŒã«å¥ã ã®ãªãã¶ãŒããŒãäœæããæ¹ããã³ãŒãã®å¯èªæ§ãšä¿å®æ§ãåäžããŸãã
- ããã©ãŒãã³ã¹ãªãŒããŒããããçè§£ããïŒ ãã®APIã¯éåžžã«äœãªãŒããŒãããã«ãªãããã«èšèšãããŠããŸããããããéãèšç®ãè¡ãéåžžã«è€éãªã³ãŒã«ããã¯é¢æ°ã¯ãããã©ãŒãã³ã¹ã«åœ±é¿ãäžããå¯èœæ§ããããŸãããªãã¶ãŒããŒã®ã³ãŒã«ããã¯ã¯ç°¡æœã§å¹ççã«ä¿ã¡ãŸããããéãåŠçã¯ãŠã§ãã¯ãŒã«ãŒã«å§è²ããããçã®ããŒã¿ãããã¯ãšã³ãã«éä¿¡ããŠããã§åŠçããŸãã
çµè«ïŒããã©ãŒãã³ã¹ç¬¬äžã®æåãç¯ã
Performance Observer APIã¯åãªãããŒã«ä»¥äžã®ãã®ã§ããããŠã§ãããã©ãŒãã³ã¹ãžã®ã¢ãããŒãæ¹æ³ã«ãããæ ¹æ¬çãªå€åã§ããããã¯ãç§ãã¡ãåå¿çã§äžåºŠããã®æž¬å®ãããäžçäžã®ãŠãŒã¶ãŒã®çã®åçãªäœéšãåæ ãããç©æ¥µçã§ç¶ç¶çãªç£èŠãžãšç§»è¡ãããŸããã³ã¢ãŠã§ããã€ã¿ã«ããã³ã°ã¿ã¹ã¯ããªãœãŒã¹ã¿ã€ãã³ã°ãã«ã¹ã¿ã ã¡ããªãã¯ã確å®ã«å¹ççã«ãã£ããã£ããæ¹æ³ãæäŸããããšã§ãéçºè ã倿°ã®ãŠãŒã¶ãŒã«åœ±é¿ãäžããåã«ããã©ãŒãã³ã¹ã®ããã«ããã¯ãç¹å®ãã解決ã§ããããã«ããŸãã
Performance Observer APIã®æ¡çšã¯ãããããéçºããŒã ã«ãããŠããã©ãŒãã³ã¹ç¬¬äžã®æåãç¯ãããã®éèŠãªã¹ãããã§ããéèŠãªãã®ã枬å®ã§ããã°ãéèŠãªãã®ãæ¹åã§ããŸãã仿¥ãããããã®ãªãã¶ãŒããŒããããžã§ã¯ãã«çµ±åãå§ããŸããããäžçäžã®ã©ãã«ãããŠãŒã¶ãŒããããéããããã¹ã ãŒãºã§ãããå¿«é©ãªäœéšã«æè¬ããã§ãããã