# Web Vitals
## First Contentful Paint(FCP)
* FCP measures how long it takes the browser to render the first piece of DOM content after a user navigates to your page
~~簡單來說就是當我們按下click或者是輸入URL,直到有一點點畫面渲染出來~~
![](https://i.imgur.com/Q8WalLA.png)
---
![](https://i.imgur.com/d7zMJ6j.png)
### How to improve FCP
* $$$$$$ 取決於你的網路頻寬
* 減少TTFB的回應時間
* CDN
* 壓縮CSS HTML JS
> **名詞解釋**:
FCP: First Contentful Paint is when the browser renders the first DOM element on the page
FP: The browser renders the first bytes of information
```javascript=
let hiddenTime = document.visibilityState === 'hidden' ? 0 : Infinity;
document.addEventListener('visibilitychange', (evt) => {
hiddenTime = Math.min(hiddenTime, evt.timeStamp);
}, { once: true })
const FCPobserver = new PerformanceObserver((entryList) => {
entryList.getEntriesByName('first-contentful-paint').forEach(entry => {
if (entry.startTime < hiddenTime) {
trackingData.fcp = entry.startTime;
console.log('Record: FCP', trackingData.fcp);
}
})
}).observe({ type: 'paint', buffered: true });
```
標準:
![](https://i.imgur.com/kU5fqd0.png)
## Largest Contentful Paint(LCP)
* Largest Contentful Paint is the metric that measures the time a website takes to show the user the largest content on the screen
* 一般來說image就是 Largest contentful,例如各item的圖片,主要的圖片以及廣告的圖
![](https://i.imgur.com/nRacBWO.jpg)
### How to improve LCP
* 圖片lazy load、JS與CSS的download機制
1. 透過intersectionObserver去lazy load image或者是根據screen size load 不同尺寸的image
2. 透過本身的`<img loading="lazy" />`
3. 小圖先用base64
4. JS使用`<script defer src="YouDontKnow"></script>`
![](https://i.imgur.com/SQqjyaj.png)
```javascript=
const observer = new PerformanceObserver((entryList) => {
const entries = entryList.getEntries();
entries.forEach(entry => {
trackingData.lcp = entry.startTime;
console.log('Record: LCP', trackingData.lcp);
})
}).observe({ type: 'largest-contentful-paint', buffered: true });
```
標準:
![](https://i.imgur.com/mwoX7oA.png)
## Cumulative Layout Shift(CLS)
* CLS is the unexpected shifting of webpage elements while the page is still downloading. The kinds of elements that tend to cause shift are fonts, images, videos, contact forms, buttons, and other kinds of content. -> 簡單來說就是位移網頁元素,最常見的就是廣告
```javascript=
const CLSobserver = new PerformanceObserver((entryList) => {
const entries = entryList.getEntries();
for (const entry of entries) {
if (!entry.hadRecentInput) {
trackingData.cls += entry.value;
console.log('Record: CLS', trackingData.cls);
}
}
}).observe({ type: 'layout-shift', buffered: true });
```
標準:
![](https://i.imgur.com/yAzfFBQ.png)
How to improve CLS
* 就先在原本要位移的地方先塞空白
## First Input Delay(FID)
FID measures the time from when a user first interacts with a page (i.e. when they click a link, tap on a button, or use a custom, JavaScript-powered control) to the time when the browser is actually able to begin processing event handlers in response to that interaction.
![](https://i.imgur.com/2Hr7xq0.png)
## Incremental Static Regeneration
official document: https://vercel.com/docs/concepts/next.js/incremental-static-regeneration
簡單就是在過去我們在更新SSG的內容(因為是不常變動的)就要rebuild,因為SSG的頁面就是在build time產生出來,但是這樣如果有小部分要更新就要一直rebuild
-> ISR就是解決這問題,用法很像react-query的data flow, data超過時間就會轉為stale的cache
如何使用,加上revalidate就好
```javascript=
export async function getStaticProps() {
const res = await axios('http://localhost:4000/blogs');
return {
props: {
posts: res.data,
},
revalidate: 1,
}
}
```
補充 -> ISR是在server side的階段所以可以在這時候存取DB的資料,但是DB直接存取會有格式上的問題,所以建議還是建立一個server
DEMO TIME