• home > webfront > SGML > html5 >

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

    Author:zhoulujun Date:

    比如可视化话数据仪表盘预览,如下图所示:常规的预览方案就是弹窗预览,比如datatalk:https: cloud tencent com product tbdt如果是新开

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

    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