前端加速图片的一些小技巧
一、根据情景的不同来加载不同的图片资源
不同的设备,所需的图片大小不需要一致, 在 4K 屏上,需要高分辨率的,对应的小屏幕如手机上,如果仍然加载高分辨的图片,这无疑是一种浪费。
通过结合使用 srcset 和 sizes 属性,可以实现根据屏幕分辨率加载不同的图片
- 大多数情况下使用 我们都是指定唯一的资源文件。 如:
<img src="image-800w.jpg" alt="Image" />
- 通过结合使用 srcset 和 sizes 属性,可以实现根据设备特性和视口宽度选择最佳图像资源和布局大小,从而提供更好的用户体验和性能优化。
<img
src="default.jpg"
srcset="small.jpg 480w, medium.jpg 800w, large.jpg 1200w"
sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 33vw"
alt="Image"
>
使用 srcset 和 sizes 属性,浏览器可以根据设备特性和视口宽度选择最佳的图像资源和布局大小,以提供更好的用户体验和性能优化。这样,不同设备和屏幕尺寸的用户可以加载适合其设备的最佳图像,并避免加载过大或过小的图像。
二、使用更优秀的图片格式
PNG、JPG 作为最初一代的图片格式,相信大家已经十分熟识。但是所谓后浪推前浪,他们的压缩算法在如今看来并不是最好的选择。许多现代的图片格式可以在不牺牲图片质量的情况下,更好的对图片进行压缩。
如: WebP 和 AVIF
- WebP 是 Google 于 2010 年基于 VP8 开发的一种格式,与大多数其他图片格式相比,它提供了卓越的压缩率,同时具有 96%+ 的浏览器支持。
- AVIF 由开放媒体联盟开发,作为 AV1 的衍生产品,提供比 WebP 更好的压缩。不幸的是,由于“许可”问题,AV1 目前在较旧的浏览器和 Microsoft Edge 中不受支持。
下面是一个 PNG 和 AV1 图片等效情况下的示例:
- 图片等效情况下的文件大小对比
(PS:相同图片质量的情况下,avif 图片大小简直不要太香!)
图片格式转换的软件非常多,在线的也不少这里就不一一列举。
-
兼容性
但是最新的图片格式毕竟还是存在兼容性问题,我们在使用时应该考虑的是,如何实现在支持的浏览器上使用 AVIF,不支持的浏览器上降级使用 JPG -
这里建议使用的解决方案是使用 标签
<picture>
<source srcset="/images/avif-image.avif" type="image/avif" /> <!-- 浏览器首选 --->
<source srcset="/images/webp-image.webp" type="image/webp" /> <!-- 其次 --->
<img src="/images/fallback.jpg" alt="image" width="1200" height="600" />
<!-- 兜底 --->
</picture>
三、服务端图片资源优化
前面给出了前端两个手动优化,让浏览器加载最合适的图片的方法。可是手动处理这些图片的时候,既要写 sizes srcset 又要写 ,非常的麻烦。
更简单的办法有没有呢?
- 是有的。那就是 让后端老哥负重前行
简单来说就是把这些优化交给服务端来做,当前端发起图片请求时,图片资源的提供着根据请求内容来提供最优资源给客户端。
比如: ImageKit
-
ImageKit 会根据请求时的网络情况、设备信息等提供最合适的图片资源,这样做 hmtl 中就仅仅需要一个 img src 便可。
-
至于具体的实现,也不是什么黑盒。请求时携带对应的参数到服务处,服务自处理即可。(既要又要不存在的,那是另外的价钱)
四、图片懒加载
如果一个网站的页面包含大量的图片,一般初始加载的时候,我们是期望它不要加载所有的图片的,只需要加载用户当前看得到的区域内的图片就行了。
但是默认情况下 img 标签内的图片都会立即加载。这样可能会阻塞页面内其他资源的加载,解决此问题的方法是使用图片的懒加载。
- 添加 loading=“lazy” 属性实现图片懒加载
<img src="/images/lazy.png" loading="lazy">
五、缓存 - 老生常谈的方案
- 缓存是提高任何资源性能的最佳方案之一
如果服务器指示允许缓存,浏览器将在本地存储资源,这意味着用户下次访问该站点时不必再次请求它们。
若要使用缓存,需要将 HTTP Cache-Control 标头添加到 HTTP 响应中,这可以通过不同的方式完成,具体取决如何缓存,简单示例如下:
Cache-Control: max-age=86400
这样的话浏览器会将结果缓存一天(86,400 秒),具体的缓存策略可自行设定。
六、异步解码
图片传输到浏览器上要想展示,还需要经过解码。除了硬件本身外,如何解码直接影响着图片展示在用户眼前的时机了。
-
img 标签的 decoding 属性用于指定浏览器图片解码方式。
• sync:同步解码。浏览器在主线程上立即解码图片。这可能会阻塞其他任务,例如页面布局和绘制,直到图片解码完成。如果你有一个小的图片,或者图片在视觉上非常重要,选择这个值。
• async:异步解码。浏览器在后台线程上解码图片,这样就不会阻塞其他任务。这对于大型图片或者不那么重要的图片比较有用,因为它们可能需要更长的时间来解码,而且不会影响到页面的其他部分。
• auto:自动解码。默认值,让浏览器自己决定如何进行解码。浏览器可能会根据图片的大小、当前的 CPU 使用情况等因素来决定使用同步还是异步解码。
<img src="example.jpg" alt="Example Image" decoding="async">
如此,浏览器将异步解码名为 “example.jpg” 的图片。这意味着浏览器将在后台线程上解码图片,从而避免影响页面的其他任务。