纯JavaScript实现图片延时加载的两种方案

作者:霁月

时间:2026-10-29

浏览:618

针对长页面图片加载导致的性能问题,本文介绍两种纯JavaScript实现图片延时加载(懒加载)的方案。第一种方案利用自定义属性csii_src延迟赋值src;第二种方案通过class状态切换及alt属性预存路径实现。文章详细解析了核心逻辑、代码实现及注意事项,旨在帮助开发者优化页面加载速度并节省流量。

文章目录

背景与需求分析

近期整理了一些以往开发中实用的插件,特此分享。

现代网页内容日益丰富,尤其是淘宝、京东等大型电商网站,首页作为核心流量入口,其加载性能至关重要。

在近期开发的某银行网站项目中,首页曝光位置竞争激烈,各业务部门对首页布局提出了多样化需求。

为满足各方需求,技术负责人指出首页资源体积过大,要求必须进行性能优化与精简。

首要措施是压缩图片大小,若仍不达标,则需采用更高效的加载策略。对于长页面中当前视口未显示区域的图片,可以暂缓加载,这既能节省用户流量,也能降低服务器带宽成本。

方案一:自定义属性延迟加载

核心思路是计算图片在页面中的位置坐标,若图片顶部距离大于当前屏幕可视高度,则暂不加载,否则立即显示。

实现初始隐藏的关键在于使用浏览器不识别的自定义属性,例如<img csii_src="1.png">。当触发加载条件时,通过element.src=element.getAttribute("csii_src");将自定义属性值赋给src,从而触发图片加载。


function lazyLoad() {
var map_element = {};
var element_obj = [];
var download_count = 0;
var last_offset = -1;
var doc_body = null;
var doc_element = null;
var lazy_load_tag = [];
function initVar(tags) {
doc_body = document.body;
doc_element = document.compatMode == 'BackCompat' ? doc_body
: document.documentElement;
lazy_load_tag = tags || [ "img", "iframe" ];
}
;
function initElementMap() {
for ( var i = 0, len = lazy_load_tag.length; i < len; i++) {
var el = document.getElementsByTagName(lazy_load_tag[i]);
for ( var j = 0, len2 = el.length; j < len2; j++) {
if (typeof (el[j]) == "object"
&& el[j].getAttribute("csii_src")) {
element_obj.push(el[j]);
}
}
}

for ( var i = 0, len = element_obj.length; i < len; i++) {
var o_img = element_obj[i];
var t_index = getAbsoluteTop(o_img);
if (map_element[t_index]) {
map_element[t_index].push(i);
} else {
var t_array = [];
t_array[0] = i;
map_element[t_index] = t_array;
download_count++;
}
}

}
;
function initDownloadListen() {
if (!download_count)
return;
/*var offset = (window.MessageEvent && !document.getBoxObjectFor) ? doc_body.scrollTop
: doc_element.scrollTop;*/
var offset;
if(os.firefox){
offset = doc_element.scrollTop;
}else{
offset = doc_body.scrollTop;
}

var visio_offset = offset + doc_element.clientHeight;
if (last_offset == visio_offset) {
// setTimeout(initDownloadListen, 200);
return;
}
last_offset = visio_offset;
var visio_height = doc_element.clientHeight;
var img_show_height = visio_height + offset + 20;
for ( var key in map_element) {
if (img_show_height > key) {
var t_o = map_element[key];
var img_vl = t_o.length;
for ( var l = 0; l < img_vl; l++) {
element_obj[t_o[l]].src = element_obj[t_o[l]]
.getAttribute("csii_src");
}
delete map_element[key];
download_count--;
}
}
// setTimeout(initDownloadListen, 200);
}
;
function getAbsoluteTop(element) {
if (arguments.length != 1 || element == null) {
return null;
}
var offsetTop = element.offsetTop;
while (element = element.offsetParent) {
offsetTop += element.offsetTop;
}
return offsetTop;
}
function init(tags) {
initVar(tags);
initElementMap();
initDownloadListen();
$(window).scroll(function(){
initDownloadListen();
});
}
;
init();
}

该方案存在局限性:页面结构必须固定,且图片高度需预先设定,否则无法准确计算图片距离顶部的偏移量。

方案二:Class状态切换与占位图

接下来介绍另一种常见的实现方式。


<!-- 
      var temp = -1;//用来判断是否是向下滚动(向上滚动就不需要判断延迟加载图片了) 
       
      window.onscroll = function() { 
      var imgElements = document.getElementsByTagName("img"); 
      var lazyImgArr = new Array(); 
      var j = 0; 
      for(var i=0; i<imgElements.length; i++) { 
       if(imgElements[i].className == "lazy"){ 
        lazyImgArr[j++] = imgElements[i]; 
       } 
      } 
     
              var scrollHeight = document.body.scrollTop;//滚动的高度 
      var bodyHeight = document.body.offsetHeight;//body(页面)可见区域的总高度 
      if(temp < scrollHeight) {//为true表示是向下滚动,否则是向上滚动,不需要执行动作。 
       
       for(var k=0; k<lazyImgArr.length; k++) { 
       var imgTop = lazyImgArr[k].offsetTop;//1305(图片纵坐标) 
       if((imgTop - scrollHeight) <= bodyHeight) { 
        lazyImgArr[k].src = lazyImgArr[k].alt; 
        lazyImgArr[k].className = "notlazy" 
               } 
      } 
       
      temp = scrollHeight; 
     } 
       
    }; 
       
// -->

该方案在<img>标签中将src设置为一个极小的占位图片路径,并将alt属性设置为真实图片路径。当用户滚动至图片可视区域时,将src替换为alt的值以加载真实图片。同时,通过给标签添加值为lazy的class来标记待加载图片,加载完成后将class值改为notlazy,以此区分已加载和未加载状态。

代码中的注释已详细说明逻辑,欢迎提出改进建议。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章