--- tags: 科技資訊 --- # 透過瀏覽器機制從預先載入響應式圖片提升效能 本篇文章將基於「瀏覽器方」所提供的原生解法來看看要如何透過預先載入(Preload)技術,來提升網頁效能。 ## 預先載入圖片 考慮到商業需求,有時候產品網站需要利用圖片來突顯產品特色,或者用視覺效果來吸引消費者。在這種無法避免使用圖片的情境下,如何同時確保網站效能就變成了開發者的重要挑戰。 ### 實作方法 透過 `link` 元素中的 `rel="preload"` 我們主動告知瀏覽器希望能夠盡快載入的關鍵資源: ```htmlembedded <link rel="preload" as="image" href="important.png"> ``` 而從 Netkwork 觀測 Waterfall,可以觀察到在正常載入下未特別處理的頁面 request 順序原先如下: **正常載入**  - index.html - a.js - important.png 而經由 Preload 處理過後的圖片 request 比起原先的順序還要更早。 **經由 Preload 處理**  - index.html - important.png - a.js 經過 Preload 處理後,除了圖片加載時間在總體來說變得更快之外,對於 Core Web Vitals 中的指標 Largest Contentful Paint(LCP) 也有顯著影響,這是因為 LCP 最主要是觀測第一畫面(First View)中的最大資源載入時間,而圖片本身即為 LCP 關注的「候選對象」之一,基本上前幾名大概率都偏離不了圖片資源,也就是說加快圖片載入的同時也是在提升 LCP 指標。 ### 要注意之處 要小心的是我們並非所有圖片都是需要進行 Preload 的,也就是說除了載入畫面原先的圖片之外,需要卷軸下滑等等才能瀏覽到的圖片基本上我們會透過類似 LazyLoad 的方式來進行處理。 要透過瀏覽器原生的實作可在 `img` 元素上加上 `loading="lazy"` 部分: ```htmlembedded <img src="notInFirstView.jpg" loading="lazy" alt="..." /> ``` 另一種常見策略是透過 JavaScript 去控制,比方透過 `Intersection Observer API` 去偵測該元素是否進入瀏覽視野來判定是否真的要去要求(request)圖片資源。 ```javascript! // 寫下監聽邏輯 const lazyImageObserver = new IntersectionObserver(function(entries, observer) { entries.forEach(function(entry) { // 監聽邏輯:是否進入視野 (當然也可以設定距離多少) if (entry.isIntersecting) { let lazyImage = entry.target lazyImage.src = lazyImage.dataset.src lazyImage.classList.remove('lazyload') lazyImageObserver.unobserve(lazyImage) } }) }) // 取得目前所有 class name 含有 lazyload 的圖片 const lazyImages = [].slice.call(document.querySelectorAll('img.lazyload')) // 加上監聽邏輯 lazyImages.forEach(function(lazyImage) { lazyImageObserver.observe(lazyImage) }) ``` --- ## 預先載入響應式圖片 而上述提及的預先載入方法其實主要是用於 img 元素只有單張的圖片,然後專案架構如果是設計 RWD 的情況下,為了效能考量我們有時候會在 img 元素上加上 `srcset` 來控制應該載入哪種尺寸的圖片,來優化效能。 ```htmlembedded <img src="responsive.jpg" srcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w" sizes="50vw" alt="…"> ``` 這時候如果我們想透過 Preload 機制的話就需要改寫成這樣: ```htmlembedded <link rel="preload" as="image" href="responsive.jpg" imagesrcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w" imagesizes="50vw"> ``` 接著就可以依照原先響應式邏輯預載入圖片。 ### 要注意之處 另外,有另外一種處理方式,也是常用來處理響應式圖片的寫法之一,就是透過 CSS 中的 background-image 中的 `image-set` 來處理: ```css img { background-image: image-set( "cat.png" 1x, "cat-2x.png" 2x); } ``` 但是透過這種做法的缺點是瀏覽器可能要處理頁面中的其他 css 後可能才會發現有其設定,所以如果是用來處理 first view 中的圖片對於效能來說可能相較就比較差一些。 那以上就是透過瀏覽器方提供的機制,來預先載入響應式圖片提升效能的做法,如果你有其他方式也歡迎投稿或留言! <p style="text-align:center">--End--</p> {%hackmd H18MwJyDTk-tZXoBgxht0Q %}
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up