背景

最近项目中基于需求限制需要使用mineMap地图绘制路段,路段数据有3万+条(大概27.6M),前后端请求一次耗时38s,这么长的基础数据请求时间对任何一个项目来说都是无法接受的。基于此前后端做了以下操作以期解决这个问题:

  1. 后端清除不需要的返回字段,处理后数据大小降至18.6M,请求时间缩短至28s
  2. 前端寻求浏览器存储大量数据的方案只在第一次打开页面时请求,后续均从浏览器存储中获取数据(indexDB)
  3. 路段数据由基础路段和虚拟路段组成,虚拟路段可能会变化,沟通此处需求是否可以变更为只渲染不变的基础路段数据,这样方案可以变更为前端项目里直接请求本地json文件即可,不再需要请求后端

虽然最后不再采用indexDB存储,但是还是记录下vue中使用indexDB的相关代码

indexDB

IndexedDB 是一种底层 API,用于在客户端存储大量的结构化数据(也包括文件/二进制大型对象(blobs))。该 API 使用索引实现对数据的高性能搜索。虽然 Web Storage 在存储较少量的数据很有用,但对于存储更大量的结构化数据来说力不从心。而 IndexedDB 提供了这种场景的解决方案。

indexDB操作步骤如下:

  • 打开/创建数据库(如果没有就会创建)。
  • 首次创建则在数据库中创建一个对象仓库(也就是建一个表)。
  • 数据库操作(增删改查等)

代码如下

全局定义几个变量:

let indexDB
let db
let objectStore

数据库操作(created里):

        const that this        
        // 创建indexDB内存数据库,存储基础路段数据
        indexDB = window.indexedDB.open('sectionsData')
        
        // 数据库首次创建版本,或者window.indexedDB.open传递的新版本(版本数值要比现在的高)
        indexDB.onupgradeneeded = function (event) {
          db = event.target.result
          if (!db.objectStoreNames.contains('sections')) {
            objectStore = db.createObjectStore('sections', { keyPath: 'sectionCode' })//        定义主键,相当于id
            objectStore.createIndex('sectionCode', 'sectionCode', { unique: true })
            objectStore.createIndex('flow', 'flow', { unique: false })
            objectStore.createIndex('trafficStatus', 'trafficStatus', { unique: false })
            objectStore.createIndex('coordinates', 'coordinates', { unique: false })
          }
        }

        // 数据库成功打开
        indexDB.onsuccess = function (event) {
          //获取db容器
          db = indexDB.result
          //判断是否有值--objectStore数据存储仓库(表)
          objectStore = db.transaction('sections', 'readwrite').objectStore('sections')
           //此处根据里面是否有sectionCode=0的数据来判断是否已存储路段数据
          let request = objectStore.get(0)
          request.onsuccess = function (event) {
            if (request.result) {
              let allRecords = objectStore.getAll()
              allRecords.onsuccess = function () {
                //拿到所有路段数据,进行需要的操作
                console.log(allRecords.result)
              }
            } else {
              //如果表中无数据则走接口请求逻辑
              getRoadData().then(res => {
                const data = res.data
                data.forEach((item, index) => {
                  //数据入表
                  that.add({
                    sectionCode: item.sectionCode,
                    flow: item.flow || 1000,
                    trafficStatus: item.trafficStatus || 1,
                    coordinates: JSON.stringify(coordinates)
                  })
                })
                that.add({ sectionCode: 0 })
              })
            }
          }
        }
        

add方法:

add(item) {
      const objectStore = db.transaction(['sections'], 'readwrite').objectStore('sections')
      objectStore.add(item)
    },

Logo

前往低代码交流专区

更多推荐