H5 资源加载优化分析
# H5 资源加载优化分析
# 问题背景
H5 页面首次加载时,由于背景图不能及时加载,会造成背景白屏现象,页面内容先于背景显示。
# 原因分析
- 背景图往往较大,比其他 UI 加载时间更长。
- 目前项目中的图片使用
background-image
的形式,这在浏览器中属于低优先级资源。
资源加载优先级可以在控制台中查看,
Priority
字段。
# 优化点一:图片大小
- 将图片分割为首屏和非首屏(根据市面上手机长宽比加预留空间,判断首屏范围)。
- 将背景图从 png 格式转为 jpg 格式,并进行压缩。
# 优化点二:资源优先级
- 使用
<img />
标签加载背景图。 - 设置
fetchpriority="high"
提高资源加载优先级。
# 优化点三:响应式图像 + 预加载
所有现代浏览器都支持响应式图像,而仅在基于 Chromium 的浏览器中支持预加载它们。
# 响应式图像 srcset
srcset
用于响应式的给图片设置地址,即根据不同的屏宽,设置不同分辨率的图片。
# 预加载:imagesrcset
从 Chrome 73 开始,浏览器可以在发现标签 img 之前预加载 srcset 指定的响应图像。 (opens new window)
为了预加载响应式图像,<link>
元素新加了属性:imagesrcset
和 imagesizes
。
它们与 <link rel="preload">
一起使用,并与 <img/>
元素中使用的 srcset 和 sizes 语法相匹配。
例如,如果想预加载指定的响应式图片:
<img src="wolf.jpg" alt="A rad wolf" />
可以通过将以下内容添加到 HTML 的 <head>
:
<link
as="image"
href="wolf.jpg"
imagesrcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w"
imagesizes="50vw"
/>
2
3
4
5
6
此时将无需等待加载完 CSS,便可以开始加载图片。
# 优化前后加载时序对比
优化前,等待所有 js 和 css 加载完才开始:
优化后,js 和 css 未加载完就开始加载图片:
# 扩展:其他关于资源加载的特性
# 雪碧图
雪碧图是指将多个小分辨率图片拼接到一张图里,以减少发起请求的次数。
由于 http2 增加了多路复用的特性,现在已经很少使用。
# importance
搜搜“如何优化背景图加载速度”,很多中文文章中提到了 img 标签的 important
属性:
但在 MDN 以及 stackoverflow 等网站搜不到相关内容。
MDN 中搜索 importance
,该属性可用于 link
和 iframe
标签,并未表示其可用于 img
暂未找到权威的具体用法。有一篇描述较为相关的文章 (opens new window)讲了百度 APP 中的资源调优机制,提到了该写法,但并不是通用的 web 标准;在百度小程序文档 (opens new window)中同样出现了该种写法,怀疑网上关于 importance 用于 HTML 中 img 标签的写法是误传。
# 渐进式图片加载
# 含义
非渐进式加载时,图片的显示是从上到下展示,也就是一点点的展示出高分辨率的图片,下方部分初始是空白。
渐进式加载的含义:先用低分辨率图片填充整个图片部分,然后逐渐加载为完整的高分辨率图片。
# 实现方法
使用 srcset 设置不同分辨率下使用的图片,当分辨率改变使用其他图片时,可以先显示低分辨率的图片,并使用 css 的 filter 加一层模糊滤镜。
在图片的 onLoad 事件中,去掉模糊效果。