新聞中心
當(dāng)今的網(wǎng)站上充斥著大量媒體資源,例如圖片和視頻。圖片約占網(wǎng)站平均通信量的 50%。然而這些圖片中的大部分都沒(méi)機(jī)會(huì)進(jìn)入用戶(hù)的視野,因?yàn)樗鼈兾挥诰W(wǎng)站頁(yè)面的頭版之外。

創(chuàng)新互聯(lián)建站專(zhuān)注為客戶(hù)提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、彝良網(wǎng)絡(luò)推廣、微信小程序開(kāi)發(fā)、彝良網(wǎng)絡(luò)營(yíng)銷(xiāo)、彝良企業(yè)策劃、彝良品牌公關(guān)、搜索引擎seo、人物專(zhuān)訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)建站為所有大學(xué)生創(chuàng)業(yè)者提供彝良建站搭建服務(wù),24小時(shí)服務(wù)熱線(xiàn):18980820575,官方網(wǎng)址:www.cdcxhl.com
看到本文標(biāo)題你會(huì)問(wèn)「懶加載是什么東西?」CSS-Tricks 網(wǎng)站中有非常多的探討懶加載的文章,其中有一篇非常詳盡的《用 JavaScript 花式實(shí)現(xiàn)懶加載的指南文檔》。簡(jiǎn)言之,我們要討論的是一種延遲網(wǎng)絡(luò)資源加載的機(jī)制,在該機(jī)制下,網(wǎng)頁(yè)內(nèi)容按需加載,或者說(shuō)得更直白些,當(dāng)網(wǎng)頁(yè)內(nèi)容進(jìn)入用戶(hù)視野時(shí)再觸發(fā)加載。
這樣做有什么好處?壓縮初始頁(yè)面的體積以提升加載速度;免于為用戶(hù)根本不會(huì)看到的內(nèi)容浪費(fèi)網(wǎng)絡(luò)請(qǐng)求。
如果你之前讀過(guò)關(guān)于懶加載的其他文章,你就會(huì)明白,我們必須借助各種不同的方式才能實(shí)現(xiàn)懶加載功能。而當(dāng)原生 HTML 用 loading 特性支持懶加載功能后,那可就柳暗花明又一村了。目前僅有 Chrome 支持 loading 特性,但有望全面開(kāi)花。Chrome 近期正在開(kāi)發(fā)和測(cè)試對(duì)原生懶加載特性的支持功能,預(yù)計(jì)在 2019 年 9 月初發(fā)布的 Chrome 77 版本中面世。
非原生的方法
截至目前,我們這群開(kāi)發(fā)者仍需要用 JavaScript(不論是借助第三方庫(kù)還是自己從零手寫(xiě))實(shí)現(xiàn)懶加載功能。大多數(shù)懶加載庫(kù)的原理都是:
服務(wù)端返回的 HTML 響應(yīng)中包含一個(gè)初始的、不帶 src 特性的 img 元素,這樣瀏覽器就不會(huì)加載任何數(shù)據(jù)。而圖片的鏈接地址放在 img 元素的其他特性上,例如 data-src。
然后,載入一個(gè)懶加載庫(kù),運(yùn)行它。
該懶加載庫(kù)時(shí)刻記錄用戶(hù)滾動(dòng)頁(yè)面的行為,告訴瀏覽器加載即將滾入用戶(hù)視野的圖片。加載方式是把 data-src 特性的值賦給原本為空的 src 特性。
長(zhǎng)期以來(lái),我們都在用這種方式實(shí)現(xiàn)懶加載。但這并不是理想的實(shí)現(xiàn)方式。
該方式的顯著問(wèn)題就是,要展示網(wǎng)站頁(yè)面,得經(jīng)過(guò)好幾個(gè)關(guān)鍵步驟??偣惨齻€(gè)步驟,還必須得按順序執(zhí)行:
- 加載初始的 HTML 響應(yīng)內(nèi)容
- 加載懶加載庫(kù)
- 加載圖片
如果把這樣的懶加載技術(shù)應(yīng)用到頭版中的圖片上,頁(yè)面在加載期間會(huì)發(fā)生閃爍,因?yàn)橐婚_(kāi)始繪制的時(shí)候,頁(yè)面中沒(méi)有圖片(閃爍發(fā)生于第 1 步還是第 2 步之后,取決于載入庫(kù)的腳本用的是 defer 還是 async),懶加載庫(kù)生效后,圖片才姍姍來(lái)遲。這還會(huì)給用戶(hù)造成網(wǎng)頁(yè)加載速度緩慢的錯(cuò)覺(jué)。
另外,懶加載庫(kù)本身也是對(duì)帶寬和 CPU 算力的占用。而且別忘了,如果用戶(hù)禁用了 JavaScript(都已經(jīng)2019年了,這種情況我們不予考慮,你說(shuō)對(duì)吧?),那么懶加載庫(kù)是行不通的。
哦對(duì)了,那些依賴(lài) RSS 來(lái)發(fā)布內(nèi)容的網(wǎng)站(如 CSS-Tricks)又該怎么辦呢?如果初始的頁(yè)面中不載入圖片,那么 RSS 版本的頁(yè)面就始終不會(huì)顯示圖片。
凡此種種,不一而足。
原生懶加載前來(lái)救駕!
如前文所說(shuō),Chromium 開(kāi)發(fā)團(tuán)隊(duì)和 Google Chrome 開(kāi)發(fā)團(tuán)隊(duì)從 Chrome 75 開(kāi)始,裝載 loading 特性支持的原生懶加載功能。關(guān)于該特性及其值,我們稍后再討論,還是先在瀏覽器里啟用這個(gè)功能來(lái)一探究竟吧。
啟用原生懶加載功能
從 Chrome 75 開(kāi)始,我們可以切換兩個(gè)開(kāi)關(guān)來(lái)手動(dòng)啟用懶加載功能。預(yù)計(jì)從 Chrome 77(計(jì)劃于 2019 年 9 月發(fā)布)開(kāi)始,該功能就會(huì)是默認(rèn)開(kāi)啟的了。
- 在 Chromium 或 Chrome Canary 打開(kāi) chrome://flags。
- 搜索關(guān)鍵詞 lazy。
- 把「Enable lazy image loading」和「Enable lazy frame loading」兩項(xiàng)都激活。
- 點(diǎn)擊屏幕右下角的按鈕重啟瀏覽器。
↑↑↑ 示意圖:Google Chrome 中的原生懶加載功能開(kāi)關(guān) ↑↑↑
打開(kāi) JavaScript 控制臺(tái)(按 F12 鍵),看看懶加載功能是否已經(jīng)成功激活。如果成功激活,你會(huì)看到如下警告信息:
[Intervention] Images loaded lazily and replaced with placeholders. Load events are deferred.(圖片以懶惰方式加載并替換為占位符。加載事件被延遲。)
都搞定了嗎?那就一起深入了解 loading 吧。
loading 特性
img 和 iframe 元素都支持 loading 特性。切記, loading 特性的值不是讓瀏覽器嚴(yán)格執(zhí)行的命令,而是幫助瀏覽器自己決定是否要懶加載圖片或者框架。
下面會(huì)介紹 loading 特性可取的三個(gè)值。在下文中的每張圖片下面,你都可以看到一張表格,其中列著每個(gè)圖片資源的加載時(shí)序。范圍請(qǐng)求(譯者注:原文用詞為 Range response,疑似筆誤)指的是一種預(yù)檢圖片局部的請(qǐng)求,用來(lái)確定圖片文件的大?。▍⒁?jiàn)詳細(xì)原理)。如果該列有內(nèi)容,證明瀏覽器成功發(fā)出了范圍請(qǐng)求。
請(qǐng)注意 startTime 列,該列表明了在 DOM 解析后,圖片的加載被推遲了多長(zhǎng)時(shí)間。你可以使用強(qiáng)制刷新(CTRL + Shift + R)重新觸發(fā)范圍請(qǐng)求。
默認(rèn)值: auto
↑↑↑ 示意圖:自動(dòng)加載的車(chē)模照 ↑↑↑
| 度量 / 請(qǐng)求 | #1 |
|---|---|
| encodedBodySize | 20718 bytes |
| decodedBodySize | 20718 bytes |
| transferSize | 0 bytes |
| startTime | 54 ms |
| requestStart | 592 ms |
| responseStart | 596 ms |
| responseEnd | 601 ms |
| timeToFirstByte | 4 ms |
| downloadDuration | 5 ms |
把 loading 設(shè)為 auto(或者將其置空:loading=""),可以讓瀏覽器自己決定是否懶加載圖片。決定是否懶加載要考慮很多因素,例如平臺(tái)、是否處于 Data Saver 模式(譯者注:Chrome 已于 2019 年 5 月 6 日廢棄了該功能)、網(wǎng)絡(luò)狀況、圖片大小、是圖片還是 iframe 以及 CSS 的 display 屬性等等。(關(guān)于考慮這些因素的原因,參見(jiàn)此處。)
急脾氣的值: eager
↑↑↑ 示意圖:急切加載的急豹圖 ↑↑↑
| 度量 / 請(qǐng)求 | #1 |
|---|---|
| encodedBodySize | 24019 bytes |
| decodedBodySize | 24019 bytes |
| transferSize | 0 bytes |
| startTime | 54 ms |
| requestStart | 592 ms |
| responseStart | 600 ms |
| responseEnd | 605 ms |
| timeToFirstByte | 7 ms |
| downloadDuration | 5 ms |
eager 告訴瀏覽器這張圖片需要立即加載。如果加載已經(jīng)被延遲了(比如初始值為 lazy,后來(lái)用 JavaScript 改成了 eager),那么瀏覽器也應(yīng)該立即加載圖片。
懶洋洋的值: lazy
↑↑↑ 示意圖:懶加載的懶貓圖 ↑↑↑
| 度量 / 請(qǐng)求 | #1 |
|---|---|
| encodedBodySize | 12112 bytes |
| decodedBodySize | 12112 bytes |
| transferSize | 0 bytes |
| startTime | 54 ms |
| requestStart | 593 ms |
| responseStart | 599 ms |
| responseEnd | 604 ms |
| timeToFirstByte | 6 ms |
| downloadDuration | 5 ms |
lazy 告訴瀏覽器此圖片應(yīng)該懶加載。懶加載到底有多「懶」,這應(yīng)該由瀏覽器來(lái)解釋?zhuān)f(shuō)明文檔表明,懶加載始于用戶(hù)將頁(yè)面滾動(dòng)到圖片附近之時(shí),意即當(dāng)圖片即將進(jìn)入視野時(shí)加載。
loading 特性的原理
與基于 JavaScript 的懶加載庫(kù)不同,原生懶加載功能使用了一種預(yù)檢請(qǐng)求來(lái)獲取圖片文件的前 2048 字節(jié)數(shù)據(jù)。根據(jù)預(yù)先取得的數(shù)據(jù),瀏覽器會(huì)試著確定該圖片的大小,便于在完整圖片的位置插入一個(gè)隱形的占位符,防止加載過(guò)程中頁(yè)面發(fā)生閃爍現(xiàn)象。
在第一個(gè)(如果圖片大小小于 2 KB,一個(gè)預(yù)檢請(qǐng)求就夠了)或第二個(gè)請(qǐng)求完成后,完整圖片一加載完畢,其 load 事件就會(huì)解除監(jiān)聽(tīng)。請(qǐng)注意,如果沒(méi)有完成第二個(gè)請(qǐng)求,那么 load 事件可能會(huì)一直綁定著。
從今以后,瀏覽器因獲取圖片而發(fā)出的請(qǐng)求的數(shù)量可能會(huì)翻倍。每張圖片對(duì)應(yīng)兩個(gè)請(qǐng)求:先是范圍請(qǐng)求,再是完整請(qǐng)求。要確保你的服務(wù)器支持 HTTP Range:0-2047 請(qǐng)求頭,而響應(yīng)狀態(tài)碼要用 206(部分內(nèi)容),防止整個(gè)圖片被傳送兩次。
每個(gè)用戶(hù)都會(huì)發(fā)送大量的后續(xù)請(qǐng)求,因此 Web 服務(wù)器對(duì) HTTP/2 協(xié)議的支持變得越來(lái)越重要。
現(xiàn)在我們來(lái)聊聊延遲的內(nèi)容。Chrome 瀏覽器的渲染引擎 Blink 采用啟發(fā)式技術(shù)來(lái)確定哪些內(nèi)容應(yīng)該延遲加載、延遲多久。Scott Little 在他的設(shè)計(jì)文檔中全面地列出了確定延遲策略的條件。下面是確定延遲對(duì)象的簡(jiǎn)短策略:
- 所有平臺(tái)中設(shè)置了 loading="lazy" 的圖片和框架
- 瀏覽器為 Android 系統(tǒng)中的 Chrome,啟用了 Data Saver 模式;并且滿(mǎn)足下列條件的圖片:
- 設(shè)置了 loading="auto" 或 loading=""
- width 和 height 特性的值都不小于 10 px
- 非 JavaScript 插入的圖片
- 滿(mǎn)足下列條件的框架:
- 設(shè)置了 loading="auto" 或 loading=""
- 來(lái)自第三方(與被插入頁(yè)面的域名或協(xié)議不同)
- 寬、高都大于 4 像素(防止將微型跟蹤框架一并延遲加載)
- 未設(shè)置 display:none 或 visibility:hidden(防止將跟蹤框架一并延遲加載)
- 未用負(fù)坐標(biāo)值定位于屏幕區(qū)域以外
帶有 srcset 特性的響應(yīng)式圖片
對(duì)于帶有 srcset 特性的響應(yīng)式圖片,原生懶加載同樣有效。srcset 特性提供了一系列圖片文件供瀏覽器選用。根據(jù)用戶(hù)的屏幕尺寸、設(shè)備像素比、網(wǎng)絡(luò)狀況等因素,瀏覽器會(huì)選取最適合情境的圖片。像 tiny.pictures這樣的圖片優(yōu)化 CDN 可以實(shí)時(shí)提供備選圖片,無(wú)需后端開(kāi)發(fā)。
瀏覽器支持
在撰寫(xiě)本文時(shí),還沒(méi)有瀏覽器默認(rèn)支持原生懶加載功能。但就像之前說(shuō)的,Chrome 從 77 版本開(kāi)始會(huì)默認(rèn)開(kāi)啟懶加載。除此之外,目前還沒(méi)有瀏覽器廠商宣稱(chēng)支持該功能。(Edge 將是個(gè)例外,因?yàn)樗磳⑥D(zhuǎn)為 Chromium 內(nèi)核。)
你可以用幾行 JavaScript 代碼檢查支持情況:
- if("loading" in HTMLImageElement.prototype) {
- // 支持。
- } else {
- // 不支持。你可能需要引入懶加載庫(kù)(下文已列出)。
- }
參見(jiàn) CodePen 中 Erk Struwe(@erkstruwe)的代碼示例:瀏覽器原生懶加載支持探測(cè)器
以模糊圖片自動(dòng)回退到 JavaScript 方案
多數(shù)基于 JavaScript 的懶加載庫(kù)都有一個(gè)炫酷的功能:模糊占位圖片(LQIP)。該功能基本上利用了這個(gè)原理:即使后來(lái) src 特性的值會(huì)被另外的 URL 替換掉,瀏覽器還是會(huì)在一開(kāi)始就立刻加載 img 元素。這樣,我們可以在頁(yè)面載入時(shí)先加載一個(gè)不清晰的小圖片,之后再用完整圖片代替它。
現(xiàn)在我們可以利用這個(gè)功能,在不支持懶加載的瀏覽器中模擬原生懶加載的 2 KB 范圍請(qǐng)求,以期實(shí)現(xiàn)模糊占位圖片相同的效果。
參見(jiàn) CodePen 中 Erk Struwe(@erkstruwe)的代碼示例:針對(duì)原生懶加載的 JavaScript 回退方案,以及模糊占位圖片功能
總結(jié)
這個(gè)新功能著實(shí)讓我激動(dòng)。原生懶加載功能的發(fā)布近在眼前,會(huì)對(duì)全球互聯(lián)網(wǎng)通信產(chǎn)生非凡影響。就算它只能改變啟發(fā)式技術(shù)的一小部分,老實(shí)說(shuō)我仍不明白為何人們不給予足夠的關(guān)注。
想想吧,隨著在不同的 Chrome 平臺(tái)中逐漸推廣、 auto 值成為默認(rèn)選項(xiàng),世界上最流行的瀏覽器即將對(duì)視口外的圖片和框架應(yīng)用懶加載技術(shù)。決堤般的通信量會(huì)大面積擊潰那些健壯性不足的網(wǎng)站,而且,蜂擁而至的圖片探測(cè)請(qǐng)求也會(huì)傷及網(wǎng)絡(luò)服務(wù)器。
接下來(lái)遭殃的就是追蹤技術(shù): 假設(shè)那些深受信賴(lài)的追蹤像素和追蹤框架都無(wú)法加載,那么數(shù)據(jù)分析領(lǐng)域及其周邊產(chǎn)業(yè)將面臨被動(dòng)局面。我們只能希望他們千萬(wàn)別驚慌失措,千萬(wàn)別給每個(gè)圖片都加上 loading="eager"這項(xiàng)偉大功能,這樣添加 loading 特性根本不是為了服務(wù)網(wǎng)站用戶(hù),實(shí)在暴殄天物。他們更應(yīng)該改寫(xiě)代碼,以便于被啟發(fā)式技術(shù)識(shí)別為追蹤像素。
Web 開(kāi)發(fā)者、數(shù)據(jù)分析經(jīng)理和運(yùn)營(yíng)經(jīng)理應(yīng)該立即檢查自己的網(wǎng)站,確保前端支持原生懶加載、后端支持范圍請(qǐng)求和 HTTP/2 協(xié)議。
萬(wàn)一原生懶加載功能出現(xiàn)問(wèn)題,或者你想把圖片加載優(yōu)化到極致(包括自動(dòng)支持 WebP、模糊占位圖片等等),圖片優(yōu)化 CDN 能助你一臂之力。更多內(nèi)容參見(jiàn) tiny.pictures!
當(dāng)前題目:深入理解圖片和框架的原生懶加載功能
本文URL:http://m.fisionsoft.com.cn/article/dpepcdg.html


咨詢(xún)
建站咨詢(xún)
