JavaScript 的Image对象、图像渲染和浏览器缓存
来源:互联网 发布:网络火词2016 编辑:程序博客网 时间:2024/05/16 06:24
最近需要攻克一个难点就是:需要将1000张左右的图片制作成动画效果。
转载该篇博客只为研究
使用Javascript创建new Image()对象的最主要作用就是实现图片预加载。
预加载的实现很简单,百度谷歌一下会有很多相关的文章。其核心说到底也就两句话:
- var img = new Image();
- img.src = "my_image.jpg";
废话不多说,我们来做几个实验。用IE 9、Firefox 14、Chrome 21这三大主流引擎代表浏览器测试比较。详细的测试结果我就不列出来啦,各位自己可以去试一下。这里主要比较的是物理内存占用情况。
图片参数:1440*758px 17.4KB/每张 共100张 1.7MB
实验一:Image对象参照实验
利用100张同样尺寸和大小的图片创建100个Image对象作为参照。代码如下:
- var imgs = [];
- for(var i =0; i<100; i++){
- imgs[i] = new Image();
- imgs[i].src = "images/"+( i+1 + Math.pow(10,3)).toString().substr(1) + ".jpg";
- }
实验二:<img>标签参照实验 & 浏览器渲染
用img标签直接放出100张图片。
- $(function(){
- for(var i =0; i<100; i++){
- $("body").append('<img src="images/'+( i+1 + Math.pow(10,3)).toString().substr(1) + '.jpg">');
- }
- });
这个实验中,你可以发现非常有趣的一点。加载完100张图片之后,内存占用与实验一中相差无几,稍微大一些。而当你将页面向下翻,内存占用会不断升高。
为什么会升高呢?因为浏览器在将这些图片渲染到页面上。用about:memory命令在Firefox中查看详细的内存占用情况,就会发现,占用1.7MB的图片经过渲染之后会占用几十兆内存。经查资料并证实,浏览器渲染图片的内存占用大小只跟图片的长宽有关,跟图片文件的大小并没有关系。
实验三:Image对象preload图片,用<img>标签渲染
实验代码:
- <input type="button" value="change"/>
- <img src="" width="1440" height="758">
- <script>
- $(function(){
- var img = $("img")[0];
- var preload = [];
- var n = -1;
- for(var i =0; i<100; i++){
- preload[i] = new Image();
- preload[i].src = "images/"+( i+1 + Math.pow(10,3)).toString().substr(1) + ".jpg";
- }
- $("INPUT").click(function(){
- if( ++n<100 ){
- img.src = preload[n].src;
- }
- });
- });
- </script>
这个实验你会发现万恶的Firefox在每click一次后内存长几兆,然后就下不来了。IE也好不到哪里去。而Chrome的表现非常好,短时间内内存就降下来了。
查了许久,发现根本原因就在浏览器引擎本身对图片渲染的Cache处理方法不同。
Firefox会将页面中所有被渲染过的图片存在Cache中,占用浏览器进程的内存。以求页面浏览顺畅。但这个“看似”很棒的设计,却给我们造成了极大的不变。也就是说,如果要做一个类似http://360langstrasse.sf.tv/page/的很酷的网站,而且图片的原始尺寸非常大的话,Firefox和IE很容易就会崩溃。
这是一个难以由前端开发者用code来填补的问题。即使将load的所有Image对象全部释放掉,也没有任何办法清除它们被渲染之后占用的内存。在Mozilla官方网站上有人提交过相关的BUG:https://bugzilla.mozilla.org/show_bug.cgi?id=659220
这个时候,就有一个抉择摆在你的面前。减小图片尺寸or减少图片数量。实际上碰到这种情况的只有少数。很幸运,我就TMD碰到了,迫于第三方设计要求和限制,俺必须另寻出路突破重重阻碍。
第一个想到的是类似目前流行的瀑布流图片网站的做法,延迟加载。事实证明,这方法仅能加快页面的显示,给用户带来比较好的用户体验,但对Firefox/IE这种臃肿的浏览器并不能减少内存的占用。再次表示,我爱Webkit,我爱Chrome。
然后就想到更换图片的渲染方式——用HTML5 Canvas画布渲染图片。这个时候,你又要面临另外一个抉择,是否要牺牲IE6/7/8?
NO。Trick无处不在。神马fxcanvas,excanvas都是帮助我们前端开发进行浏览器兼容的工具。但是,在我做的那个很BT的页面中,它们根本不适用。因为这些用一些其他的方法模拟出来的canvas画布在画这样大量大尺寸图片的情况下,根本如同废柴。你就看到丫画出了第一张图片,迟迟画不出第二张。性能完全不能与HTML5的canvas相比。
Well,any way. 让该死的IE6/7/8先见鬼去吧!我们看看我们伟大的HTML5。
实验四:使用Canvas画布
实验代码:
- <input type="button" value="change"/>
- <canvas id="cv" width="1440" height="758">Your canvas tag is not supported.</canvas>
- <script>
- var cv = document.getElementById("cv");
- var ctx = cv.getContext("2d");
- var preload = [];
- for(var i =0; i<100; i++){
- preload[i] = new Image();
- preload[i].src = "images/"+( i+1 + Math.pow(10,3)).toString().substr(1) + ".jpg";
- }
- $(function(){
- var n = -1;
- $("INPUT").click(function(){
- if( ++n<100 ){
- ctx.drawImage(preload[n], 0, 0);
- }
- });
- });
- </script>
相较于上一个实验,这个实验的内存占用大大缩减。Canvas简直太酷了!
- JavaScript 的Image对象、图像渲染和浏览器缓存
- Javascript的Image对象、图像渲染与浏览器内存两三事
- JavaScript的内置对象和浏览器对象
- JavaScript的内置对象和浏览器对象
- JavaScript的内置对象和浏览器对象
- JavaScript的内置对象和浏览器对象
- Javascript 装载和执行 浏览器的渲染原理简介
- 如何改变Image对象中图像的宽度和高度
- 浅谈JavaScript的内置对象和浏览器对象
- javascript dom中的Image对象——图像预加载
- 关于浏览器缓存-javascript清除浏览器缓存的方法
- 预载入和JavaScript Image()对象
- 预载入和JavaScript Image()对象
- 预载入和JavaScript Image()对象
- 浏览器加载和渲染html的顺序
- 浏览器加载和渲染html的顺序
- 浏览器加载和渲染html的顺序
- 浏览器的加载和渲染页面
- 普适性的视觉感知与运动感知
- poj2983&&poj1364
- Android6.0 权限后编辑头像功能
- 【云隐课堂】【软件安装】Source_Insight3.5安装步骤
- 如何系统的学习 Unity 3D 中的 shader 编写(nvidia cg 编程)?
- JavaScript 的Image对象、图像渲染和浏览器缓存
- C语言 函数递归
- 项目联调服务器问题汇总
- 机房之登陆窗体
- easyui中combobox 验证输入的值必须为选项框中的数据
- jdk8-获取list<Object>中的某个属性并过滤非空,然后返回一个属性的list
- 初始化ImageLoader
- c++中sort()及qsort()的用法总结
- Hibernate的查询