阿里云主机折上折
  • 微信号
Current Site:Index > Data caching and local storage optimization

Data caching and local storage optimization

Author:Chuan Chen 阅读数:32937人阅读 分类: uni-app

Data Caching and Local Storage Optimization

In uni-app development, rational use of data caching and local storage can significantly improve application performance. From simple variable caching to complex database operations, different scenarios require appropriate solutions.

Differences Between Local Cache and Persistent Storage

uni-app provides two main storage methods:

  • Local Cache: uni.setStorage/uni.getStorage, data is stored in memory and may be cleared by the system after the app closes
  • Persistent Storage: uni.setStorageSync/uni.getStorageSync, data is written to device storage and retained long-term
// Temporary cache example
uni.setStorage({
  key: 'tempData',
  data: { timestamp: Date.now() },
  success: () => console.log('Cache successful')
})

// Persistent storage example
try {
  uni.setStorageSync('userToken', 'abc123xyz')
} catch (e) {
  console.error('Storage failed', e)
}

Cache Strategy Design

1. Data Expiration Mechanism

Add timestamps to cached data and periodically verify validity:

function setCacheWithExpire(key, data, expireHours) {
  const cacheObj = {
    data: data,
    expire: Date.now() + expireHours * 60 * 60 * 1000
  }
  uni.setStorageSync(key, JSON.stringify(cacheObj))
}

function getCacheWithExpire(key) {
  const cacheStr = uni.getStorageSync(key)
  if (!cacheStr) return null
  
  const cacheObj = JSON.parse(cacheStr)
  if (Date.now() > cacheObj.expire) {
    uni.removeStorageSync(key)
    return null
  }
  return cacheObj.data
}

2. Cache Tiering Strategy

  • Level 1 Cache: Memory cache using global variables
  • Level 2 Cache: Local storage using uni.storage
  • Level 3 Cache: Server requests
const memoryCache = {}

function getData(key) {
  // 1. Check memory cache
  if (memoryCache[key]) return Promise.resolve(memoryCache[key])
  
  // 2. Check local storage
  const localData = getCacheWithExpire(key)
  if (localData) {
    memoryCache[key] = localData
    return Promise.resolve(localData)
  }
  
  // 3. Request from network
  return fetchDataFromServer(key).then(serverData => {
    memoryCache[key] = serverData
    setCacheWithExpire(key, serverData, 24)
    return serverData
  })
}

Storage Performance Optimization

1. Batch Operations to Reduce I/O

// Inefficient approach
userList.forEach(user => {
  uni.setStorageSync(`user_${user.id}`, user)
})

// Optimized approach
const batchData = {}
userList.forEach(user => {
  batchData[`user_${user.id}`] = user
})
uni.setStorageSync('all_users', batchData)

2. Data Compression Storage

For large JSON data, compress before storage:

import lzString from 'lz-string'

function setCompressedData(key, data) {
  const compressed = lzString.compressToUTF16(JSON.stringify(data))
  uni.setStorageSync(key, compressed)
}

function getCompressedData(key) {
  const compressed = uni.getStorageSync(key)
  return JSON.parse(lzString.decompressFromUTF16(compressed))
}

Special Scenario Handling

1. Image Caching Solution

function cacheImage(url) {
  return new Promise((resolve) => {
    const fileName = url.split('/').pop()
    const cacheKey = `img_${fileName}`
    
    // Check existing cache
    const cachedPath = uni.getStorageSync(cacheKey)
    if (cachedPath) {
      resolve(cachedPath)
      return
    }
    
    // Download and cache
    uni.downloadFile({
      url,
      success: (res) => {
        if (res.statusCode === 200) {
          uni.saveFile({
            tempFilePath: res.tempFilePath,
            success: (saveRes) => {
              uni.setStorageSync(cacheKey, saveRes.savedFilePath)
              resolve(saveRes.savedFilePath)
            }
          })
        }
      }
    })
  })
}

2. Paginated List Caching

const PAGE_SIZE = 10

