圖片延遲加載的原理是什么?
圖片延遲加載的原理就是先不設(shè)置img的src屬性,等合適的時(shí)機(jī)(比如滾動、滑動等)再把圖片真實(shí)url放到img的src屬性上。
過多的圖片會嚴(yán)重影響網(wǎng)頁的加載速度,移動網(wǎng)絡(luò)下的流量消耗巨大,延遲加載幾乎是標(biāo)配。
圖片延遲加載的使用場景有哪些?
- 好奇心日報(bào)首頁和列表頁都有很多固定寬高的圖片。
- 好奇心日報(bào)文章詳情頁的圖片,這些圖片需要自適應(yīng)寬度且保持寬高比(防止頁面抖動)。
固定寬高延遲加載
這個(gè)比較簡單,設(shè)置好固定寬高,直接使用最簡單的延遲加載即可
淘寶mobile首頁的延遲加載有個(gè)點(diǎn)做得特別好,滾動結(jié)束后只加載當(dāng)前視窗可見的圖片,不會加載滾動超過視窗的圖片,也不會加載還沒滾動到的視窗圖片。
非固定寬高的延遲加載
目前大概有兩種方案,各有優(yōu)劣,具體看情況使用:
第一種方案使用padding-top或者padding-bottom來實(shí)現(xiàn)固定寬高比。優(yōu)點(diǎn)是純css方案,缺點(diǎn)是html冗余,對輸出到第三方不友好
<div style="padding-top:75%">
<img data-src="" alt="" class="lazyload">
<div>
第二種方案在頁面初始化階段利用ratio設(shè)置實(shí)際寬高值,優(yōu)點(diǎn)是html干凈,對輸出到第三方友好,缺點(diǎn)是依賴js,理論上會至少抖動一次
<img data-src="" alt="" class="lazyload" data-ratio="0.75">
更進(jìn)一步結(jié)合srcset
除了上面說的延遲加載,我們可以更進(jìn)一步的引入srcset,通過設(shè)置srcset來保證加載最匹配的圖片,這樣對于一倍屏,二倍屏,三倍屏來說,可以做到不浪費(fèi)流量且效果最好。
都有哪些延遲加載開源方案?
jquery_lazyload
依賴于jquery
<img class="lazy" data-original="img/example.jpg" width="640" height="480">
// 初始化
$("img.lazy").lazyload();
lazysizes 推薦
原生js,不依賴于jquery/zepto
自動監(jiān)測可能發(fā)生變化的lazyload節(jié)點(diǎn),不需要額外初始化
支持響應(yīng)式圖片srcset
性能高,改善SEO
// 引入js文件
<script src="lazysizes.min.js" async=""></script>
// 非響應(yīng)式 例子
<img data-src="image.jpg" class="lazyload" />
// 響應(yīng)式 例子,自動計(jì)算合適的圖片
<img
data-sizes="auto"
data-src="image2.jpg"
data-srcset="image1.jpg 300w,
image2.jpg 600w,
image3.jpg 900w" class="lazyload" />
// iframe 例子
<iframe frameborder="0"
class="lazyload"
allowfullscreen=""
data-src="http://www.youtube.com/embed/ZfV-aYdU4uE">
</iframe>
lazyload
依賴jquery/zepto
<!-- 直接賦予圖片寬高 -->
<img class="lazy" data-original="img/example.jpg" width="640" height="480">
<!-- 或:通過css賦予圖片寬高 -->
<style>
.lazy{width:640px;height:480px;}
</style>
<img class="lazy" data-original="img/example.jpg">
<!-- 或:自適應(yīng)寬度的圖片樣式(常用于移動端) -->
<style>
.lazy{width:100%;height:0;padding-top:75%;background-size:100%;}
/* 假設(shè)高寬比為 480:640,即75%,并使用背景圖的方式將圖片鋪在padding-top區(qū)域內(nèi)
(padding的百分比是寬度的百分比而不是高度的,即使是padding-top|padding-bottom) */
</style>
<div class="lazy" data-original="img/example.jpg"><div>
<!-- 請參閱examples/enabled_image_full_width.html -->
<!-- 初始化 -->
$(".lazy").lazyload();
微信如何實(shí)現(xiàn)延遲加載?
研究了微信延遲加載的代碼,還解決了一個(gè)問題,那就是常見于移動端的自適應(yīng)寬度的延遲加載,即根據(jù)情況具體計(jì)算寬高。
// 源碼
<img
data-s="300,640"
data-type="jpeg"
data-src="http://mmbiz.qpic.cn/mmbiz/meG6Vo0MeviaLibiaARRszfMpiaXtejcktPB2fK6uP13R4RS9Y7fHtk5bUd7A9R9zRyZ1nupW8ZVjHwBiaZUa3SkcPg/0?wx_fmt=jpeg"
data-ratio="0.8003597122302158"
data-w=""
/>
// 解析后的代碼
<img
data-s="300,640"
data-type="jpeg"
data-src="http://mmbiz.qpic.cn/mmbiz/meG6Vo0MeviaLibiaARRszfMpiaXtejcktPBLbT37dSYzNyhwDTiac0WiaribF0Vt7I3Zd7AG9xXSCUoch61KicnYnfqIw/0?wx_fmt=jpeg"
data-ratio="0.8003597122302158"
data-w=""
src="http://mmbiz.qpic.cn/mmbiz/meG6Vo0MeviaLibiaARRszfMpiaXtejcktPBLbT37dSYzNyhwDTiac0WiaribF0Vt7I3Zd7AG9xXSCUoch61KicnYnfqIw/640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy=1&retryload=1"
style="width: 414px !important; visibility: visible !important; height: 331.349px !important;"
/>
/* 其中
data-s:表示可選的圖片尺寸大小
data-type:表示圖片類型
data-src:表示圖片鏈接
data-ratio:表示長寬比
*/
由于源碼是壓縮模式的,做簡單的猜測如下:
- 對于延遲加載,微信采用的模式和正常的延遲加載的模式類似,即用data-src存儲真實(shí)的圖片鏈接
- 為了解決移動端的自適應(yīng)寬度的問題,微信存儲了長寬比,然后進(jìn)入頁面就計(jì)算在不同設(shè)備里的真實(shí)寬高,并設(shè)置在style
其他問題?
- 接入第三方平臺的網(wǎng)頁怎么處理?
由于好奇心日報(bào)的文章會輸出到第三方平臺,比如今日頭條/一點(diǎn)資訊等平臺,這些平臺對html都有一定的規(guī)范。這時(shí)候就需要后臺在輸出之前對html做一些轉(zhuǎn)換。
為了簡單起見,類似<div class="lazy" data-original="img/example.jpg"><div>的方案不太適合讓后臺轉(zhuǎn)換,所以微信這種動態(tài)計(jì)算方法可以借鑒。 - 怎么處理響應(yīng)式圖片?
響應(yīng)式圖片能夠根據(jù)當(dāng)前屏幕分辨率加載最匹配的圖片,能夠因地制宜,詳見圖片響應(yīng)式解決方案 - 方案有了,回頭追加一篇具體實(shí)踐踩坑的博文