性能优化指南
本指南详细介绍如何优化 Taro Bluetooth Print 库的性能,包括连接速度、打印效率、内存使用等方面的优化技巧。
性能分析
性能指标
在使用蓝牙打印功能时,需要关注以下性能指标:
- 连接建立时间: 从开始连接到连接成功的时间
- 数据传输速度: 每秒传输的数据量
- 打印响应时间: 从发送命令到打印机响应的时间
- 内存占用: 应用运行时的内存使用量
- CPU 使用率: 处理打印任务时的 CPU 占用
- 电池消耗: 蓝牙操作对电池的影响
性能监控
typescript
// 性能监控器
class PerformanceMonitor {
private metrics = {
connectionTime: [] as number[],
transferSpeed: [] as number[],
printTime: [] as number[],
memoryUsage: [] as number[],
}
private startTime = 0
// 开始监控
startMonitoring(operation: string) {
this.startTime = performance.now()
console.log(`🚀 开始监控: ${operation}`)
}
// 结束监控
endMonitoring(operation: string) {
const endTime = performance.now()
const duration = endTime - this.startTime
console.log(`✅ ${operation} 完成,耗时: ${duration.toFixed(2)}ms`)
// 记录指标
switch (operation) {
case "connection":
this.metrics.connectionTime.push(duration)
break
case "print":
this.metrics.printTime.push(duration)
break
}
}
// 记录传输速度
recordTransferSpeed(dataSize: number, duration: number) {
const speed = (dataSize / duration) * 1000 // bytes per second
this.metrics.transferSpeed.push(speed)
console.log(`📊 传输速度: ${(speed / 1024).toFixed(2)} KB/s`)
}
// 记录内存使用
recordMemoryUsage() {
if (typeof performance !== "undefined" && performance.memory) {
const memory = performance.memory.usedJSHeapSize / 1024 / 1024 // MB
this.metrics.memoryUsage.push(memory)
console.log(`💾 内存使用: ${memory.toFixed(2)} MB`)
}
}
// 获取性能报告
getPerformanceReport() {
const report = {
averageConnectionTime: this.calculateAverage(this.metrics.connectionTime),
averagePrintTime: this.calculateAverage(this.metrics.printTime),
averageTransferSpeed: this.calculateAverage(this.metrics.transferSpeed),
averageMemoryUsage: this.calculateAverage(this.metrics.memoryUsage),
}
console.table(report)
return report
}
private calculateAverage(values: number[]): number {
if (values.length === 0) return 0
return values.reduce((sum, value) => sum + value, 0) / values.length
}
}
// 使用性能监控
const performanceMonitor = new PerformanceMonitor()
连接优化
快速连接策略
typescript
// 智能连接管理器
class SmartConnectionManager {
private deviceCache = new Map<
string,
{
device: any
lastConnected: number
connectionCount: number
}
>()
private connectionPool = new Map<string, any>()
// 优化连接参数
private getOptimalConnectionOptions(deviceId: string) {
const cached = this.deviceCache.get(deviceId)
if (cached && cached.connectionCount > 3) {
// 频繁连接的设备使用更快的参数
return {
timeout: 5000, // 减少超时时间
autoReconnect: true, // 启用自动重连
fastConnect: true, // 启用快速连接
}
}
// 默认连接参数
return {
timeout: 10000,
autoReconnect: false,
fastConnect: false,
}
}
// 智能连接
async smartConnect(deviceId: string): Promise<boolean> {
const options = this.getOptimalConnectionOptions(deviceId)
performanceMonitor.startMonitoring("connection")
try {
// 检查连接池
if (this.connectionPool.has(deviceId)) {
const connection = this.connectionPool.get(deviceId)
if (connection && connection.isConnected()) {
console.log("🔄 使用连接池中的连接")
return true
}
}
// 执行连接
const connected = await printer.bluetooth.connect(deviceId, options)
if (connected) {
// 更新缓存
this.updateDeviceCache(deviceId)
// 添加到连接池
this.connectionPool.set(deviceId, printer.bluetooth)
}
performanceMonitor.endMonitoring("connection")
return connected
} catch (error) {
performanceMonitor.endMonitoring("connection")
throw error
}
}
// 更新设备缓存
private updateDeviceCache(deviceId: string) {
const cached = this.deviceCache.get(deviceId)
if (cached) {
cached.lastConnected = Date.now()
cached.connectionCount++
} else {
this.deviceCache.set(deviceId, {
device: null,
lastConnected: Date.now(),
connectionCount: 1,
})
}
}
// 清理连接池
cleanupConnectionPool() {
for (const [deviceId, connection] of this.connectionPool) {
if (!connection.isConnected()) {
this.connectionPool.delete(deviceId)
}
}
}
}
// 使用智能连接管理
const connectionManager = new SmartConnectionManager()
并行搜索优化
typescript
// 并行设备搜索
class ParallelDeviceSearch {
private searchPromises = new Map<string, Promise<any>>()
// 并行搜索多种服务
async parallelSearch(services: string[]): Promise<any[]> {
console.log("🔍 开始并行搜索设备...")
// 为每个服务创建搜索任务
const searchTasks = services.map((service) => this.searchService(service))
try {
// 等待所有搜索完成
const results = await Promise.allSettled(searchTasks)
// 合并结果
const allDevices = []
results.forEach((result) => {
if (result.status === "fulfilled") {
allDevices.push(...result.value)
}
})
// 去重
const uniqueDevices = this.deduplicateDevices(allDevices)
console.log(`✅ 搜索完成,发现 ${uniqueDevices.length} 个设备`)
return uniqueDevices
} catch (error) {
console.error("并行搜索失败:", error.message)
return []
}
}
// 搜索特定服务
private async searchService(service: string): Promise<any[]> {
try {
await printer.bluetooth.startDiscovery({
services: [service],
timeout: 5000,
})
await new Promise((resolve) => setTimeout(resolve, 5000))
return await printer.bluetooth.getDiscoveredDevices()
} catch (error) {
console.error(`搜索服务 ${service} 失败:`, error.message)
return []
}
}
// 设备去重
private deduplicateDevices(devices: any[]): any[] {
const seen = new Set()
return devices.filter((device) => {
if (seen.has(device.deviceId)) {
return false
}
seen.add(device.deviceId)
return true
})
}
}
// 使用并行搜索
const deviceSearch = new ParallelDeviceSearch()
async function optimizedDeviceSearch() {
// 搜索常见的打印机服务
const services = ["1812", "180F", "180A"]
const devices = await deviceSearch.parallelSearch(services)
if (devices.length > 0) {
// 按信号强度排序
devices.sort((a, b) => (b.RSSI || 0) - (a.RSSI || 0))
// 连接信号最强的设备
await connectionManager.smartConnect(devices[0].deviceId)
}
}
数据传输优化
批量数据传输
typescript
// 批量数据传输管理器
class BatchTransferManager {
private batchSize = 512 // 每批数据大小 (bytes)
private batchDelay = 50 // 批次间延迟 (ms)
private maxConcurrentBatches = 3 // 最大并发批次数
// 分批传输数据
async transferInBatches(data: ArrayBuffer): Promise<boolean> {
const chunks = this.splitData(data)
const totalChunks = chunks.length
console.log(`📦 开始批量传输,共 ${totalChunks} 个数据块`)
try {
// 使用并发控制
await this.transferChunksWithConcurrency(chunks)
console.log("✅ 批量传输完成")
return true
} catch (error) {
console.error("批量传输失败:", error.message)
return false
}
}
// 分割数据
private splitData(data: ArrayBuffer): ArrayBuffer[] {
const chunks = []
const totalLength = data.byteLength
for (let offset = 0; offset < totalLength; offset += this.batchSize) {
const chunkSize = Math.min(this.batchSize, totalLength - offset)
const chunk = data.slice(offset, offset + chunkSize)
chunks.push(chunk)
}
return chunks
}
// 并发传输数据块
private async transferChunksWithConcurrency(chunks: ArrayBuffer[]) {
const semaphore = new Semaphore(this.maxConcurrentBatches)
const transferPromises = chunks.map(async (chunk, index) => {
await semaphore.acquire()
try {
await this.transferChunk(chunk, index, chunks.length)
} finally {
semaphore.release()
}
})
await Promise.all(transferPromises)
}
// 传输单个数据块
private async transferChunk(
chunk: ArrayBuffer,
index: number,
total: number
) {
const startTime = performance.now()
try {
await printer.bluetooth.writeData(chunk)
const duration = performance.now() - startTime
performanceMonitor.recordTransferSpeed(chunk.byteLength, duration)
console.log(
`📤 传输进度: ${index + 1}/${total} (${(
chunk.byteLength / 1024
).toFixed(2)} KB)`
)
// 添加延迟以避免缓冲区溢出
if (index < total - 1) {
await new Promise((resolve) => setTimeout(resolve, this.batchDelay))
}
} catch (error) {
console.error(`数据块 ${index} 传输失败:`, error.message)
throw error
}
}
}
// 信号量实现
class Semaphore {
private permits: number
private waitQueue: (() => void)[] = []
constructor(permits: number) {
this.permits = permits
}
async acquire(): Promise<void> {
return new Promise((resolve) => {
if (this.permits > 0) {
this.permits--
resolve()
} else {
this.waitQueue.push(resolve)
}
})
}
release(): void {
this.permits++
if (this.waitQueue.length > 0) {
const resolve = this.waitQueue.shift()!
resolve()
this.permits--
}
}
}
// 使用批量传输
const batchTransfer = new BatchTransferManager()
数据压缩
typescript
// 数据压缩工具
class DataCompressor {
// 简单的 RLE 压缩算法
compressRLE(data: Uint8Array): Uint8Array {
const compressed = []
let i = 0
while (i < data.length) {
const currentByte = data[i]
let count = 1
// 计算连续相同字节的数量
while (
i + count < data.length &&
data[i + count] === currentByte &&
count < 255
) {
count++
}
// 如果连续字节数量大于 3,使用压缩
if (count > 3) {
compressed.push(0xff, currentByte, count)
} else {
// 否则直接存储原始数据
for (let j = 0; j < count; j++) {
compressed.push(currentByte)
}
}
i += count
}
return new Uint8Array(compressed)
}
// RLE 解压缩
decompressRLE(compressed: Uint8Array): Uint8Array {
const decompressed = []
let i = 0
while (i < compressed.length) {
if (compressed[i] === 0xff && i + 2 < compressed.length) {
// 压缩数据
const byte = compressed[i + 1]
const count = compressed[i + 2]
for (let j = 0; j < count; j++) {
decompressed.push(byte)
}
i += 3
} else {
// 原始数据
decompressed.push(compressed[i])
i++
}
}
return new Uint8Array(decompressed)
}
// 压缩图片数据
async compressImageData(imageData: ArrayBuffer): Promise<ArrayBuffer> {
const uint8Array = new Uint8Array(imageData)
// 检查数据类型和选择压缩策略
if (this.isBlackWhiteImage(uint8Array)) {
// 黑白图像使用 RLE 压缩
const compressed = this.compressRLE(uint8Array)
console.log(
`🗜️ 图片压缩率: ${(
(1 - compressed.length / uint8Array.length) *
100
).toFixed(1)}%`
)
return compressed.buffer
}
// 其他类型数据返回原始数据
return imageData
}
// 检查是否为黑白图像
private isBlackWhiteImage(data: Uint8Array): boolean {
// 简单的黑白检测逻辑
const uniqueBytes = new Set(data)
return uniqueBytes.size <= 2
}
}
// 使用数据压缩
const dataCompressor = new DataCompressor()
async function printCompressedImage(imageData: ArrayBuffer) {
try {
// 压缩图片数据
const compressedData = await dataCompressor.compressImageData(imageData)
// 传输压缩后的数据
await batchTransfer.transferInBatches(compressedData)
console.log("✅ 压缩图片打印完成")
} catch (error) {
console.error("压缩图片打印失败:", error.message)
}
}
内存优化
内存池管理
typescript
// 内存池管理器
class MemoryPool {
private pools = new Map<number, ArrayBuffer[]>()
private maxPoolSize = 10
// 获取内存块
getBuffer(size: number): ArrayBuffer {
const pool = this.pools.get(size) || []
if (pool.length > 0) {
const buffer = pool.pop()!
console.log(`🔄 从内存池获取 ${size} 字节缓冲区`)
return buffer
}
console.log(`🆕 创建新的 ${size} 字节缓冲区`)
return new ArrayBuffer(size)
}
// 归还内存块
returnBuffer(buffer: ArrayBuffer) {
const size = buffer.byteLength
let pool = this.pools.get(size)
if (!pool) {
pool = []
this.pools.set(size, pool)
}
if (pool.length < this.maxPoolSize) {
// 清空缓冲区内容
new Uint8Array(buffer).fill(0)
pool.push(buffer)
console.log(`💾 归还 ${size} 字节缓冲区到内存池`)
} else {
console.log(`🗑️ 内存池已满,丢弃 ${size} 字节缓冲区`)
}
}
// 清理内存池
cleanup() {
this.pools.clear()
console.log("🧹 内存池已清理")
}
// 获取内存池统计
getStats() {
const stats = {
totalBuffers: 0,
totalMemory: 0,
pools: {} as Record<string, number>,
}
for (const [size, pool] of this.pools) {
stats.pools[`${size}B`] = pool.length
stats.totalBuffers += pool.length
stats.totalMemory += pool.length * parseInt(size)
}
console.table(stats)
return stats
}
}
// 使用内存池
const memoryPool = new MemoryPool()
async function printWithMemoryPool(imageData: ArrayBuffer) {
performanceMonitor.recordMemoryUsage()
// 从内存池获取缓冲区
const buffer = memoryPool.getBuffer(imageData.byteLength)
try {
// 复制数据到缓冲区
new Uint8Array(buffer).set(new Uint8Array(imageData))
// 打印数据
await printer.bluetooth.writeData(buffer)
} finally {
// 归还缓冲区到内存池
memoryPool.returnBuffer(buffer)
performanceMonitor.recordMemoryUsage()
}
}
图片处理优化
typescript
// 优化的图片处理器
class OptimizedImageProcessor {
private canvasPool: HTMLCanvasElement[] = []
private maxCanvasPoolSize = 5
// 获取 Canvas
private getCanvas(): HTMLCanvasElement {
if (this.canvasPool.length > 0) {
return this.canvasPool.pop()!
}
return document.createElement("canvas")
}
// 归还 Canvas
private returnCanvas(canvas: HTMLCanvasElement) {
if (this.canvasPool.length < this.maxCanvasPoolSize) {
// 清空 Canvas
const ctx = canvas.getContext("2d")
if (ctx) {
ctx.clearRect(0, 0, canvas.width, canvas.height)
}
this.canvasPool.push(canvas)
}
}
// 优化的图片缩放
async resizeImage(
imagePath: string,
maxWidth: number,
maxHeight: number
): Promise<ArrayBuffer> {
const canvas = this.getCanvas()
const ctx = canvas.getContext("2d")!
try {
// 加载图片
const img = new Image()
img.src = imagePath
await new Promise((resolve, reject) => {
img.onload = resolve
img.onerror = reject
})
// 计算新尺寸
const { width, height } = this.calculateDimensions(
img.width,
img.height,
maxWidth,
maxHeight
)
// 设置 Canvas 尺寸
canvas.width = width
canvas.height = height
// 使用高质量缩放
ctx.imageSmoothingEnabled = true
ctx.imageSmoothingQuality = "high"
// 绘制缩放后的图片
ctx.drawImage(img, 0, 0, width, height)
// 转换为黑白图像
const imageData = ctx.getImageData(0, 0, width, height)
this.convertToBlackWhite(imageData)
ctx.putImageData(imageData, 0, 0)
// 转换为 ArrayBuffer
return await this.canvasToArrayBuffer(canvas)
} finally {
this.returnCanvas(canvas)
}
}
// 计算缩放尺寸
private calculateDimensions(
originalWidth: number,
originalHeight: number,
maxWidth: number,
maxHeight: number
): { width: number; height: number } {
let width = originalWidth
let height = originalHeight
// 计算缩放比例
const widthRatio = maxWidth / width
const heightRatio = maxHeight / height
const ratio = Math.min(widthRatio, heightRatio, 1)
if (ratio < 1) {
width = Math.round(width * ratio)
height = Math.round(height * ratio)
}
return { width, height }
}
// 转换为黑白图像
private convertToBlackWhite(imageData: ImageData): void {
const data = imageData.data
for (let i = 0; i < data.length; i += 4) {
// 计算灰度值
const gray = data[i] * 0.299 + data[i + 1] * 0.587 + data[i + 2] * 0.114
// 二值化
const value = gray > 128 ? 255 : 0
data[i] = value // R
data[i + 1] = value // G
data[i + 2] = value // B
// Alpha 通道保持不变
}
}
// Canvas 转 ArrayBuffer
private async canvasToArrayBuffer(
canvas: HTMLCanvasElement
): Promise<ArrayBuffer> {
return new Promise((resolve) => {
canvas.toBlob((blob) => {
if (blob) {
blob.arrayBuffer().then(resolve)
} else {
resolve(new ArrayBuffer(0))
}
}, "image/png")
})
}
}
// 使用优化的图片处理器
const imageProcessor = new OptimizedImageProcessor()
async function printOptimizedImage(imagePath: string) {
try {
// 优化图片处理
const optimizedData = await imageProcessor.resizeImage(imagePath, 384, 400)
// 压缩数据
const compressedData = await dataCompressor.compressImageData(optimizedData)
// 批量传输
await batchTransfer.transferInBatches(compressedData)
console.log("✅ 优化图片打印完成")
} catch (error) {
console.error("优化图片打印失败:", error.message)
}
}
缓存优化
多级缓存系统
typescript
// 多级缓存系统
class MultiLevelCache {
private memoryCache = new Map<
string,
{
data: any
timestamp: number
accessCount: number
}
>()
private persistentCache = new Map<string, any>()
private maxMemoryCacheSize = 50
private cacheTimeout = 30 * 60 * 1000 // 30 分钟
// 获取缓存数据
async get(key: string): Promise<any> {
// 检查内存缓存
const memoryData = this.memoryCache.get(key)
if (memoryData && !this.isExpired(memoryData.timestamp)) {
memoryData.accessCount++
console.log(`🎯 内存缓存命中: ${key}`)
return memoryData.data
}
// 检查持久化缓存
const persistentData = this.persistentCache.get(key)
if (persistentData) {
console.log(`💾 持久化缓存命中: ${key}`)
// 加载到内存缓存
this.setMemoryCache(key, persistentData)
return persistentData
}
console.log(`❌ 缓存未命中: ${key}`)
return null
}
// 设置缓存数据
async set(key: string, data: any, persistent = false): Promise<void> {
// 设置内存缓存
this.setMemoryCache(key, data)
// 设置持久化缓存
if (persistent) {
this.persistentCache.set(key, data)
console.log(`💾 数据已保存到持久化缓存: ${key}`)
}
}
// 设置内存缓存
private setMemoryCache(key: string, data: any): void {
// 检查缓存大小
if (this.memoryCache.size >= this.maxMemoryCacheSize) {
this.evictLeastUsed()
}
this.memoryCache.set(key, {
data,
timestamp: Date.now(),
accessCount: 1,
})
}
// 淘汰最少使用的数据
private evictLeastUsed(): void {
let leastUsedKey = ""
let leastAccessCount = Infinity
for (const [key, value] of this.memoryCache) {
if (value.accessCount < leastAccessCount) {
leastAccessCount = value.accessCount
leastUsedKey = key
}
}
if (leastUsedKey) {
this.memoryCache.delete(leastUsedKey)
console.log(`🗑️ 淘汰缓存: ${leastUsedKey}`)
}
}
// 检查是否过期
private isExpired(timestamp: number): boolean {
return Date.now() - timestamp > this.cacheTimeout
}
// 清理过期缓存
cleanup(): void {
for (const [key, value] of this.memoryCache) {
if (this.isExpired(value.timestamp)) {
this.memoryCache.delete(key)
console.log(`🧹 清理过期缓存: ${key}`)
}
}
}
// 获取缓存统计
getStats() {
const stats = {
memoryCacheSize: this.memoryCache.size,
persistentCacheSize: this.persistentCache.size,
hitRate: 0,
memoryUsage: this.calculateMemoryUsage(),
}
console.table(stats)
return stats
}
// 计算内存使用量
private calculateMemoryUsage(): number {
let totalSize = 0
for (const [key, value] of this.memoryCache) {
totalSize += key.length * 2 // 字符串大小
totalSize += JSON.stringify(value.data).length * 2
totalSize += 24 // 对象开销
}
return totalSize / 1024 // KB
}
}
// 使用多级缓存
const cache = new MultiLevelCache()
async function printWithCache(imagePath: string) {
const cacheKey = `image_${imagePath}`
try {
// 尝试从缓存获取
let imageData = await cache.get(cacheKey)
if (!imageData) {
console.log("🔄 处理新图片...")
// 处理图片
imageData = await imageProcessor.resizeImage(imagePath, 384, 400)
// 保存到缓存
await cache.set(cacheKey, imageData, true)
}
// 打印图片
await printer.bluetooth.writeData(imageData)
} catch (error) {
console.error("缓存打印失败:", error.message)
}
}
打印队列优化
智能打印队列
typescript
// 智能打印队列管理器
class SmartPrintQueue {
private queue: Array<{
id: string
type: "text" | "image" | "command"
data: any
priority: number
timestamp: number
retryCount: number
}> = []
private isProcessing = false
private maxRetries = 3
private batchSize = 5
private batchTimeout = 1000
// 添加打印任务
addTask(
type: "text" | "image" | "command",
data: any,
priority = 0
): Promise<string> {
return new Promise((resolve, reject) => {
const taskId = `task_${Date.now()}_${Math.random()
.toString(36)
.substr(2, 9)}`
this.queue.push({
id: taskId,
type,
data,
priority,
timestamp: Date.now(),
retryCount: 0,
})
// 按优先级排序
this.queue.sort((a, b) => b.priority - a.priority)
// 监听任务完成
this.waitForTaskCompletion(taskId, resolve, reject)
// 开始处理队列
this.processQueue()
console.log(
`📋 添加打印任务: ${taskId} (类型: ${type}, 优先级: ${priority})`
)
})
}
// 等待任务完成
private waitForTaskCompletion(
taskId: string,
resolve: (value: string) => void,
reject: (reason: any) => void
) {
const checkInterval = setInterval(() => {
const task = this.queue.find((t) => t.id === taskId)
if (!task) {
clearInterval(checkInterval)
resolve(taskId)
}
}, 500)
// 设置超时
setTimeout(() => {
clearInterval(checkInterval)
reject(new Error("任务超时"))
}, 30000)
}
// 处理队列
private async processQueue() {
if (this.isProcessing || this.queue.length === 0) {
return
}
this.isProcessing = true
try {
// 批量处理任务
while (this.queue.length > 0) {
const batch = this.queue.slice(0, this.batchSize)
await this.processBatch(batch)
// 移除已处理的任务
this.queue = this.queue.slice(this.batchSize)
// 如果还有任务,稍作延迟
if (this.queue.length > 0) {
await new Promise((resolve) => setTimeout(resolve, this.batchTimeout))
}
}
} finally {
this.isProcessing = false
}
}
// 处理批次任务
private async processBatch(batch: any[]) {
console.log(`🔄 处理批次任务 (${batch.length} 个)`)
for (const task of batch) {
try {
await this.executeTask(task)
// 任务成功,从队列中移除
const index = this.queue.findIndex((t) => t.id === task.id)
if (index !== -1) {
this.queue.splice(index, 1)
}
console.log(`✅ 任务完成: ${task.id}`)
} catch (error) {
console.error(`❌ 任务失败: ${task.id}`, error.message)
task.retryCount++
if (task.retryCount < this.maxRetries) {
console.log(
`🔄 重试任务: ${task.id} (${task.retryCount}/${this.maxRetries})`
)
// 降低优先级并重新排队
task.priority = Math.max(0, task.priority - 1)
// 延迟后重试
await new Promise((resolve) =>
setTimeout(resolve, 1000 * task.retryCount)
)
} else {
console.error(`💀 任务最终失败: ${task.id}`)
// 从队列中移除
const index = this.queue.findIndex((t) => t.id === task.id)
if (index !== -1) {
this.queue.splice(index, 1)
}
}
}
}
}
// 执行单个任务
private async executeTask(task: any): Promise<void> {
switch (task.type) {
case "text":
await printer.printer.printText(task.data)
break
case "image":
await printer.printer.printImage(task.data)
break
case "command":
await printer.printer.sendCommands(task.data)
break
default:
throw new Error(`未知任务类型: ${task.type}`)
}
}
// 获取队列状态
getQueueStatus() {
const status = {
queueLength: this.queue.length,
isProcessing: this.isProcessing,
tasksByType: {} as Record<string, number>,
averagePriority: 0,
}
// 统计任务类型
this.queue.forEach((task) => {
status.tasksByType[task.type] = (status.tasksByType[task.type] || 0) + 1
})
// 计算平均优先级
if (this.queue.length > 0) {
const totalPriority = this.queue.reduce(
(sum, task) => sum + task.priority,
0
)
status.averagePriority = totalPriority / this.queue.length
}
console.table(status)
return status
}
// 清空队列
clearQueue() {
this.queue = []
console.log("🧹 打印队列已清空")
}
}
// 使用智能打印队列
const printQueue = new SmartPrintQueue()
async function optimizedPrintExample() {
try {
// 添加多个打印任务
const taskId1 = await printQueue.addTask("text", "=== 测试收据 ===", 10)
const taskId2 = await printQueue.addTask("image", "/path/to/logo.png", 5)
const taskId3 = await printQueue.addTask("text", "商品列表:", 3)
const taskId4 = await printQueue.addTask("command", [0x1b, 0x61, 0x01], 1)
console.log("所有任务已添加到队列")
} catch (error) {
console.error("队列打印失败:", error.message)
}
}
性能监控与分析
性能分析工具
typescript
// 性能分析工具
class PerformanceAnalyzer {
private performanceData = {
connections: [] as Array<{
timestamp: number
duration: number
success: boolean
}>,
transfers: [] as Array<{
timestamp: number
size: number
duration: number
}>,
prints: [] as Array<{
timestamp: number
type: string
duration: number
success: boolean
}>,
memory: [] as Array<{ timestamp: number; usage: number }>,
}
// 记录连接性能
recordConnection(duration: number, success: boolean) {
this.performanceData.connections.push({
timestamp: Date.now(),
duration,
success,
})
}
// 记录传输性能
recordTransfer(size: number, duration: number) {
this.performanceData.transfers.push({
timestamp: Date.now(),
size,
duration,
})
}
// 记录打印性能
recordPrint(type: string, duration: number, success: boolean) {
this.performanceData.prints.push({
timestamp: Date.now(),
type,
duration,
success,
})
}
// 记录内存使用
recordMemoryUsage(usage: number) {
this.performanceData.memory.push({
timestamp: Date.now(),
usage,
})
}
// 生成性能报告
generateReport() {
const report = {
connection: this.analyzeConnections(),
transfer: this.analyzeTransfers(),
print: this.analyzePrints(),
memory: this.analyzeMemory(),
recommendations: this.generateRecommendations(),
}
console.log("📊 性能分析报告:")
console.table(report)
return report
}
// 分析连接性能
private analyzeConnections() {
const connections = this.performanceData.connections
if (connections.length === 0) {
return { count: 0, averageDuration: 0, successRate: 0 }
}
const successfulConnections = connections.filter((c) => c.success)
const totalDuration = connections.reduce((sum, c) => sum + c.duration, 0)
return {
count: connections.length,
averageDuration: totalDuration / connections.length,
successRate: (successfulConnections.length / connections.length) * 100,
fastestConnection: Math.min(...connections.map((c) => c.duration)),
slowestConnection: Math.max(...connections.map((c) => c.duration)),
}
}
// 分析传输性能
private analyzeTransfers() {
const transfers = this.performanceData.transfers
if (transfers.length === 0) {
return { count: 0, averageSpeed: 0, totalData: 0 }
}
const totalData = transfers.reduce((sum, t) => sum + t.size, 0)
const totalTime = transfers.reduce((sum, t) => sum + t.duration, 0)
const averageSpeed = (totalData / totalTime) * 1000 // bytes per second
return {
count: transfers.length,
averageSpeed: averageSpeed / 1024, // KB/s
totalData: totalData / 1024, // KB
fastestTransfer:
Math.max(...transfers.map((t) => (t.size / t.duration) * 1000)) / 1024, // KB/s
slowestTransfer:
Math.min(...transfers.map((t) => (t.size / t.duration) * 1000)) / 1024, // KB/s
}
}
// 分析打印性能
private analyzePrints() {
const prints = this.performanceData.prints
if (prints.length === 0) {
return { count: 0, averageDuration: 0, successRate: 0 }
}
const successfulPrints = prints.filter((p) => p.success)
const totalDuration = successfulPrints.reduce(
(sum, p) => sum + p.duration,
0
)
// 按类型分组
const byType = prints.reduce((acc, print) => {
if (!acc[print.type]) {
acc[print.type] = { count: 0, successCount: 0, totalDuration: 0 }
}
acc[print.type].count++
if (print.success) {
acc[print.type].successCount++
acc[print.type].totalDuration += print.duration
}
return acc
}, {} as Record<string, any>)
return {
count: prints.length,
averageDuration:
successfulPrints.length > 0
? totalDuration / successfulPrints.length
: 0,
successRate: (successfulPrints.length / prints.length) * 100,
byType,
}
}
// 分析内存使用
private analyzeMemory() {
const memory = this.performanceData.memory
if (memory.length === 0) {
return { average: 0, peak: 0, trend: "stable" }
}
const average = memory.reduce((sum, m) => sum + m.usage, 0) / memory.length
const peak = Math.max(...memory.map((m) => m.usage))
// 分析趋势
const recent = memory.slice(-10)
const older = memory.slice(-20, -10)
let trend = "stable"
if (recent.length > 0 && older.length > 0) {
const recentAvg =
recent.reduce((sum, m) => sum + m.usage, 0) / recent.length
const olderAvg = older.reduce((sum, m) => sum + m.usage, 0) / older.length
if (recentAvg > olderAvg * 1.1) {
trend = "increasing"
} else if (recentAvg < olderAvg * 0.9) {
trend = "decreasing"
}
}
return {
average,
peak,
trend,
}
}
// 生成优化建议
private generateRecommendations() {
const recommendations = []
const connectionAnalysis = this.analyzeConnections()
const transferAnalysis = this.analyzeTransfers()
const memoryAnalysis = this.analyzeMemory()
// 连接优化建议
if (connectionAnalysis.successRate < 90) {
recommendations.push("连接成功率较低,建议检查蓝牙信号强度或增加重试次数")
}
if (connectionAnalysis.averageDuration > 10000) {
recommendations.push("连接时间较长,建议优化连接参数或使用连接池")
}
// 传输优化建议
if (transferAnalysis.averageSpeed < 10) {
recommendations.push("传输速度较慢,建议启用数据压缩或增加批次大小")
}
// 内存优化建议
if (memoryAnalysis.trend === "increasing") {
recommendations.push(
"内存使用呈上升趋势,建议检查内存泄漏或增加缓存清理频率"
)
}
if (memoryAnalysis.peak > 50) {
recommendations.push("内存峰值较高,建议优化图片处理或减少缓存大小")
}
return recommendations
}
}
// 使用性能分析器
const performanceAnalyzer = new PerformanceAnalyzer()
// 定期生成性能报告
setInterval(() => {
performanceAnalyzer.generateReport()
}, 60000) // 每分钟生成一次报告
最佳实践
1. 预加载和预热
typescript
// 预加载管理器
class PreloadManager {
private preloadedData = new Map<string, any>()
// 预加载常用图片
async preloadCommonImages() {
const commonImages = [
"/images/logo.png",
"/images/qr-code.png",
"/images/header.png",
]
console.log("🔄 预加载常用图片...")
const preloadPromises = commonImages.map(async (imagePath) => {
try {
const processedImage = await imageProcessor.resizeImage(
imagePath,
384,
200
)
this.preloadedData.set(imagePath, processedImage)
console.log(`✅ 预加载完成: ${imagePath}`)
} catch (error) {
console.error(`❌ 预加载失败: ${imagePath}`, error.message)
}
})
await Promise.allSettled(preloadPromises)
}
// 获取预加载数据
getPreloadedData(key: string) {
return this.preloadedData.get(key)
}
// 预热蓝牙连接
async warmupBluetooth() {
try {
console.log("🔥 预热蓝牙连接...")
// 初始化蓝牙适配器
await printer.bluetooth.init()
// 短暂搜索设备
await printer.bluetooth.startDiscovery({ timeout: 2000 })
console.log("✅ 蓝牙预热完成")
} catch (error) {
console.error("❌ 蓝牙预热失败:", error.message)
}
}
}
// 使用预加载
const preloadManager = new PreloadManager()
// 应用启动时预加载
preloadManager.preloadCommonImages()
preloadManager.warmupBluetooth()
2. 渐进式优化
typescript
// 渐进式优化管理器
class ProgressiveOptimizer {
private optimizationLevel = 1
private performanceThresholds = {
connectionTime: 5000,
transferSpeed: 20, // KB/s
memoryUsage: 30, // MB
}
// 根据性能调整优化级别
adjustOptimizationLevel(performanceData: any) {
const { connection, transfer, memory } = performanceData
// 如果性能良好,降低优化级别
if (
connection.averageDuration < this.performanceThresholds.connectionTime &&
transfer.averageSpeed > this.performanceThresholds.transferSpeed &&
memory.average < this.performanceThresholds.memoryUsage
) {
this.optimizationLevel = Math.max(1, this.optimizationLevel - 1)
console.log(`⬇️ 降低优化级别到: ${this.optimizationLevel}`)
}
// 如果性能较差,提高优化级别
if (
connection.averageDuration >
this.performanceThresholds.connectionTime * 2 ||
transfer.averageSpeed < this.performanceThresholds.transferSpeed / 2 ||
memory.average > this.performanceThresholds.memoryUsage * 2
) {
this.optimizationLevel = Math.min(5, this.optimizationLevel + 1)
console.log(`⬆️ 提高优化级别到: ${this.optimizationLevel}`)
}
}
// 获取当前优化配置
getOptimizationConfig() {
const configs = {
1: {
batchSize: 512,
batchDelay: 50,
compressionEnabled: false,
cacheEnabled: true,
},
2: {
batchSize: 256,
batchDelay: 30,
compressionEnabled: true,
cacheEnabled: true,
},
3: {
batchSize: 128,
batchDelay: 20,
compressionEnabled: true,
cacheEnabled: true,
},
4: {
batchSize: 64,
batchDelay: 10,
compressionEnabled: true,
cacheEnabled: false,
},
5: {
batchSize: 32,
batchDelay: 5,
compressionEnabled: true,
cacheEnabled: false,
},
}
return configs[this.optimizationLevel] || configs[1]
}
}
// 使用渐进式优化
const progressiveOptimizer = new ProgressiveOptimizer()
下一步
学习了性能优化后,您可以继续探索: