mirror of
https://github.com/Kuingsmile/PicList.git
synced 2026-05-06 20:42:57 +08:00
⚡ Perf(custom): add memory monitor and optimiz memory usage
This commit is contained in:
@@ -62,8 +62,8 @@ const trayWindowOptions = {
|
|||||||
preload: preloadPath,
|
preload: preloadPath,
|
||||||
nodeIntegration: false,
|
nodeIntegration: false,
|
||||||
contextIsolation: true,
|
contextIsolation: true,
|
||||||
nodeIntegrationInWorker: true,
|
nodeIntegrationInWorker: false,
|
||||||
backgroundThrottling: false,
|
backgroundThrottling: true,
|
||||||
webSecurity: false
|
webSecurity: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,11 +83,11 @@ const settingWindowOptions = {
|
|||||||
webPreferences: {
|
webPreferences: {
|
||||||
sandbox: false,
|
sandbox: false,
|
||||||
webviewTag: true,
|
webviewTag: true,
|
||||||
backgroundThrottling: false,
|
backgroundThrottling: true,
|
||||||
preload: preloadPath,
|
preload: preloadPath,
|
||||||
nodeIntegration: false,
|
nodeIntegration: false,
|
||||||
contextIsolation: true,
|
contextIsolation: true,
|
||||||
nodeIntegrationInWorker: true,
|
nodeIntegrationInWorker: false,
|
||||||
webSecurity: false
|
webSecurity: false
|
||||||
}
|
}
|
||||||
} as IBrowserWindowOptions
|
} as IBrowserWindowOptions
|
||||||
@@ -112,8 +112,8 @@ const miniWindowOptions = {
|
|||||||
preload: preloadPath,
|
preload: preloadPath,
|
||||||
nodeIntegration: false,
|
nodeIntegration: false,
|
||||||
contextIsolation: true,
|
contextIsolation: true,
|
||||||
backgroundThrottling: false,
|
backgroundThrottling: true,
|
||||||
nodeIntegrationInWorker: true
|
nodeIntegrationInWorker: false
|
||||||
}
|
}
|
||||||
} as IBrowserWindowOptions
|
} as IBrowserWindowOptions
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ const renameWindowOptions = {
|
|||||||
preload: preloadPath,
|
preload: preloadPath,
|
||||||
nodeIntegration: false,
|
nodeIntegration: false,
|
||||||
contextIsolation: true,
|
contextIsolation: true,
|
||||||
nodeIntegrationInWorker: true,
|
nodeIntegrationInWorker: false,
|
||||||
backgroundThrottling: false
|
backgroundThrottling: false
|
||||||
}
|
}
|
||||||
} as IBrowserWindowOptions
|
} as IBrowserWindowOptions
|
||||||
@@ -158,11 +158,11 @@ const toolboxWindowOptions = {
|
|||||||
icon: logo,
|
icon: logo,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
sandbox: false,
|
sandbox: false,
|
||||||
backgroundThrottling: false,
|
backgroundThrottling: true,
|
||||||
preload: preloadPath,
|
preload: preloadPath,
|
||||||
nodeIntegration: false,
|
nodeIntegration: false,
|
||||||
contextIsolation: true,
|
contextIsolation: true,
|
||||||
nodeIntegrationInWorker: true,
|
nodeIntegrationInWorker: false,
|
||||||
webSecurity: false
|
webSecurity: false
|
||||||
}
|
}
|
||||||
} as IBrowserWindowOptions
|
} as IBrowserWindowOptions
|
||||||
|
|||||||
@@ -1,5 +1,31 @@
|
|||||||
import { EventEmitter } from 'node:events'
|
import { EventEmitter } from 'node:events'
|
||||||
|
|
||||||
const bus = new EventEmitter()
|
class OptimizedBus extends EventEmitter {
|
||||||
|
constructor () {
|
||||||
export default bus
|
super()
|
||||||
|
this.setMaxListeners(50)
|
||||||
|
}
|
||||||
|
|
||||||
|
once (event: string | symbol, listener: (...args: any[]) => void): this {
|
||||||
|
const wrappedListener = (...args: any[]) => {
|
||||||
|
try {
|
||||||
|
listener(...args)
|
||||||
|
} finally {
|
||||||
|
this.removeListener(event, wrappedListener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.once(event, wrappedListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanupListeners () {
|
||||||
|
const events = this.eventNames()
|
||||||
|
events.forEach(event => {
|
||||||
|
const listenerCount = this.listenerCount(event)
|
||||||
|
console.log(` listener count (${listenerCount}) for event: ${String(event)}`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const bus = new OptimizedBus()
|
||||||
|
|
||||||
|
export default bus
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import { II18nLanguage, IRemoteNoticeTriggerHook, ISartMode, IWindowList } from
|
|||||||
import { getUploadFiles } from '~/utils/handleArgv'
|
import { getUploadFiles } from '~/utils/handleArgv'
|
||||||
import { initI18n } from '~/utils/handleI18n'
|
import { initI18n } from '~/utils/handleI18n'
|
||||||
import { notificationList } from '~/utils/notification'
|
import { notificationList } from '~/utils/notification'
|
||||||
|
import { MemoryMonitor } from '~/utils/performanceOptimizer'
|
||||||
import { CLIPBOARD_IMAGE_FOLDER } from '~/utils/static'
|
import { CLIPBOARD_IMAGE_FOLDER } from '~/utils/static'
|
||||||
import updateChecker from '~/utils/updateChecker'
|
import updateChecker from '~/utils/updateChecker'
|
||||||
|
|
||||||
@@ -164,6 +165,10 @@ class LifeCycle {
|
|||||||
initI18n()
|
initI18n()
|
||||||
rpcServer.start()
|
rpcServer.start()
|
||||||
busEventList.listen()
|
busEventList.listen()
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
MemoryMonitor.start(30000)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#onReady () {
|
#onReady () {
|
||||||
@@ -315,6 +320,7 @@ class LifeCycle {
|
|||||||
server.shutdown()
|
server.shutdown()
|
||||||
webServer.stop()
|
webServer.stop()
|
||||||
stopFileServer()
|
stopFileServer()
|
||||||
|
MemoryMonitor.stop()
|
||||||
})
|
})
|
||||||
// Exit cleanly on request from parent process in development mode.
|
// Exit cleanly on request from parent process in development mode.
|
||||||
if (isDevelopment) {
|
if (isDevelopment) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class ClipboardWatcher extends EventEmitter {
|
|||||||
this.timer = null
|
this.timer = null
|
||||||
}
|
}
|
||||||
|
|
||||||
startListening (watchDelay = 500) {
|
startListening (watchDelay = 1000) {
|
||||||
this.stopListening(false)
|
this.stopListening(false)
|
||||||
|
|
||||||
this.timer = setInterval(() => {
|
this.timer = setInterval(() => {
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ export const showNotification = (
|
|||||||
const notification = new Notification({
|
const notification = new Notification({
|
||||||
title: options.title,
|
title: options.title,
|
||||||
body: options.body
|
body: options.body
|
||||||
// icon: options.icon || undefined
|
|
||||||
})
|
})
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
if (options.clickToCopy) {
|
if (options.clickToCopy) {
|
||||||
|
|||||||
31
src/main/utils/performanceOptimizer.ts
Normal file
31
src/main/utils/performanceOptimizer.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
export class MemoryMonitor {
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
private static interval: NodeJS.Timeout | null = null
|
||||||
|
|
||||||
|
static start (intervalMs: number = 30000) {
|
||||||
|
if (this.interval) return
|
||||||
|
|
||||||
|
this.interval = setInterval(() => {
|
||||||
|
const memUsage = process.memoryUsage()
|
||||||
|
const mbUsage = {
|
||||||
|
rss: Math.round(memUsage.rss / 1024 / 1024),
|
||||||
|
heapTotal: Math.round(memUsage.heapTotal / 1024 / 1024),
|
||||||
|
heapUsed: Math.round(memUsage.heapUsed / 1024 / 1024),
|
||||||
|
external: Math.round(memUsage.external / 1024 / 1024)
|
||||||
|
}
|
||||||
|
console.log(`[Memory] RSS: ${mbUsage.rss}MB, Heap: ${mbUsage.heapUsed}/${mbUsage.heapTotal}MB, External: ${mbUsage.external}MB`)
|
||||||
|
|
||||||
|
if (mbUsage.heapUsed / mbUsage.heapTotal > 0.8 && global.gc) {
|
||||||
|
console.log('[Memory] Triggering garbage collection')
|
||||||
|
global.gc()
|
||||||
|
}
|
||||||
|
}, intervalMs)
|
||||||
|
}
|
||||||
|
|
||||||
|
static stop () {
|
||||||
|
if (this.interval) {
|
||||||
|
clearInterval(this.interval)
|
||||||
|
this.interval = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,63 +1,66 @@
|
|||||||
import db from '@core/datastore'
|
import db from '@core/datastore'
|
||||||
import windowManager from 'apis/app/window/windowManager'
|
import windowManager from 'apis/app/window/windowManager'
|
||||||
import { screen } from 'electron'
|
import { screen } from 'electron'
|
||||||
|
|
||||||
import { configPaths } from '~/utils/configPaths'
|
import { configPaths } from '~/utils/configPaths'
|
||||||
import { IWindowList } from '~/utils/enum'
|
import { IWindowList } from '~/utils/enum'
|
||||||
|
|
||||||
export function openMiniWindow (hideSettingWindow: boolean = true) {
|
export function openMiniWindow (hideSettingWindow: boolean = true) {
|
||||||
const miniWindow = windowManager.get(IWindowList.MINI_WINDOW)!
|
const miniWindow = windowManager.get(IWindowList.MINI_WINDOW)!
|
||||||
miniWindow.removeAllListeners()
|
|
||||||
if (db.get(configPaths.settings.miniWindowOntop)) {
|
miniWindow.removeAllListeners('close')
|
||||||
miniWindow.setAlwaysOnTop(true)
|
miniWindow.removeAllListeners('move')
|
||||||
}
|
|
||||||
const { width, height } = screen.getPrimaryDisplay().workAreaSize
|
if (db.get(configPaths.settings.miniWindowOntop)) {
|
||||||
const lastPosition = db.get(configPaths.settings.miniWindowPosition)
|
miniWindow.setAlwaysOnTop(true)
|
||||||
const setPositionFunc = () => {
|
}
|
||||||
const position = miniWindow.getPosition()
|
const { width, height } = screen.getPrimaryDisplay().workAreaSize
|
||||||
db.set(configPaths.settings.miniWindowPosition, position)
|
const lastPosition = db.get(configPaths.settings.miniWindowPosition)
|
||||||
}
|
const setPositionFunc = () => {
|
||||||
if (lastPosition) {
|
const position = miniWindow.getPosition()
|
||||||
if (lastPosition[0] < 0 || lastPosition[0] > width || lastPosition[1] < 0 || lastPosition[1] > height) {
|
db.set(configPaths.settings.miniWindowPosition, position)
|
||||||
miniWindow.setPosition(width - 100, height - 100)
|
}
|
||||||
db.set(configPaths.settings.miniWindowPosition, [width - 100, height - 100])
|
if (lastPosition) {
|
||||||
} else if (lastPosition[0] + miniWindow.getSize()[0] > width || lastPosition[1] + miniWindow.getSize()[1] > height) {
|
if (lastPosition[0] < 0 || lastPosition[0] > width || lastPosition[1] < 0 || lastPosition[1] > height) {
|
||||||
miniWindow.setPosition(width - miniWindow.getSize()[0], height - miniWindow.getSize()[1])
|
miniWindow.setPosition(width - 100, height - 100)
|
||||||
db.set(configPaths.settings.miniWindowPosition, [width - miniWindow.getSize()[0], height - miniWindow.getSize()[1]])
|
db.set(configPaths.settings.miniWindowPosition, [width - 100, height - 100])
|
||||||
} else {
|
} else if (lastPosition[0] + miniWindow.getSize()[0] > width || lastPosition[1] + miniWindow.getSize()[1] > height) {
|
||||||
miniWindow.setPosition(lastPosition[0], lastPosition[1])
|
miniWindow.setPosition(width - miniWindow.getSize()[0], height - miniWindow.getSize()[1])
|
||||||
}
|
db.set(configPaths.settings.miniWindowPosition, [width - miniWindow.getSize()[0], height - miniWindow.getSize()[1]])
|
||||||
} else {
|
} else {
|
||||||
miniWindow.setPosition(width - 100, height - 100)
|
miniWindow.setPosition(lastPosition[0], lastPosition[1])
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
miniWindow.on('close', setPositionFunc)
|
miniWindow.setPosition(width - 100, height - 100)
|
||||||
miniWindow.on('move', setPositionFunc)
|
}
|
||||||
miniWindow.show()
|
|
||||||
miniWindow.focus()
|
miniWindow.on('close', setPositionFunc)
|
||||||
if (hideSettingWindow) {
|
miniWindow.on('move', setPositionFunc)
|
||||||
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)!
|
miniWindow.show()
|
||||||
settingWindow.hide()
|
miniWindow.focus()
|
||||||
} else {
|
if (hideSettingWindow) {
|
||||||
const autoCloseMainWindow = db.get(configPaths.settings.autoCloseMainWindow) || false
|
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)!
|
||||||
if (windowManager.has(IWindowList.SETTING_WINDOW) && autoCloseMainWindow) {
|
settingWindow.hide()
|
||||||
windowManager.get(IWindowList.SETTING_WINDOW)!.hide()
|
} else {
|
||||||
}
|
const autoCloseMainWindow = db.get(configPaths.settings.autoCloseMainWindow) || false
|
||||||
}
|
if (windowManager.has(IWindowList.SETTING_WINDOW) && autoCloseMainWindow) {
|
||||||
}
|
windowManager.get(IWindowList.SETTING_WINDOW)!.hide()
|
||||||
|
}
|
||||||
export const openMainWindow = () => {
|
}
|
||||||
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)
|
}
|
||||||
const autoCloseMiniWindow = db.get(configPaths.settings.autoCloseMiniWindow) || false
|
|
||||||
settingWindow!.show()
|
export const openMainWindow = () => {
|
||||||
settingWindow!.focus()
|
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)
|
||||||
if (windowManager.has(IWindowList.MINI_WINDOW) && autoCloseMiniWindow) {
|
const autoCloseMiniWindow = db.get(configPaths.settings.autoCloseMiniWindow) || false
|
||||||
windowManager.get(IWindowList.MINI_WINDOW)!.hide()
|
settingWindow!.show()
|
||||||
}
|
settingWindow!.focus()
|
||||||
}
|
if (windowManager.has(IWindowList.MINI_WINDOW) && autoCloseMiniWindow) {
|
||||||
|
windowManager.get(IWindowList.MINI_WINDOW)!.hide()
|
||||||
export const hideMiniWindow = () => {
|
}
|
||||||
if (windowManager.has(IWindowList.MINI_WINDOW)) {
|
}
|
||||||
windowManager.get(IWindowList.MINI_WINDOW)!.hide()
|
|
||||||
}
|
export const hideMiniWindow = () => {
|
||||||
}
|
if (windowManager.has(IWindowList.MINI_WINDOW)) {
|
||||||
|
windowManager.get(IWindowList.MINI_WINDOW)!.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user