5种图片资源预加载方式

5种图片资源预加载方式

如今,Web 应用随着越来越丰富的 API 实现了更多的功能,用户设备性能也不断提高,Web 应用的用户体验也可以通过优化变得丝滑。下面介绍几种 Web 应用图片预加载方式。

原理

Web 应用基于 HTTP/HTTPS 进行,预加载是为了将需要的资源写入浏览器/磁盘缓存(基于资源/浏览器缓存策略),以便于在它真正被需要使用时可以直接从缓存内读取。

什么场景需要进行预加载?

简单列举几个常见的场景:

  • 通过用户交互操作,打开一个带有图片背景的弹窗
  • 切换页面数据,此时开始请求图片需要耗时/图片切换闪一下
  • 能够预知在不久后需要展示某个固定的图片

实现预加载

关键字 preload 作为元素 <link> 的属性 rel 的值,表示用户十分有可能需要在当前浏览中加载目标资源,所以浏览器必须预先获取和缓存对应资源。
示例:

预加载
1
2
3
<head>
<link rel="preload" as="image" href="https://xxx.xxx.com/a.jpg">
</head>

在 head 内插入一个 link,为其设置 rel="preload", as="image", 以及 href 属性为资源 url。其中 as 属性参考文档,我们可以通过 <link preload> 的方式预加载多种静态资源。

如何通过 javascript 进行这个预加载操作呢?

示例
1
2
3
4
5
6
7
const preload = (src: string) => {
const link = document.createElement('link')
link.setAttribute('rel', 'preload')
link.setAttribute('as', 'image')
link.setAttribute('href', src)
document.head.appendChild(link)
}

对于使用 next.js 的用户,其内置 next/head 组件,可以帮助你便捷地修改 HTML 文档的 head 内容。官方文档

示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import Head from 'next/head'

function IndexPage() {
return (
<div>
<Head>
<title>My page title</title>
<link rel="preload" as="image" href="https://xxx.xxx.com/a.jpg">
</Head>
<p>Hello world!</p>
</div>
)
}

export default IndexPage

你可以为你的 link 绑定一个 state,亦或是通过一个数组来预加载多个图片资源,取决于你如何组织你的代码逻辑。

Link types: preload你可以阅读更多关于其规范、兼容性等说明。

方式二:new Image()

这是一种比较简单的方式,通过 new Image 构造器,我们可以创建一个 <img /> 元素。

示例
1
2
3
4
const preloadImage = (src: string) => {
const img = new Image()
img.src = src
}

这段代码是 Eager 执行的,所以当你执行 preloadImage 时,即刻便会触发浏览器获取这个图片资源。

方式三:XHR

通过 XHR 我们同样可以使得我们的资源进行缓存。

示例
1
2
3
4
5
6
const preloadImage = (src: string) => {
const xhr = new XMLHttpRequest()
xhr.responseType = 'blob'
xhr.open('GET', src, true)
xhr.send()
}

在这个示例中,对于 XHR 获取回来的图片资源我们未进行任何处理,你也可以通过 URL.createObjectURL() 来使用它。

方式四:CSS

通过 CSS 来加载资源的前提是,这个 CSS 被使用。所以这种方式对于上面几种,并不灵活。
当浏览器解析到被使用的 CSS 规则含有静态资源时,会自动进行加载。

示例
1
2
3
.example {
background-image: url('https://xxx.xxx.com/a.jpg');
}

方式五:非可见的元素

通过插入一个元素进入HTML,浏览器同样会解析它的样式,加载其所需的静态资源。

示例
1
2
3
4
5
const preloadImage = (src: string) => {
const Element = document.createElement('div')
Element.setAttribute('style', `background-image: url('${src}')`)
document.body.appendChild(Element)
}

几种图片资源预加载方式介绍完毕,希望对你有所帮助。