http://my.oschina.net/HerrySun/blog/658657
今天看到了一章关于图片预加载的博文,其代码如下:
function loadImage(url, callback)
{
var img = new Image(); //创建一个Image对象,实现图片的预下载
img.src = url;
if (img.complete)
{ // 如果图片已经存在于浏览器缓存,直接调用回调函数
callback(img);
return; // 直接返回,不用再处理onload事件
}
img.onload = function () { //图片下载完毕时异步调用callback函数。
callback(img);
};
};
在网上搜索了一下相关文章,大体上都是这个思路。
这个方法功能是ok的,但是有一些隐患。
1. 创建了一个临时匿名函数来作为图片的onload事件处理函数,形成了闭包。
相信大家都看到过ie下的内存泄漏模式的文章,其中有一个模式就是循环引用,而闭包就有保存外部运行环境的能力(依赖于作用域链的实现),所以img.onload这个函数内部又保存了对img的引用,这样就形成了循环引用,导致内存泄漏。(这种模式的内存泄漏只存在低版本的ie6中,打过补丁的ie6以及高版本的ie都解决了循环引用导致的内存泄漏问题)。
2. 只考虑了静态图片的加载,忽略了gif等动态图片,这些动态图片可能会多次触发onload。
要解决上面两个问题很简单,其实很简单,代码如下:
img.onload = function () { //图片下载完毕时异步调用callback函数。
img.onload = null;
callback(img);
};
这样既能解决内存泄漏的问题,又能避免动态图片的事件多次触发问题。
在一些相关博文中,也有人注意到了要把img.onload 设置为null,只不过时机不对,大部分文章都是在callback运行以后,才将img.onload设置为null,这样虽然能解决循环引用的问题,但是对于动态图片来说,如果callback运行比较耗时的话,还是有多次触发的隐患的。隐患经过上面的修改后,就消除了,但是这个代码还有优化的余地:
if (img.complete) { // 如果图片已经存在于浏览器缓存,直接调用回调函数
callback(img);
return; // 直接返回,不用再处理onload事件
}
关于这段代码,看相关博文里的叙述,原因如下:
经过对多个浏览器版本的测试,发现ie、opera下,当图片加载过一次以后,如果再有对该图片的请求时,由于浏览器已经缓存住这张图片了,不会再发起一次新的请求,而是直接从缓存中加载过来。对于 firefox和safari,它们试图使这两种加载方式对用户透明,同样会引起图片的onload事件,而ie和opera则忽略了这种同一性,不会引起图片的onload事件,因此上边的代码在它们里边不能得以实现效果。
确实,在ie,opera下,对于缓存图片的初始状态,与firefox和safari,chrome下是不一样的(有兴趣的话,可以在不同浏览器下,测试一下在给img的src赋值缓存图片的url之前,img的状态),但是对onload事件的触发,却是一致的,不管是什么浏览器。产生这个问题的根本原因在于,img的src赋值与 onload事件的绑定,顺序不对(在ie和opera下,先赋值src,再赋值onload,因为是缓存图片,就错过了onload事件的触发)。应该先绑定onload事件,然后再给src赋值,代码如下:
function loadImage(url, callback) {
var img = new Image(); //创建一个Image对象,实现图片的预下载
img.onload = function(){
img.onload = null;
callback(img);
}
img.src = url;
}
这样内存泄漏,动态图片的加载问题都得到了解决,而且也以统一的方式,实现了callback的调用
分享到:
相关推荐
本篇文章介绍了javascript图片懒加载与预加载的分析,详细的介绍了懒加载和预加载的问题,有需要的可以了解一下。
有很多种方法来实现图片的预加载,通常大部分使用Javascript让事情滚动。不要再受Javascript预载的束缚了吧,用CSS你就可以毫不麻烦的预载你的图片,需要的朋友可以了解下
图片是Web页面的重要组成部分,也是我们进行项目优化时的重中之重。图片的一种优化技术--图片预加载,并了解在什么情况下去使用它,以获得更好的用户体验。
由于图片加载慢,导致用户体验特别差,本文将介绍一种图片预加载技术,需要了解的朋友可以参考下
预加载一张图片 var promise = Walter ( 'picture.jpg' ) ; 预加载多张图片 var promise = Walter ( [ 'picture1.jpg' , 'picture2.jpg' ] ) ; 活动 var promise = Walter ( [ 'picture1.jpg' , 'picture2.jpg' ]...
本篇文章主要介绍了微信小程序实现图片懒加载的示例代码,实现的原理是通过页面预加载图片,对用户体验度会有一定的提高,具有一定的参考价值,有兴趣可以了解一下
我们来学习一种名为图像预装载(image preloading)的小技巧来提高图像访问速度,一些浏览器试图通过在本地缓存中保存这些图片来解决此问题,感兴趣的朋友可以了解下
1.重新改写数据库访问底层,使优化后的页面加载速度比原来提升50% 2.系统添加有问必答栏目,将客户对酒店预订相关问题分页列出 3.对问题和回答添加顶帖功能 4.修正酒店详细信息浏览页的酒店问答标签中,查找不生效的...
扫码体验后台上传图片资源较大,加载较慢,不会P图,请谅解。使用说明目前小程序内部使用的云API的token,以及我的小程序APPID我也上传了。下载SRC目录全部代码,在微信web开发工具打开就能查看和修改,暂不知道会有...
2、如何加载图片数据,并处理数据。 3、如果将标签转为onehot编码 4、如何使用数据增强。 5、如何使用mixup。 6、如何切分数据集。 7、如何加载预训练模型。 原文链接:...
personal blog 合抱之木,生于毫末;...Intersection Observer + Vue指令 优雅实现图片懒加载 【性能优化】图片优化——总览 事件循环机制 Event-Loop及其延伸 深入了解HTTP/2的前世今生以及Web性能优化总结
jQuery产品360度旋转展示代码,支持预加载,能够快速全面的的预览产品的图片,主要原理是利用多张图片按顺序播放实现,本段代码兼容目前最新的各类主流浏览器,是一款非常优秀的特效源码。 运行效果图:——————...
复制代码代码如下:src :视频的属性poster:视频封面,没有播放时显示的图片preload:预加载autoplay:自动播放loop:循环播放controls:浏览器自带的控制条width:视频宽度height:视频高度 html 代码 复制代码代码...
页面上预加载了五个按钮,这些按钮将生成单击后预渲染的演员的gif。 还可以通过表单添加演员,并在单击按钮时为其生成gif。 最多可加载10个Gif,首先它们将显示为静态图片。 单击Gif时,它将播放,也可以在单击时...
狂欢 go-blurhash是算法的纯Go实现, 和其他Fediverse软件使用它来实现快速预加载占位符图像以及隐藏敏感媒体的方式。 了解更多信息。 tl; dr: BlurHash是图像占位符的紧凑表示。 该库允许生成给定图像的BlurHash,...
隔夜项目:代理 Project Overnight是一个完整的物业租赁平台,允许用户通过描述和图像来了解该物业,进行预订并浏览评论。 相关项目 ... 请参考“相关项目”部分中的链接,以了解如何加载各个模块。
后台界面采用EasyUI框架,前台界面采用Bootstrap框架,用户浏览器和服务器全程几乎采用jquery异步加载技术! 它实现了常见字段比如字符串,整型,浮点型,日期型,图片型和文件型的添删改查,查询条件采用多条件组合...
解决方案摘要:在客户端加载一组图像。 对于基于简单算法输入的每个密码,将显示其中一张图像。 图片是根据密码计算得出的,因此只有在用户更改密码时,图片才会更改。 因此,显示的图像对用户来说将变得熟悉,直到...
对于上述每个页面,谷歌地图都会加载目的地,评论和价格范围的图片。 这个网站是有益的,因为它在一个网站上包含了他们通过城市所需要知道的一切。 最近搜索的城市将保存到本地存储中,并自动加载除酒店外的所有...
【有详细的过程,图片演示,及代码】【历时两周完成!】 实训目的 1、理解C#WinForm程序设计的风格,能设计合理的C#项目文件夹结构和公共类,注重代码的重用性,养成良好的标识符命名和代码编写习惯; 2、熟练掌握...