前端预览页面优化解决思路笔记

发布时间 2024-01-12 17:38:04作者: zhoulujun

比如可视化话数据仪表盘预览,如下图所示:

bk-vision数据可视化仪表盘

常规的预览方案就是弹窗预览,比如datatalk:https://cloud.tencent.com/product/tbdt

如果是新开窗口页面呢?

新开窗口的话存在,草稿还未保存到后台,如何预览呢?这个时候需要前端缓存储数据

前端存储方式:

  • localStorage:本地数据大致5M的数据缓存,具体参考:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/localStorage

  • sessionStorage:与localStorage类似,但是数据仅在当前会话期间有效。当用户关闭浏览器标签页或窗口时,数据将被清除。

  • IndexedDB:这是一个功能强大的客户端数据库,可以在浏览器中存储大量结构化数据。它提供了一个异步API,可以执行复杂的查询和事务操作。储存空间大 IndexedDB 的储存空间比 LocalStorage 大得多,一般来说不少于 250MB,甚至没有上限。

  • Web SQL Database:这是一个基于SQL的客户端数据库,已被废弃,但在某些浏览器中仍然可用。它提供了一个简单的关系型数据库接口,可以使用SQL语句进行数据操作。

  • Cookies:这是一种在浏览器中存储小型数据的方式。它们通常用于存储会话信息或跟踪用户行为。但是,由于其大小限制和每个请求都会发送到服务器的缺点,它们不适合存储大量数据。

其中Web SQL 已经被抛弃了,但是 7年过去了,这个web SQL依然活在各大浏览器中,只是没多少人敢用

https://hacks.mozilla.org/2010/06/beyond-html5-database-apis-and-the-road-to-indexeddb/

当中提到了几点:

  • WebSQL 使用字符串表示SQL语句缺乏作为“web原生”的JavaScript API的优雅

  • SQL语言在不同产商推出的数据库产品上有种类繁多的方言,SQLite支持的SQL语言也只是其中一种,没有一个可信任的、广泛接受的标准来正确的规范SQL子集

  • SQLite的变动可能影响到整个Web世界

由于Web SQL Database规范已经被废弃,原因说的很清楚,当前的SQL规范采用SQLite的SQL方言,而作为一个标准,这是不可接受的,每个浏览器都有自己的实现这还搞毛的标准。这样浏览器兼容性就不重要了,估计慢慢会被遗忘。

剩下只有 localStorage、sessionStorage、IndexedDB。

sessionStorage 也得排除,因为刷新页面就没有了。不是长缓存。

我个人推荐使用 IndexedDB,因为localStorage需要把 把JSON数据存储为字符串,需要来回解析。而IndexedDB可以直接存储,如果后台是MongoDB等数据,很多逻辑是能够直接复用的。

最关键点是IndexedDB 存储的数据空间大,具体查看:https://www.ruanyifeng.com/blog/2018/07/indexeddb.html

如何存储数据

对于localStorage,再预览的时候,存储一遍。同时开始监听数据变更,如果有变更,更新再次更新数据,大致代码如下:

function saveLocalStorage(needCompare = false) {
  return new Promise((resolve, reject) => {
    try {
      const localDashboardStore = getSaveData();
      const data = JSON.stringify(localDashboardStore);
      const key = `${BvLocalDashboardStoreKey}--${uid}`;
      if (needCompare && localStorage.getItem(key) === data) {
        return;
      }
      localStorage.setItem(key, data);
      resolve(true);
    } catch (e) {
      console.error(e);
      reject(t('saveLocalStorageFail'));
    }
  });
}

对于IndexedDB ,代码会复杂很多。当然也可以曲线救国,比如:

突破本地离线存储5M限制的JS库localforage简介 https://www.zhangxinxu.com/wordpress/2018/06/js-localforage-localstorage-indexdb/

还是回归IndexDB,这里推荐 https://www.npmjs.com/package/minimongo

对于开发人员来讲,miniMongo 就像是一个真实 MongoDB 数据库,可以进行各种增删改查的操作,和MongoDB 的 API 完全一致

miniMongo 的主要作用是缓存数据,相当于服务器端数据库的局部镜像,它不会缓存全部数据,只是缓存当前客户端用到的数据。

使用 miniMongo 的效果就是应用运行非常快,而且提供了更好的用户体验。例如用户保存了一条数据,Meteor会先保存到 miniMongo,保存成功后立即反馈给用户,体验极其顺畅;同时 Meteor会把数据同步到服务器端的真实数据库中,这个过程对于用户和开发者都是透明的。

miniMongo,准备单独做个系列教材,这里就不在写。

还有一个库就是  Dexie.js,个人推荐用这个。

如何同步更新预览页?

如果使用localstorage

 window.addEventListener('storage', listenStorage);

如果使用indexDB呢?

Dexie.js 的 db.on('changes', callback) 方法来监听数据改动。

但是个人推荐直接跨标签页通知更新,因为根本不需要数据存储。

使用 BroadcastChannel API: 

这是一个较新的 API,允许同源的不同标签页、iframes 或者 workers 之间进行通信。

// 在标签页A中
var bc = new BroadcastChannel('my_channel');
bc.postMessage('Hello from A!');
// 在标签页B中
var bc = new BroadcastChannel('my_channel');
bc.onmessage = function (event) { console.log(event.data); };

使用 SharedWorker: 

SharedWorker 是一种可以由多个标签页共享的 Web Worker。你可以在 SharedWorker 中设置一个消息监听器,然后在各个标签页中向这个监听器发送消息。

// 在 SharedWorker 中
self.onconnect = function(event) {
  var port = event.ports[0];
  port.onmessage = function(event) {
    // 广播消息到所有连接的标签页
    event.ports.forEach(function(port) {
      port.postMessage(event.data);
    });
};

整个分享预览页面代码,我有空再封装一个通用的方案出来。提个一个 saveLocalData的接口出来。只是最近太忙,估计要年底才有时间搞。

 


转载本站文章《前端预览页面优化解决思路笔记》,
请注明出处:https://www.zhoulujun.cn/html/webfront/SGML/html5/2023_0920_8980.html