前言
大多数网站中图片与影片是传输资料中最繁重的存在,了解如何改善它们是最划算的选择
如果网站效能或加载速度出现问题,第一步可以从图片或影片开始改善。让我们先从简单的例子一步一步找出潜在的问题以及如何解决,了解图片实际上有很多有趣的细节可以调整。
良好图片的通则
以下是一些为网站提供好图片的通则,偏向大方向理念而非语法撰写上的建议。
合适的尺寸
如果在小画面上呈现一张超大的图片,再怎么精细的影像也无法呈现清楚图片的细节(除非放大来看),因此只要画面能够显示多大张的图片就提供多大尺寸的图片即能达成节省运算与传输资源的目的。
设计师不一定会留意这一点,身为前端工程师需要与设计者沟通,让对方提供合适的图片供网页使用,工程师也可以学习基本的绘图软件输出操作,要多大的素材自行输出,或是上网找图片压缩与裁切工具。
不同的「设备尺寸 Device Resolution」与「像素密度 Pixel Density」下合适的图片大小也会有所不同
合适的格式
不同的图片格式有不同的特性与局限,先思考好要使用什么方式传输图像,是向量还是点阵?影片还是图片序列?
衡量「档案格式的特性」与「网站需要到达支援程度」,将图片用最合适的方式呈现可以大幅增进网页效能与加载时间。如果不确定格式支援程度可以到 Can I use 网站上输入格式名称,了解网站客群有没有在范围之内?能不能使用更新型的档案格式?以下是我对常用格式的浓缩建议:
.jpg
:老牌点阵图片格式,中规中矩。.png
:老牌点阵图片格式,如果需要透明背景或高品质无损图片时使用。.gif
:老牌点阵动图格式,大小、效能以及品质极差。.webp
:集.jpg
与.png
与.gif
功能于一身,优越的压缩比。.svg
:老牌向量格式,可行内置入于 HTML 中。.mp4
:老牌影片格式,中规中矩。.webm
:专为网页而生的影片格式,优越的压缩比。
适当的压缩
SVG 可以使用 SVGOMG 来压缩,要剪辑图片或影片可以使用 EZGIF。一般来说我建议在输出图片时会选择 80% 的品质,并且没有特殊需求就尽量在 300kb 以下,自行权衡「品质」与「档案大小」哪个比较重要。
节省外部请求
每当索取一张图片就是多一次对外部的请求,如果图片数量庞大将会造成负担,因此有各种方法来“减轻”大量对外请求的技巧,像是:
- 行内 SVG: 将 SVG 写入 HTML 中
- Data URI: 将图片以 Base64 编码的方式直接写入 HTML 中
- Image Sprite:把多张图片组为单一张图节省外部请求
- Icon Fonts:将多个图像制作成字体使用
以上的做法有好有坏,由于是额外的主题,因此本篇文章不会深入讨论。
background-image
的使用
只适合用于载入「非重要装饰性质的背景图片」!
使用这项属性并没有错,只是它应对一个特定的使用情境:「背景图片」,误用滥用将带来以下麻烦问题:
留意 SEO
background-image
作为背景装饰性图片,天生就不会被搜索引擎给收录。如果图片希望被搜索引擎侦测到,就应当使用 <img>
并撰写良好的 alt
说明。
留意无障碍体验
除了搜索引擎的问题,屏幕阅读器也会完全忽略 background-image
,如果图片具备纯粹装饰以外的意涵也不应该设置为背景图片。
留意性能与加载顺序
通常背景图片很少做到能够依照设备大小以及设备像素密度来替换图片,虽然可以使用 Media Queries
与 image-set
:
但除了十分冗长之外仍有许多需求无法达成,像是:提供不同的图片格式作为备份方案、懒加载、加载顺序……等。
在外连样式的情况下,也会导致需要等待 CSS 下载完毕开始解析的时候才能开始加载图片,相比于使用 <img>
引入图片的方式就会让图片加载速度受到影响,需要使用行内样式、预加载图片、预连接等方式来避免该问题。
<img>
的使用
最常见添加图片至网页的方式,该元素合适用绝大多数时机,但仍需留意细节属性的设置
撰写替代描述 alt
属性
如果你重视 SEO,就应该为每张图片添加描述良好的 alt
,并尽可能养成描述清楚图片的习惯!
底下有一张很明显的橘色猫咪图,但如果是使用屏幕阅读器,或是搜索引擎、网页爬虫想要了解网站图片内容就会出现无法解读的问题,为了解决该状况,就务必要为每一个 <img>
添加 alt
属性。
没有为图片撰写良好的替代描述,将会导致搜索引擎、部分网站用户无法正确的了解图片内容。撰写图片的描述可以参考「Google 搜索中心提供的建议」,更好的描述网页图片。
适当的懒加载
如今大多浏览器已经支持原生的懒加载,只需要添加 loading=lazy
属性即可。善用懒加载可以让图片在真正需要用到的时候才开始加载。
搭配 src-set
与 sizes
加载合适尺寸的图片
可以额外使用 src-set
属性在网页中加载适当尺寸的图片,例如:当图片在高解析度的设备上显示时,就使用较大的图片,而在低解析度的设备上就可以使用较小的图片。
像是以上范例,当设备宽度为 100px
时就会使用 100w
的图片,当设备宽度为 200px
时就会使用 200w
的图片,以此类推。不只「设备尺寸」,连「像素密度」也会被纳入考量,例如:100w
的图片在 2x
的像素密度下就会使用 200px
。
sizes
由一个媒体条件和大小值所组成,并用逗号分隔,主要功能是让浏览器知道该图片在不同设备尺寸下会需要呈现大小,举例来说:
以以上的例子來說,浏览器会知道该图片在 400px
以下时会是 200px
,在 400px
到 800px
之间时会是 100vw
,在 800px
以上时会是 50vw
;假设目前设备尺寸是 900px
,那么该图片就会是 50vw * 900px = 450px
的大小,如果像素密度是 2x
,那么就会是 450px * 2 = 900px
。
手动计算这些尺寸真的很累人 😅,因此可以使用 Responsive Image Breakpoints Generator 来自动计算,或者是使用 RespImageLint 自动化的检测图片的 srcset
与 sizes
是否正确。
提供明确的图片比例
为了避免布局偏移,在提供图片的同时最好同时附上图片的宽高让浏览器提前知道需要预留多少空间给该张图片:
或是使用 CSS 属性 aspect-ratio
来标注图片的比例关系:
非同步图片解码
此外还有 decoding="async"
属性,能够让浏览器将解析图片的工作移到主执行序之外,建议在画面之外的图片使用。
安排图片的资源优先程度
此外也可以手动调整图片获取上的重要程度,让浏览器在第一时间加载真正重要的图片,例如 LCP 图片。
或是降低获取重要程度,举例来说画面首页轮播的后几页:
<picture>
的使用
提供替代图片
举例来说你想使用 .webp
格式来取代目前的 .png
,但并不是每个用户的浏览器都支持,因此这时候就可以使用 <picture>
来达成提供替代的图片格式:
以上的意思是如果有支持该格式就使用该 <source>
的内容,如果没有就退而使用 <img>
来显示。
提供艺术呈现的图片替换
艺术呈现指的是在不同的设备尺寸下使用不同的图片,例如在桌面上使用一张图,而在手机上使用不同内容的图,举更为实际的例子来说:你可以使用 <picture>
在有宽敞的空间的时候显示完整的 Logo,但当空间不足时就使用简化的小 Logo。
总结
我的经验是当网站性能出现问题时再特别做优化即可,基础的替代文字、图片尺寸属性都撰写清楚通常就足够了。
- 如果想要在不同设备尺寸下基于艺术呈现显示不同的图片,使用
<picture>
- 如果想要提供替代的图片格式,使用
<picture>
- 如果是不重要的背景图片,可以使用
background-image
- 使用
srcset
来提供不同设备尺寸下的图片,使用sizes
来提供图片在不同设备尺寸下的大小 - 使用
width
与height
或是aspect-ratio
来提供图片的比例关系 - 使用
alt
来提供图片的替代文字 - 使用
loading
属性来懒加载图片 - 使用
fetchpriority
属性来安排图片的资源优先程度 - 使用
decoding
属性来让浏览器将解析图片的工作移到主执行序之外