前端优化-网页图片优化

前端在工作中,一定会经常涉及到图片,甚至很多人认为前端就是切图的,还有人说前端是用div+css布局的,如果从事了这项工作,你一定不这么认为,相信大家都知道前端绝对不是用PS切片工具把网页切成小图片这样简单,但是不得不说,前端真的会接触很多图片。涉及到图片的知识点也很多,这篇文字主要讲解一下网页中的图片优化的话题。
希望通过这篇文章,下面的这些问题能够得到答案。

  • 为什么要进行图片的优化?
  • 网页中能够显示的图片格式有哪些?
  • 什么是图片的分辨率?网页中一般使用多大分辨率的图片?
  • 图片的尺寸和大小是一回事吗?
  • 图片优化的原则和方法有哪些?
  • 位图和矢量图的区别是什么?
  • 浏览器是怎么下载和渲染图片的?
  • 什么是雪碧图?
  • 能够在网页中自己绘制图片吗?
  • base64格式的图片有什么用途?
  • 图片的预加载和懒加载是什么意思?
  • 图标字体是什么意思?

网页中引入图片的方式

1、在html中通过img元素(也可以是html5新增了picture元素)的src属性引入图片
2、通过CSS的background-image为元素设置背景图引入图片
3、通过javascript引入图片

浏览器是怎样渲染图片的

1、当浏览器解析HTML文件构建DOM树时,如果遇到了img元素,会向img元素的src属性标注的图片资源位置发起http请求,这个请求是异步的多线程的,也就是说浏览器可以同时加载(下载)多个图片,某一个图片的加载不会阻塞其他资源的加载。
2、浏览器在加载css文件时,不会同时加载css中的背景图片,构建渲染树时加载背景图。
3、使用javascript引入图片,在js线程执行到这一行时发出http请求加载图片,触发操作dom的事件时渲染图片。通过javascript使前端获得控制加载时间的能力,javascript的预加载和懒加载都是很好的图片优化的方法。
4、浏览器在绘制页面时,渲染缓存中的图片。

要说明的是浏览器的http请求是多线程的,但不是没有限制的,每一个http请求,相当于和服务器的一次通信,单位时间内过多的http请求对于客户端(浏览器)和服务器端都会造成很大压力,关于并发的问题以后再谈,这里举个例子,如果有一条公路给你调度,没办法加宽公路(类似带宽是固定的),如果想让公路畅通无阻,你会有什么思路呢?
1、限号出行,减少车辆(减少请求的数量,如:使用雪碧图,使用图标字体等)
2、要求提高车速(降低一个请求的响应的时间,如:使用较小的图片)
3、错峰出行(减少并发,如提前加载和延迟加载)

图片加载与渲染规则

1、页面中的img元素,如果定义样式display:none,图片会加载但不渲染。
2、页面中某元素,css定义了背景图和display:none,图片会加载但不渲染。
3、如果某元素设置了display:none,其内部的img子元素,图片会加载但不渲染,设置了背景图的子元素既不渲染也不加载。
4、重复图片的图片不会重复加载,从第二次请求开始浏览器会从缓存中读取图片。
5、css中给不存在元素设置了背景图片,背景图片不会加载,因为不存在的元素不在DOM树的节点中,在构建渲染树时自然就不会加载背景图。
6、hover伪类在hover触发时背景图片才会加载。

网页中可以使用什么图片

位图和矢量图

本文所讨论的图片特指计算机数字化的图像,分为位图和矢量图,位图和矢量图各自又有很多的格式。
位图(bitmap) 是像素集合,它是由许许多多的点组成的,这些点被称为像素,网页中最常见的是位图。
矢量图(vector graphics) 是用数学方法描述的图,矢量图文件的大小由图像的复杂程度决定,与图形的大小无关,并且矢量图可以无限放大而不会模糊。比如现在常用的图标字体就是矢量图。

网页中常用的图片格式

不同的浏览器对图片格式的支持不尽相同,基于这一点推荐使用一下格式的图片。

1、jpg:有损压缩格式

靠损失图片本身的质量来减小图片的体积,适用于颜色丰富细节较多的图像;(像素点组成的像素点越多会越清晰 )。

2、gif:无损压缩格式

靠损失图片的色彩数量来减小图片的体积,支持透明,支持动画,适用于颜色数量较少的图像,一般在网页中作为动态广告图使用;

3、png-8/png-24:无损压缩格式

损失图片的色彩数量来减小图片的体积,支持透明,不支持动画,png-24比png-8能够显示更多(很多)的颜色,也比png-8的容量大很多,因此png图片的颜色越少容量就越小。要说明一点png-24的图片在ie6中透明背景显示成灰色背景。在当下希望各位读者跟我一样不再考虑这一点。

4、svg:可缩放矢量图形

svg图像是矢量图,在放大或改变尺寸的情况下其图形质量不会有所损失,可以通过img标签的src引入,也可以通过xml代码在HTML中绘制,减少http的请求数。低版本IE对svg图像支持的不理想,在移动设备上可以放心使用。

前端拿到UI的设计图,要考虑使用什么格式的图片,原则是在不影响网页显示效果的前提下,尽量使用小的图片,这里的小指的是图片的容量而不是尺寸,比如多年前我在切图的时候被要求单张图片pc端不得大于80k,移动端不得大于30k,随着网络带宽的提高,类似的要求不再那么严谨,在不同的工作场景中可能会有不同的要求,建议单张图片100K以内。

前端在用设计稿导出图片的时候,可以肉眼观察不同格式图片显示效果,对比图片的大小,选择最优方案。工作中,我一般是这样做的,如果图片的背景是透明的,使用png或gif图片,如果背景与前景的边缘不清晰,一定使用png24格式的图片,背景不透明细节较多的图片,一般选择品质为60的jpg图片格式,细节较少的图片观察png8和png24的显示效果,肉眼分辨不出就选择小的图片。积累一些经验后你会发现不需要这么麻烦,一张图片你看一眼就会知道什么格式存储是最佳方案。

