懒加载在一些图片繁多的网站很常见, 举个简单的例子, 淘宝的首页里有不少商品图片, 用户能够一直往下拉, 可是不少用户每每都下拉不了多少就跳转到别的地方了, 假如一次性把首页的全部图片都请求加载下来, 这会致使几个严重的问题:
javascript
将页面的图片的 src 设为 loading 图片的路径, 将真实路径存储起来, 同时给未加载的图片添加标记属性。
监听页面的滚动事件(这里最好作一下节流), 滚动时遍历未加载的图片, 获取图片距离可视区顶部的高度, 假如小于页面高度, 就将 src 替换真实的 url。css
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Lazyload 1</title>
</head>
<body>
<img src="images/loading.gif" data-src="images/1.png">
<img src="images/loading.gif" data-src="images/2.png">
<img src="images/loading.gif" data-src="images/3.png">
<img src="images/loading.gif" data-src="images/4.png">
<img src="images/loading.gif" data-src="images/5.png">
<img src="images/loading.gif" data-src="images/6.png">
<img src="images/loading.gif" data-src="images/7.png">
<img src="images/loading.gif" data-src="images/8.png">
<img src="images/loading.gif" data-src="images/9.png">
<img src="images/loading.gif" data-src="images/10.png">
<img src="images/loading.gif" data-src="images/11.png">
<img src="images/loading.gif" data-src="images/12.png">
<script>
class LazyLoad {
constructor(){
this.clientHeight = window.innerHeight // 可视区高度
this.initLoad() // 初始加载
this.bindScrollEvent()
}
initLoad(){
this.lazyLoad()
}
bindScrollEvent(){
let fn = this.throttle(() => {
this.lazyLoad()
}, 300) // 300ms可执行一次
document.addEventListener('scroll', fn)
}
lazyLoad(){
let images = document.querySelectorAll("img[data-src]")
Array.from(images).forEach((img) => {
let offsetTop = this.getPosition(img)
if(offsetTop < this.clientHeight){
img.src = img.getAttribute("data-src")
img.removeAttribute('data-src', '') // 每次删除已加载图片的 data-src 属性, 避免下次再遍历到, 提高性能
}
})
}
getPosition(el){
return el.getBoundingClientRect().top
}
throttle(fn, timeout){ // 节流
let perious = 0
return function(){
let now = +new Date()
let args = arguments
if(now - perious >= timeout){
perious = now
fn.apply(this, args)
}
}
}
}
let lazyLoadObj = new LazyLoad()
</script>
</body>
</html>
复制代码
预加载与懒加载相反, 懒加载是延迟加载, 在须要展现或用到的时候才加载
预加载是预先加载好后面须要用到的资源, 后面使用的时候直接去缓存里取。举个栗子, 好比一个网站的开场动画, 这些动画是由不少图片组成的, 假如不预先加载好, 那就会形成动画不流畅产生闪动白屏。
html
在 link 标签上设置 rel="prefetch" 能够实现预加载, 该方法兼容性还不太好。java
将图片放在 CSS 中加载, 但不显示跨域
#preload { background: url(http://domain.tld/image-01.png) no-repeat -9999px -9999px; }
复制代码
JS 实现预加载 js 文件和 css 文件时, 标签必须嵌入页面才会生效。浏览器
// CSS
var css = document.createElement('link');
css.type = "text/css";
css.rel = "stylesheet";
css.href = "http://domain.tld/preload.css";
document.body.appendChild(css)
// JS
var js = document.createElement("script");
js.type = "text/javascript";
js.src = "http://domain.tld/preload.js";
document.body.appendChild(js)
// img
new Image().src = "http://xxxx.com"
复制代码
Ajax 实现预加载比较好的一个点是, 不须要建立标签影响到页面, 可是可能会有跨域问题缓存
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://xxxx.js');
xhr.send('');
复制代码