当前位置: 首页 > Web前端 > HTML

图片加载相关技术

时间:2023-04-02 14:56:09 HTML

目前,出于性能和灵活性的考虑,我们将一些小图片替换为矢量图或字体。除了这些可以替换的小图片,还有一些场景不得不使用位图,比如照片、背景等,对于这些位图,我们需要考虑它们在加载过程中的不同状态,制定不同的呈现方案。图片加载过程中的状态一般包括:何时决定加载图片加载、加载过程结束、故障处理性别分析。决定何时加载图像通常,图像资源是在加载页面时作为单独的请求从服务器获取的。有时候,由于图片数量和大小的影响,导致页面加载缓慢,加载了很多非用户触发的图片,也造成了流量的浪费;图片,等待用户触发图片显示。可见,正确的图片加载时机对提升用户体验有很大帮助。本节讨论与图像加载时间相关的技术:预加载和延迟加载。预加载预加载技术是在用户触发图片显示之前本地加载图片。当用户触发图片显示事件时,浏览器可以及时渲染图片,保证用户浏览网页的流畅性。那么,如何实现预加载呢?本文介绍了实现预加载的三种技术。使用CSS实现预加载这种方法只需要将要加载图片的URL写入一个隐藏元素的background属性,这样图片和CSS文件就可以同时加载了。当用户触发显示图片事件时,在目标位置插入图片。如下代码所示,这里使用了CSS3背景多图特性,只用一个隐藏元素就可以预加载所有图片。.nothing-1{显示:无;背景:url('1.jpg'),url('2.jpg'),url('3.jpg');}(关于后台多图特征的兼容性:http://caniuse.com/#search=cs...)这种方法的缺点是无法控制预加载的时机。它只能在页面加载时一起加载图片。如果图片过多,会阻塞页面的加载事件,延长页面加载时间。仅使用JavaScript实现预加载实现预加载的第二种技术是直接使用JavaScript创建一个新的Image对象,并为其src属性赋值。如下代码所示:varimage=newImage();image.src='...img网址';image.onload=function(){...}image.onerror=function(){...}也可以使用Image对象的load事件和error事件完成图片预加载和失败后的处理,比如提示加载所有图像后。使用Ajax实现预加载。最后一种方法是直接发送ajax请求获取图片资源。同样,ajax请求成功和失败的回调可以作为图片预加载成功和失败的处理。显示以下代码(仅适用于webkit浏览器):varxhr=newXMLHttpRequest();xhr.onreadystatechange=function(){if(xhr.readyState==4){if((xhr.status>=200&&xhr.status<300)||xhr.status==304){...}}}xhr.open("GET",'...imgurl');xhr.send('');Ajax请求方式无冗余Image对象,获取的资源不限于图片。延迟加载延迟加载的核心思想是根据用户需要加载图片资源,而不是在渲染页面时获取所有图片。这样一来,既可以减轻服务器压力,节省用户流量,又可以提高页面加载速度。实现思路首先将页面上所有的图片url写入img的'data-src'属性中,将默认加载图片写入src作为加载图片样式。其次是判断判断加载图片的时机,即图片进入可见区域的时候浏览器。那么问题来了,如何判断一个元素进入了可见区域呢?以垂直方向为例,判断一个元素是否进入可见区域,我们首先需要知道:可见区域的高度:window.innerHeight(IE9之前没有)||document.documentElement.clientHeight(IE标准模式);元素相对于可视区域的顶部位置:element.getBoundingClientRect().top;元素相对于可见区域底部的位置:element.getBoundingClientRect().bottom;判断是否进入可见区域,即判断元素的顶部是否相对于可见区域顶部的位置是否大于0且小于可见区域的高度;或者,元素底部相对于可视区域底部的位置是否大于0且小于可视区域的高度。上图列出了元素进入可见区域的所有情况。从上到下,第一个元素的top值和bottom值均小于0,不在可见区域;第二个元素的top小于0,但是bottom在0到clientHeight之间,已经在可见区域,需要加载;第三个元素的top和bottom都满足条件,都在可见区域内;其余两个元素与前两个元素一致。当元素进入可见区域时,将img元素的'data-src'属性赋值给'src'属性,标记img元素正在加载,不再做此处理。上述过程的伪代码如下:{return;}loadedList.push(index);loadImage(img);})}最后,将窗口的scroll和resize事件写入判断图片进入可见区域后加载的check函数。优化思路有时如果用户只想查看排序后的图片,他会快速滚动滚动条。在这种情况下,不需要加载已经快速滚动的图片。这个优化的实现思路也很简单,延迟加载逻辑,判断定时器到后元素是否还在可见区域,代码可以修改如下:functioncheck(){imgs.forEach(function(img,index){if(loadedList.indexOf(index)>=0){return;}if(!isInClient(container)){return;}setTimeout(function(){if(!isInClient(container)){return;}loadedList.push(index)loadImage(img)},1000);})}加载状态当图片处于加载状态时,需要给用户提示“the图片正在加载”。图片加载后,提示隐藏。下面,本文将给出加载时提示的两种实现方式。方案一:使用img元素背景本方案的思路是:使用“loading”提示作为img的背景。图片加载时,页面显示背景;图片加载时覆盖背景显示Image。关键代码:.img{width:500px;高度:300px;background:url('data:image/gif;base64,...')centerno-repeat;}这里将“loading”动态图片作为img标签的背景,进行base64编码转换,即可以减少一个请求。浏览器兼容性如下表:浏览器Chrome54Safari10.0Firefox50.0IE8兼容性√√√√兼容性没有问题,唯一的限制是需要设置.img的宽高。如果无法提前获取图片的宽高,可以在img标签中包裹一层,使用外层容器的背景作为“loading”的提示。容器中的img可以根据容器的宽或者高设置其大小,关键代码如下:

img{height:100%;}方案二:使用img元素的load事件img元素的load事件会在图片加载完毕后触发,所以我们可以利用这个特性在加载过程中进行提示加载。实现思路:第一次渲染img元素时,以“loading”提示作为img元素,用另一个Image对象加载真实图片。加载完真实图片后,即触发Image对象的load事件,将img元素的src改为真实图片的url。关键代码如下:Array.from(document.getElementsByTagName('img')).forEach(img=>{constimage=newImage();image.src=img.dataset.src;image.onload=()=>img.src=image.src;})该方法需要js的配合,无论是提示动画还是加载时的图片,都可以原样显示,无需重新设置。兼容性没有问题:Chrome54Safari10.0Firefox50.0IE8兼容性√√√√上面介绍的两种方案都可以实现“正在加载”提示。第一种方案需要CSS,第二种方案需要js的配合,但是更加灵活。加载动画不仅可以利用图片,还可以利用CSS3的动画特性。以上两种方案稍加修改也可以适配CSS3的加载动画Tips:方案一:加载动画作为外层div的内容,但是z-index低于图片,可以覆盖图片加载完成后;方案二:用js控制img和loading动画的显示和隐藏。图片加载完成后,隐藏加载动画,显示图片,并设置过渡动画,提升体验;加载结束图片加载结束有两种结果,要么加载成功,要么加载失败。如果加载成功,我们不需要做更多的处理,但是如果加载失败,会出现难看的破解图片提示,影响体验。本文介绍两种替换图片加载失败提示的方法。方案一::before和:after伪元素img是可替换元素,即其形式和内容由外部资源控制。当img未加载时,其:before和:after伪元素不会被渲染,只有当图像加载失败时,才会出现这两个伪元素。这是无法加载的样式示例。关键的CSS样式如下:.broken-image{width:100%;位置:相对;min-height:50px;}.broken-image:before{content:"";位置:绝对;顶部:-10px;左:0;高度:计算(100%+10px);宽度:100%;背景色:rgb(230,230,230);边框:2px点缀rgb(200,200,200);border-radius:5px;}.broken-image:after{content:"\f127""BrokenImage";显示:块;字体大小:16px;字体样式:正常;字体系列:FontAwesome;RGB(100,100,100);位置:绝对;顶部:5px;左:0;宽度:100%;文本对齐:居中;line-height:2;}因为渲染后:before和:after伪元素在img元素中,设置img元素为relative,:before为背景,绝对定位覆盖默认的分图提示,以及:after作为要在img元素中居中的提示文本。这种方式实现起来很方便,风格可控,但是兼容性太差。仅Chrome支持,其他浏览器无法在图片加载失败后渲染:before和:after伪元素。仔细看规范https://www.w3.org/TR/CSS22/g...这个规范没有完全定义:before和:after与被替换元素(比如HTML中的IMG)的交互。这将在未来的规范中进行更详细的定义。因此,替换元素的:before和:after伪元素由浏览器厂商自行实现,兼容性如下:Chrome54Safari10.0Firefox50.0IE8兼容性√???方案2:使用错误事件img元素类似于加载成功事件加载,加载失败也会触发相应的事件—error。我们可以通过error事件,在加载失败时将img的src替换为加载失败提示图片的url。关键代码如下:Array.from(document.getElementsByTagName('img')).forEach(img=>{img.onerror=()=>{img.onerror=null;img.src='data:image/gif;base64...';}});在错误响应事件中,记得将img的onerror属性设置为null,否则一旦加载失败导致图片加载失败,就会陷入死循环。本方案可支持目前主流浏览器:浏览器Chrome54Safari10.0Firefox50.0IE8兼容性√√√√以上两种方案替换图片加载失败时的破解图片提示,第一种只能用于特殊情况由于兼容性问题,第二种方案需要js的配合,但不存在兼容性问题。参考文献http://perishablepress.com/3-...http://www.zhangxinxu.com/wor...http://www.cnblogs.com/a_bu/a...