一点小知识--前端缓存图片姿势

568 阅读4分钟

前言

本文章源自于最近的需求,由于页面需要展示的图片过多并且图片太大,导致加载过慢,于是需要将图片缓存到浏览器减少浏览器请求,加快图片的加载速度。正好来学习一下浏览器的缓存方式。

localStorage 与 sessionStorage

localStorage 与 sessionStorage是两个我们常使用到的做浏览器缓存的机制。

特点与区别

localStorage

  • 数据是持久化存储的,除非手动清除,否则数据会一直存在,即使关闭浏览器或重启电脑后数据依然保留。
  • 可以在同一域名下的不同页面、不同窗口或标签页中共享数据。

sessionStorage

  • 数据仅在当前会话期间有效,即只要浏览器窗口或标签页没有关闭,数据就存在。一旦关闭,数据就会被清除。
  • 同样也是在同一域名下有效,但仅限于当前窗口或标签页,不同窗口或标签页之间的sessionStorage是相互独立的。

存储大小

localStoragesessionStorage的存储大小限制因浏览器而异。一般来说,它们的存储大小限制比cookie大得多。

大多数现代浏览器中,localStoragesessionStorage的存储大小通常在 5MB 到 10MB 之间。然而,具体的限制可能因浏览器的品牌、版本和操作系统而有所不同。

需要注意的是,存储大小限制是针对每个域名或源的。这意味着在同一域名下的不同页面或窗口中,localStoragesessionStorage的存储限制是共享的。

如果尝试存储超过限制的数据,浏览器可能会抛出异常或采取其他适当的处理方式。此外,过大的存储数据可能会影响浏览器的性能,特别是在移动设备上。

因此,在使用localStoragesessionStorage时,建议合理规划数据存储,避免存储过多不必要的数据,以确保应用的性能和用户体验。

使用场景

localStorage

  • 用户偏好设置的保存:如主题选择、字体大小等,以便下次打开网站时依然保持用户设定。
  • 已阅读状态记录:记录用户已看过的文章或内容。
  • 简单数据的持久化:比如一些统计信息、累积数据等。

sessionStorage

  • 临时表单数据存储:在当前页面填写表单过程中,暂存数据以防页面刷新丢失。
  • 当前页面相关状态保存:比如当前页面的滚动位置、特定视图模式等,在页面交互过程中使用。
  • 同一会话内多页面数据传递:在同一网站的不同页面间传递一些仅在当前会话有效的信息。

使用方法

localStoragesessionStorage都具有相同的操作方法,例如setItemgetItemremoveItemclear等,具体示例如下:

  1. setItem存储value

    • 用途:将value存储到key字段。
    • 用法:setItem(key, value)
    • 代码如下
   sessionStorage.setItem("key", "value");
   localStorage.setItem("val", "value");
  1. getItem获取value

    • 用途:获取指定key本地存储的值。
    • 用法:getItem(key)
    • 代码如下:
   var value = sessionStorage.getItem("key");
   var val = localStorage.getItem("val");
  1. removeItem删除key

    • 用途:删除指定key本地存储的值。
    • 用法:removeItem(key)
    • 代码如下:
   sessionStorage.removeItem("key");
   localStorage.removeItem("val");
  1. clear清除所有的key/value

    • 用法:clear()
    • 代码如下:
   sessionStorage.clear();
   localStorage.clear();

注意事项

  1. localStoragesessionStorage只能存储字符串类型的数据,如果要存储其他类型的数据,需要使用JSON.stringify()将其转换为字符串,使用时再使用JSON.parse()将其转换回原来的类型。

  2. localStoragesessionStorage的操作方法是同步的,这意味着在执行这些方法时,浏览器会暂停其他操作,直到操作完成。

总结

localStoragesessionStorage适合存储一些用户信息和系统设置类的参数,他们的存储空间都不大,而且只能存储json字符串,在开发中我们经常使用它来存储token之类的信息

coocik

coocik也是我们经常使用的浏览器缓存机制,由服务器发送给用户浏览器并存储在用户本地设备上,通常存储一些简单的数据

特点

  • 数据存储:可以存储一些简单的信息,如用户标识、登录状态等。
  • 跨页面共享:在同一域名下的不同页面间共享数据。
  • 有一定有效期:可以设置过期时间,超过时间后 Cookie 会被自动删除。

使用方法

这里我们设置一个cookie用于存储用户的token,有效期为七天

-设置cookie

const expires = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);
document.cookie = `token=abc123; expires=${expires.toUTCString()}; path=/`;

