因為很多圖片在沒載入時他在網頁上會沒有占空間,導致加載圖片後會大幅度影響到網頁版面配置,後來我將圖片容器設置固定大小來讓版面固定
LCP 載入時間太久,解決這個問題很棘手,在使用lighthouse分析web vitals之後,我得知LCP time的組成以及他的bottle neck在哪裡
total:
Phase | % of LCP | Timing |
---|---|---|
TTFB | 10% | 460 ms |
Load Delay | 55% | 2,460 ms |
Load Time | 30% | 1,340 ms |
Render Delay | 5% | 240 ms |
LCP time | 100% | 4500ms |
分析工具提供了這些數據,還告訴我LCP是哪個元件,可以看到其中load Delay佔了最大一部分,我的case來說是heroSlide中的一張圖片,而這張圖片的url需要透過request 後端server拿到movie data之後才會拿到,可想而知可能就是這個環節最花時間因為要等待伺服器回傳圖片url才能進行後面的渲染,而我的問題其實滿簡單
useEffect(() => {
const getMedias = async () => {
const { response, err } = await mediaApi.getList({
mediaType,
mediaCategory,
page: 1,
})
dispatch(setGlobalLoading(false))
if (response) {
setMovies(response.results)
setLoopEnabled(response.results.length > 1)
}
if (err) toast.error(err.errors)
}
const getGenres = async () => {
dispatch(setGlobalLoading(true))
const { response, err } = await genreApi.getList({ mediaType })
// console.log(response.genres)
if (response) {
setGenres(response.genres)
getMedias()
}
if (err) {
toast.error(err.errors)
setGlobalLoading(false)
}
}
getGenres()
}, [mediaType, mediaCategory, dispatch])
可以看到一個很大的問題是明明呼叫movie API的參數中不需要Genres的response data,為什麼還需要等待gernes執行完呢,對沒錯所以我馬上想到我應該要同時呼叫這兩個api
useEffect(() => {
const fetchData = async () => {
dispatch(setGlobalLoading(true))
const [genreResponse, mediaResponse] = await Promise.all([
genreApi.getList({ mediaType }),
mediaApi.getList({ mediaType, mediaCategory, page: 1 }),
])
dispatch(setGlobalLoading(false))
if (genreResponse.response) {
setGenres(genreResponse.response.genres)
} else {
toast.error(genreResponse.err.errors)
}
if (mediaResponse.response) {
setMovies(mediaResponse.response.results)
setLoopEnabled(mediaResponse.response.results.length > 1)
} else {
toast.error(mediaResponse.err.errors)
}
}
fetchData()
}, [mediaType, mediaCategory, dispatch])
在使用Promise.all方法之後,我開心地想著應該會減少LCP時間吧,可是
Phase | % of LCP | Timing | |
---|---|---|---|
TTFB | 7% | 320 ms | |
Load Delay | 46% | 2,060 ms | |
Load Time | 43% | 1,930 ms | |
Render Delay | 4% | 190 ms | |
LCP time | 100% | 4500ms |
後來發現是我沒有把他build起來難怪performance很低
import axios from 'axios';
const get = async url => {
const response = await axios.get(url, {
headers: {
Accept: 'application/json', // 指定接受 JSON 格式的響應數據
'Accept-Encoding': 'identity', // 禁止響應數據壓縮
},
});
return response.data; // 返回響應中的數據部分
};
export default { get };