分辨率

分辨率用于衡量图像细节的表现能力,高的分辨率意味着更多的细节,更大的容量,比如打印一幅同样尺寸的图片,分辨率为300的效果要比72的清晰很多;网页中的图像也是以像素显示的,肉眼分辨不出分辨率为72和更高分辨率的图片的区别,关于分辨率我觉得还是让UI设计师和平面设计师去研究,作为前端,我们只需要知道,设定我们的图片的分辨率为72 ppi就可以了。

通过代码绘制图片

上面说了网页可以引入图片,在讲到svg的时候,我说了可以通过xml代码在HTML中绘制图形,减少http的请求数。对的,前端也可以在网页中绘制图形,而不是引入图形。这是HTML5的新特性,HTML5新增了两个元素,svg和canvas,都是通过文本的方式绘制图形。
SVG 是一种使用 XML 描述 2D 图形的语言。

<svg width="200" height="100">
      <line x1="0" y1="0" x2="200" y2="0" style="stroke:rgb(0,0,0);stroke-width:5" />
</svg>

这段代码描述了一个图形,说在一个200*100的画布上,从坐标(0,0)到坐标(200,0)画一条5像素粗的线段。
Canvas 通过 JavaScript 来绘制 2D 图形。

<canvas id="myCanvas" width="200" height="100" >
</canvas>
<script>
	var c=document.getElementById("myCanvas");
	var ctx=c.getContext("2d");
	ctx.fillStyle="#FF0000";
	ctx.fillRect(0,0,150,75);
</script>

这段代码描述了一个图形,说在200*100的画布中绘制一个红色矩形,(0,0,150,75)代表矩形的在画布中的位置,这里不详细讲。

为什么要进行图片优化

一定是不够好,才需要优化,前端进行图片优化的原因是追求更好的用户体验(包括渲染速度更快、减少白屏、闪烁),更好的网站性能,减小客户端和服务器端http请求和响应的压力。
这里的优化特指性能优化,稍微提一下图片的seo优化,img标签的alt属性很重要,引擎蜘蛛就是靠这个来判别图片,我们使用img标签引入图片的时候一定要填写alt属性说明一下图片。

图片优化的原则和方法

关于图片的优化,前面说了一个公路的例子,我们的原则见下:

一、减少http请求的数量

1、使用CSS Sprites(CSS精灵/雪碧图)减少http请求数
CSS Sprites是一种网页图片处理方式,其实就是把网页中一些背景图片整合拼合成一张图片中,利用网页元素CSS的“background-image”,“background- repeat”,“background-position”的组合进行背景定位。这样做能为我们的网站节省宝贵的http请求数。
2、使用图标字体
图标字体看起来是一个个的小图片,其中它是一种字体,只不过这个字体显示的并不是具体的文字之类的,而是各种图标。可以把网站中使用的小图标做成一套图标字体,只需要用一个http请求,就可以应用这些小图标,通过css就可以改变大小和颜色,应用非常广泛,这里不详细讲,自行百度吧。
3、使用base64图片,避免http请求
在html和css中都可以使用base64格式图片,Base64就是一种基于64个字符来表示二进制数据的方法。可以使用在线工具进行转码,一般会巴拉巴拉好多代码,下面是一个png图片转码后的写法,base64的编码省略了,注意一定是对小图片进行转码,否则代码量太大。

<img src=“data:image/png;base64,这里放Base64的编码...”/>
二、降低图片的大小

1、选择72的分辨率,选择适当格式的图片,降低图片的容量,上面已经讲过了。
2、html中通过img元素的srcset 属性和sizes属性配合使用,根据屏幕密度加载不同大小的图片
3、css中通过background-image的image-set()设置使用不同大小的背景图片。
请自行百度

三、避免闪烁和白屏,提高用户体验

1、在html和css中设置图片的尺寸
如果可以,最好是在在html和css中设置图片显示的尺寸,这个尺寸是你的页面盒模型中显示的尺寸,因为图片的加载是异步的,浏览器这个时候已经开始渲染页面,如果没有规定图片的尺寸,就会导致回流,看起来就是页面的闪烁,不是好的用户体验,规定了尺寸再渲染过程中浏览器会流出图片的显示空间,图片加载完成只会重绘页面,相对可以接受。
3、预加载和懒加载
懒加载
也叫延迟加载,之前的错峰出行的例子提到过,我们可以分批的发起http请求,对用户来说,只要可视的范围内将图片迅速的显示出来就是好的体验,这就是懒加载。实现懒加载需要javascript的配合,可以将页面里所有img属性src属性用data-xx代替,当页面滚动直至此图片出现在可视区域时,用js取到该图片的data-xx的值赋给src。
说明:页面中的img元素,如果没有src属性,浏览器就不会发出请求去下载图片。所以我们要先给src设置一幅占位图(可以是个1px*1px的图片)。

预加载
和懒加载相反,有时候我们希望一幅暂时不显示的图片,一旦需要显示的时候不要有一个等待的过程,比如这图图片对页面的功能非常关键,或者图片很大,加载比较耗时,严重影响用户体验,就可以使用预加载,预加载的方法很多,像上面提到的通过display:none的方法就可以实现预加载,也可以使用javascript创建一个Image对象,定义Image对象的src,实现预加载,预加载相当于给浏览器缓存了一张图片。

var a=new Image();    
 a.src=”xxx.gif”;  

猜你喜欢

转载自blog.csdn.net/dreamingbaobei3/article/details/88135026