function cachePageData(listKey, pageNum, data) {
  const pageKey = `${listKey}_page_${pageNum}`
  uni.setStorageSync(pageKey, data)
  
  // Update list metadata
  const meta = uni.getStorageSync(`${listKey}_meta`) || {}
  meta.lastUpdate = Date.now()
  meta.totalPages = Math.max(meta.totalPages || 0, pageNum)
  uni.setStorageSync(`${listKey}_meta`, meta)
}

function getCachedPage(listKey, pageNum) {
  const pageKey = `${listKey}_page_${pageNum}`
  return uni.getStorageSync(pageKey)
}

Cross-Platform Compatibility

Different platforms have different storage limits:

  • WeChat Mini Program: 1MB per key, 10MB total
  • H5: Depends on browser implementation, typically around 5MB
  • App: Virtually no limits
function checkStorageSpace() {
  if (uni.getSystemInfoSync().platform === 'android') {
    // Special handling for Android
    return true
  }
  
  try {
    uni.setStorageSync('test_space', new Array(1024 * 1024).join('a'))
    uni.removeStorageSync('test_space')
    return true
  } catch (e) {
    return false
  }
}

Data Security Considerations

1. Sensitive Data Encryption

import CryptoJS from 'crypto-js'

const SECRET_KEY = 'your-secret-key-123'

function encryptData(data) {
  return CryptoJS.AES.encrypt(JSON.stringify(data), SECRET_KEY).toString()
}

function decryptData(cipherText) {
  const bytes = CryptoJS.AES.decrypt(cipherText, SECRET_KEY)
  return JSON.parse(bytes.toString(CryptoJS.enc.Utf8))
}

2. Automatic Cleanup Mechanism

function autoCleanStorage() {
  const now = Date.now()
  const allKeys = uni.getStorageInfoSync().keys
  
  allKeys.forEach(key => {
    if (key.startsWith('cache_')) {
      const data = uni.getStorageSync(key)
      if (data && data.expire && data.expire < now) {
        uni.removeStorageSync(key)
      }
    }
  })
}

// Execute when app starts
autoCleanStorage()

Performance Monitoring and Debugging

Add storage operation logs:

const storageLogger = {
  log: [],
  maxSize: 100
}

function wrapStorage() {
  const originalSet = uni.setStorageSync
  uni.setStorageSync = function(key, data) {
    storageLogger.log.push({
      type: 'set',
      key,
      size: JSON.stringify(data).length,
      time: Date.now()
    })
    if (storageLogger.log.length > storageLogger.maxSize) {
      storageLogger.log.shift()
    }
    return originalSet.call(uni, key, data)
  }
}

// Initialize wrapper
wrapStorage()

Local Database Solutions

For complex data structures, consider using local databases:

// Using indexedDB (H5)
function initDB() {
  return new Promise((resolve) => {
    const request = indexedDB.open('myDatabase', 1)
    
    request.onupgradeneeded = (event) => {
      const db = event.target.result
      if (!db.objectStoreNames.contains('products')) {
        db.createObjectStore('products', { keyPath: 'id' })
      }
    }
    
    request.onsuccess = (event) => {
      resolve(event.target.result)
    }
  })
}

// Using SQLite (App side)
function initSQLite() {
  plus.sqlite.openDatabase({
    name: 'mydb',
    path: '_doc/mydb.db',
    success: (e) => {
      console.log('Database opened successfully')
    }
  })
}

Cache Update Strategies

Implement intelligent cache update mechanisms:

const cacheStrategies = {
  // Timed updates
  TIMED: (key, getData, interval) => {
    const lastUpdate = uni.getStorageSync(`${key}_lastUpdate`) || 0
    if (Date.now() - lastUpdate > interval) {
      return getData().then(data => {
        uni.setStorageSync(key, data)
        uni.setStorageSync(`${key}_lastUpdate`, Date.now())
        return data
      })
    }
    return Promise.resolve(uni.getStorageSync(key))
  },
  
  // Version-based updates
  VERSIONED: (key, getData, currentVersion) => {
    const cachedVersion = uni.getStorageSync(`${key}_version`)
    if (cachedVersion !== currentVersion) {
      return getData().then(data => {
        uni.setStorageSync(key, data)
        uni.setStorageSync(`${key}_version`, currentVersion)
        return data
      })
    }
    return Promise.resolve(uni.getStorageSync(key))
  }
}

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.