-获取cookie

function getCookie(name) {
  const cookieValue = document.cookie.split('; ').find(row => row.startsWith(name + '='));
  if (cookieValue) {
    return cookieValue.split('=')[1];
  }
  return null;
}

-删除cookie

要删除 Cookie,只需将其有效期设置为过去的时间即可:

document.cookie = `token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;

注意事项

在使用 Cookie 时,需要注意其存储容量有限,不要存储过多数据。同时要确保数据的安全性,避免敏感信息泄露。

另外,在一些场景下,可能需要结合服务器端来共同管理和维护 Cookie,以达到更好的效果。

总结

cookie的使用场景并不宽泛,这和cookie的存储容量过小有关,通常我们使用cookie做登录判断类的需求

indexDB

接下来介绍适合本需求的存储机制indexDB。

IndexDB 是一种强大的客户端数据库存储技术。简单的说,他如同嵌入在浏览器上的数据库,他的存储量巨大,可以存储多种数据类型

特点

大容量存储:能够存储比 Cookie 等更多的数据,适合存储大量复杂数据。

离线可用:数据存储在本地,即使在离线状态下也可以访问和操作数据。

支持复杂数据结构:可以存储对象、数组等多种复杂的数据类型。

异步操作:大多数操作都是异步进行的,不会阻塞页面的渲染和其他操作,保证了性能。

事务性:支持事务操作,确保数据的完整性和一致性。

跨浏览器支持:虽然在不同浏览器上的实现可能存在一些差异,但基本得到了广泛的支持。

可扩展性:可以根据需要灵活地创建和管理不同的对象存储区。

长期存储:数据可以长期保存在用户设备上,除非被特意清除。

使用方法

以下是使用 IndexedDB 的一般步骤:

  1. 打开数据库:
    使用 indexedDB.open() 方法打开数据库,并指定数据库名称和版本号。如果数据库不存在,将会创建一个新的数据库。
  2. 创建对象仓库:
    在数据库打开成功的回调函数中,可以使用 db.createObjectStore() 方法创建对象仓库。对象仓库类似于数据库中的表,用于存储数据。
  3. 新增数据:
    使用 objectStore.add() 方法向对象仓库中添加数据。
  4. 查找数据:
    可以使用索引或游标来查找数据。通过创建索引,可以提高查找数据的效率。
  5. 修改数据:
    使用 objectStore.put() 方法修改已存在的数据。
  6. 删除数据:
    使用 objectStore.delete() 方法删除指定的数据。

以下是一个简单的示例代码,演示了如何使用 IndexedDB:

// 打开数据库
const request = indexedDB.open('myDatabase', 1);

request.onerror = function(event) {
  console.error('数据库打开失败', event);
};

request.onsuccess = function(event) {
  const db = event.target.result;

  // 创建对象仓库
  const objectStore = db.createObjectStore('myObjectStore', { keyPath: 'id' });

  // 新增数据
  const data = { id: 1, name: 'John Doe' };
  const addRequest = objectStore.add(data);

  addRequest.onerror = function(event) {
    console.error('数据添加失败', event);
  };

  addRequest.onsuccess = function(event) {
    console.log('数据添加成功');
  };
};

总结

indexDB是一种非常强大的前端数据库技术,可以使我们能够在浏览器上缓存大量的,复杂的数据,他的使用场景更加广泛,当我们需要缓存大量的数据,例如大量图片,或者需要缓存大量浏览器数据时使用。

补充

下面是我针对这个需求使用缓存的方法

首先我们需要安装 localforage,他是一个,用于在浏览器中实现本地存储的js库,提供了简单的api

  • 设置img标签
<img ref='img' data-src='url'>
  • 获取img标签,这里使用了vue的ref,也可以使用原生dom获取
const img = ref(null)

onMounted(() =>{
 const image = img.value
})
  • 查询数据库是否已缓存图片,如果未缓存则缓存到本地
image.value.forEach(item => {
localforage.getItem(item.dataset.src).then((value) => {
        if (value) {
          item.src = value;
        } else {
          fetch(item.dataset.src)
            .then((res) => res.blob())
            .then((blob) => {
              const reader = new FileReader();
              console.log(reader.result);
              reader.onloadend = () => {
                const base64data = reader.result;
                localforage.setItem(`${item.dataset.src}`, base64data);
                console.log(base64data, "222");
                item.src = base64data;
              };
              reader.readAsDataURL(blob);
            });
        }
      });)