前端预览页面优化解决思路笔记
Author:zhoulujun Date:
比如可视化话数据仪表盘预览,如下图所示:
常规的预览方案就是弹窗预览,比如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