懶加載,顧名思義,在當前網頁,滑動頁面到能看到圖片的時候再加載圖片javascript
故問題拆分紅兩個:html
本篇文章原文地址: 如何實現圖片懶加載,另存到 個人每日一題,歡迎 starjava
clientTop
,offsetTop
,clientHeight
以及 scrollTop
各類關於圖片的高度做比對git
這些高度都表明了什麼意思?程序員
這我之前有多是知道的,那時候我比較單純,喜歡死磕。我如今想通了,背不過的東西就不要背了github
因此它有一個問題:複雜瑣碎很差理解!web
僅僅知道它靜態的高度還不夠,咱們還須要知道動態的面試
如何動態?監聽 window.scroll
事件後端
<img data-src="shanyue.jpg">
複製代碼
首先設置一個臨時屬性 data-src
,控制加載時使用 src
代替 data-src
瀏覽器
改進一下
引入一個新的 API, Element.getBoundingClientRect()
方法返回元素的大小及其相對於視口的位置。
那如何判斷圖片出如今了當前視口呢,根據示例圖示意,代碼以下,這個就比較好理解了,就能夠很容易地背會(就能夠愉快地去面試了)。
// clientHeight 表明當前視口的高度
img.getBoundingClientRect().top < document.documentElement.clientHeight
複製代碼
監聽 window.scroll
事件也優化一下
加個節流器,提升性能。工做中通常使用 lodash.throttle
就能夠了,萬能的 lodash
啊!
_.throttle(func, [wait=0], [options={}])
複製代碼
再改進一下
方案二使用的方法是: window.scroll
監聽 Element.getBoundingClientRect()
並使用 _.throttle
節流
一系列組合動做太複雜了,因而瀏覽器出了一個三合一事件: IntersectionObserver
API,一個可以監聽元素是否到了當前視口的事件,一步到位!
事件回調的參數是 IntersectionObserverEntry 的集合,表明關因而否在可見視口的一系列值
其中,entry.isIntersecting
表明目標元素可見
const observer = new IntersectionObserver((changes) => {
// changes: 目標元素集合
changes.forEach((change) => {
// intersectionRatio
if (change.isIntersecting) {
const img = change.target
img.src = img.dataset.src
observer.unobserve(img)
}
})
})
observer.observe(img)
複製代碼
固然,IntersectionObserver
除了給圖片作懶加載外,還能夠對單頁應用資源作預加載。
如在 next.js v9
中,會對視口內的資源作預加載,能夠參考 next 9 production optimizations
<Link href="/about">
<a>關於山月</a>
</Link>
複製代碼
瀏覽器以爲懶加載這事能夠交給本身作,大家開發者加個屬性就行了。實在是...!
<img src="shanyue.jpg" loading="lazy">
複製代碼
不過目前瀏覽器兼容性不太好,關於 loading
屬性的文章也能夠查看 Native image lazy-loading for the web!
總結一下
window.scroll
監聽各類 top
與 height
並使用 _.throttle
節流,可是很差理解各類 top
與 hegith
window.scroll
監聽 getBoundingClientRect
並使用 _.throttle
節流,沒有一個統一事件,相對複雜IntersectionObserver
,瀏覽器推出了一個事件,方便簡單img.loading=lazy
,瀏覽器直接給你解決,開發者直接標註屬性我是山月,一個喜歡跑步與登山的程序員,我會按期分享全棧文章在我的公衆號中,歡迎交流