懒加载
什么是懒加载
懒加载也叫做延迟加载。
当访问一个页面的时候,先把 img 元素或者其他元素的背景图片换成一张大小为 1*1 的图片的路径(俗称:占位符),只有当图片出现在浏览器的可视区域内的时候,才设置图片真正的路径,让图片显示出来。
为什么要使用懒加载
很多页面,内容丰富,页面很长,图片较多。比如各种商城页面,这些页面图片数量多,而且比较大,少说百来 k,多则上兆,要是页面载入就一次性的加载完毕,估计我们等的黄花菜都凉了。
懒加载的原理
比如:页面中的 img 图片,如果没有 src 属性,浏览器就不会发送请求下载图片,只有通过 js 设置了图片的 src 属性,浏览器才会真正的去发送请求。
懒加载的原理就是先把页面中所有的图片统一使用一张占位符进行占位,把真正的 url 存储在‘data-url’属性里,需要的时候再拿出来,给图片设置上。
懒加载优点
页面加载速度快,可以减轻服务器的压力,节约流量,用户体验好。
代码实现步骤
- 首先不要将图片地址放在 src 中,而是放在其他属性,如 data-url 中。
- 页面加载完成后,根据 scrolltop 的值判断图片是否出现在用户的视野范围内,如果在,将 data-url 中的路径拿出来,设置在 src 上。
- 在滚动事件中重复判断图片是否进入视野,如果进入,则将 data-original 属性中的值取出存放到 src 属性中。
代码实现
<img src="" class="image-item" lazyload="true" data-original="./1.jpg" />
<img src="" class="image-item" lazyload="true" data-original="./1.jpg" />
<!-- 可以复制多行 -->
<img src="" class="image-item" lazyload="true" data-original="./1.jpg" />
<img src="" class="image-item" lazyload="true" data-original="./1.jpg" />
//获取可视区高度
var viewHeight = document.documentElement.clientHeight;
function lazyload() {
var eles = document.querySelectorAll("img[data-original][lazyload]");
Array.prototype.forEach.call(eles, function(item, index) {
var rect;
if (item.dataset.original === "") return;
// 用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置
rect = item.getBoundingClientRect();
// 当元素距离底部的距离大于0并且距离顶部的距离小于可是区高度时,设置src属性。
if (rect.bottom >= 0 && rect.top < viewHeight) {
!(function() {
var img = new Image();
img.src = item.dataset.original;
img.onload = function() {
item.src = img.src;
};
//移除属性,下次不再遍历
item.removeAttribute("data-original");
item.removeAttribute("lazyload");
})();
}
});
}
//刚开始还没滚动屏幕时,要先触发一次函数,初始化首页的页面图片
lazyload();
document.addEventListener("scroll", lazyload);
预加载
什么是预加载
预加载就是提前加载图片,当用户需要查看时,直接从本地缓存中渲染。
为什么要使用预加载
图片预先的加载到浏览器中,访问者可以很顺利的在你的网站上冲浪,并且享受到极快的加载速度。这对图片画廊及图片占据很大比例的网站来说是十分有利的。他保证了图片的快速,无缝的发布,帮助用户在你的网站获得更好的体验。
实现预加载的方法
使用 css 和 js
#preload-01 { background: url(http://qiniu.cllgeek.com/react02.png) no-repeat -9999px -9999px; }
#preload-02 { background: url(http://qiniu.cllgeek.com/react03.png) no-repeat -9999px -9999px; }
#preload-03 { background: url(http://qiniu.cllgeek.com/react04.png no-repeat -9999px -9999px; }
css 加载的图片会同页面的其他内容一起加载,增加了页面的整体加载时间.
function preloader() {
if (document.getElementById) {
document.getElementById("preload-01").style.background =
"url(http://qiniu.cllgeek.com/react02.png) no-repeat -9999px -9999px";
document.getElementById("preload-02").style.background =
"url(http://qiniu.cllgeek.com/react03.png) no-repeat -9999px -9999px";
document.getElementById("preload-03").style.background =
"url(http://qiniu.cllgeek.com/react04.png) no-repeat -9999px -9999px";
}
}
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != "function") {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
};
}
}
addLoadEvent(preloader);
使用 js
function preloader() {
if (document.images) {
var img1 = new Image();
var img2 = new Image();
var img3 = new Image();
img1.src = "http://qiniu.cllgeek.com/react02.png";
img2.src = "http://qiniu.cllgeek.com/react03.png";
img3.src = "http://qiniu.cllgeek.com/react04.png";
}
}
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != "function") {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
};
}
}
addLoadEvent(preloader);
预加载和懒加载的对比
概念
- 懒加载: 延迟加载,当达到某些条件时再加载图片。
- 预加载: 提前加载,当用户查看时从浏览器缓存中渲染。
技术本质
- 懒加载:缓解服务器前端的压力
- 预加载:增加服务器前端的压力
实现方式
- 懒加载
- 纯粹的延迟加载,使用 setTimeOut 或 setInterval 进行加载延迟.
- 条件加载,当符合某种条件,触发某些事件进行加载。
- 可视区加载,仅仅加载用户可以看到的区域,当滚动条滚动时,距离用户看到某张图片一定距离时开始加载,这样用户下拉时正好可以看到图片。
- 预加载
- css
- js
- ajax
常用的是 new Image();设置 src 进行预加载,再使用 onload 方法回调预加载完成事件。只要浏览器把图片下载到本地,同样的 src 就会使用缓存,当图片下载完之后会得到图片的宽和高。
意义
- 懒加载:主要目的是作为服务器前端的优化,减少请求数或延迟请求数
- 预加载:牺牲服务器前端性能,获得更好的用户体验。
你可能会用到的方法
- 屏幕可是窗口的大小:
原生方法
window.innerHeight 标准浏览器及 IE9+ ||
document.documentElement.clientHeight 标准浏览器及低版本的 IE 标准模式 ||
document.body.clientHeight 低版本混杂模式
jQuery 方法
$(window).height();
- 滚动条滚动的距离
原生方法:
window.pagYoffset 标准浏览器及 IE9+ ||
document.documentElement.scrollTop 兼容 ie 低版本的标准模式 ||
document.body.scrollTop 兼容混杂模式;
jQuery 方法:
$(document).scrollTop();
- 获取元素尺寸
$(o).width() = o.style.width;
$(o).innerWidth() = o.style.width+o.style.padding;
$(o).outerWidth() = o.offsetWidth = o.style.width+o.style.padding+o.style.border;
$(o).outerWidth(true) = o.style.width+o.style.padding+o.style.border+o.style.margin;
注意:
要使用原生的 style.xxx 方法获取属性,这个元素必须已经有内嵌的样式,如
;如果原先是通过外部或内部样式表定义 css 样式,必须使用 o.currentStyle[xxx] || document.defaultView.getComputedStyle(0)[xxx]来获取样式值。- 获取元素的位置信息
jQuery
$(o).offset().top 元素距离文档顶的距离
$(o).offset().left 元素距离文档左边缘的距离。
原生
getoffsetTop();
顺便提一下返回元素相对于第一个以定位的父元素的偏移距离,注意与上面偏移距的区别;
jQuery:position() // 返回一个对象
$(o).position().left = o.style.left;
$(o).position().top = o.style.top;