当前位置:   article > 正文

elelctron-vue打开窗口太慢,采用窗口池方式优化。_electron项目中为什么窗口打开的速度很慢

electron项目中为什么窗口打开的速度很慢

electron是一个跨端开发桌面应用的框架,所以编译起来比较耗时,打开窗口也比较慢,为了避免每次都那么慢,或者每次打开都新建窗口,找到一个类似进程池的窗口池方法优化。

不多bb直接上封装代码:

const {
  BrowserWindow,
  ipcMain,
} = require('electron')
// 窗口池数组
var winItems = []
// 主要进程窗口
var mainWin
// 是否初始化完成
var isInit

// 子窗口配置数据
var winConfigJson = {
  // 设置
  setting: {
    name: "setting",
    size: {
      width: 550,
      height: 470,
    },
  },

  // 意见反馈
  feedback: {
    name: "feedback",
    size: {
      width: 360,
      height: 224,
    },
  },

  // 备份与恢复
  backup: {
    name: "backup",
    size: {
      width: 551,
      height: 371,
    },
  },


  // 图片详情弹窗
  imageDialog: {
    name: "imageDialog",
    size: {
      width: 595,
      height: 543,
    },
    open: (e) => {
      let minW = 470;
      let maxW = 966;
      let minH = 487;
      let maxH = 676;
      let width = e.width + 2
      let height = e.height + 42

      const setWH = (self, min, max) => {
        if (self < min) {
          return min
        } else if (self > min && self < max) {
          return self
        } else {
          return max
        }
      }
      winConfigJson.imageDialog.size.width = setWH(width, minW, maxW)
      winConfigJson.imageDialog.size.height = setWH(height, minH, maxH)
    }
  },

  // 截图
  screen: {
    name: "screen",
    fullscreen: true,
    resizable: false,
    nodeIntegration: false,
    close: (flag) => {
      flag && mainWin.webContents.send("isScreen")
    }
  }
}


// webpreferences配置
class ConfigWebPreferences {
  // nodeIntegration = true
  // devTools = false
  webSecurity = false
}
// 窗口配置
class ConfigWindow {
  maximizable = true
  resizable = true
  center = true
  frame = false
  show = false
  webPreferences = new ConfigWebPreferences()
  model = true
  parent = mainWin
  fullscreenable = true
  transparent = true
}

// 新建窗口
class WindowPoolItem {
  constructor() {
    let config = new ConfigWindow()
    this.win = new BrowserWindow(config)
    this.param = null
    this.initEvent()
    this.loadUrl(this.win, "/blank")
  }

  // 根据环境变量拼接页面绝对地址并让窗口加载
  getTotalUrl(url) {
    if (process.env.NODE_ENV !== "production") {
      return `http://localhost:9080/#${url}`
    } else {
      return `file://${__dirname}/index.html#/${url}`
    }
  }
  // 加载窗口
  async loadUrl(win, url) {
    let totalUrl = this.getTotalUrl(url)
    await win.loadURL(totalUrl)
  }
  // 初始化窗口事件
  initEvent() {
    this.win.on("close", () => {
      for (let i = 0; i < winItems.length; i++) {
        if (winItems[i].param && winItems[i].param.name == this.param.name) {
          winItems.splice(i, 1)
        }
      }
    })
  }
  // 使用一个窗口
  use(windowParam) {
    this.effectParam(windowParam)
    this.loadUrl(this.win, windowParam.name)
  }
  // 展示窗口
  effectParam(param) {
    this.param = param
    // this.win.setAlwaysOnTop(true)
    this.controlSize()
    // this.win.moveTop()
    this.win.center();
    !isInit && (this.win.show())
  }
  // 设置窗口大小等相关配置
  controlSize() {
    if (this.param.size) {
      this.win.setSize(this.param.size.width, this.param.size.height)
    }
    if (this.param.resizable === false) {
      this.win.setResizable(false)
      if (this.param.fullscreen) {
        this.win.setFullScreen(true)
        // console.log("是否全屏", this.win.isFullScreen());
      }
      return
    } else if (this.param.minSize) {
      this.win.setMinimumSize(this.param.minSize.width, this.param.minSize.height)
      this.win.setResizable(true)
      return
    }
    this.win.setResizable(true)
    this.win.setMinimumSize(200, 150)
  }
}


class InitWindowPool {
  constructor(mainWindow) {
    // 初始化窗口池
    this.winItems = winItems
    isInit = true
    mainWin = mainWindow
    this.init()
  }
  init() {
    // 初始化三个
    for (let i = 0; i < 3; i++) {
      winItems.push(new WindowPoolItem())
    }
    for (let i in winConfigJson) {
      let name = i
      // 特定页面可以先预加载
      if (name == 'screen' || name == 'imageDialog') {
        this.picAndUse(winConfigJson[name])
      }
      // 窗口打开
      ipcMain.on(name + '-open', (e, data) => {
        // 如果菜单中包含open函数则运行
        'open' in winConfigJson[i] && winConfigJson[i].open(data)
        let param = winConfigJson[name]
        if (!this.isWindowInUse(param))
          this.picAndUse(param)
        this.curWin(name).webContents.send(name + 'Show', data)
      })
      // 缩小
      ipcMain.on(name + '-min', e => {
        this.curWin(name).minimize()
      })
      // 放大
      ipcMain.on(name + '-max', e => {
        if (this.curWin(name).isMaximized()) {
          this.curWin(name).restore()
        } else {
          this.curWin(name).maximize()
        }
      })
      // 关闭
      ipcMain.on(name + '-close', (e, data) => {
        'close' in winConfigJson[i] && winConfigJson[i].close(data)
        this.curWin(name).hide()
      })
    }
    isInit = false
  }

  // 已有窗口则直接展示
  isWindowInUse(param) {
    let item = winItems.find((v) => v.param && v.param.name === param.name)
    if (!item) return false
    item.effectParam(param)
    return true
  }
  // 当前窗口
  curWin(name) {
    return winItems.find((v) => v.param && v.param.name === name).win
  }
  // 使用一个窗口并创建一个新的
  picAndUse(param) {
    let item = winItems.find((v) => !v.param) //没有param属性的,就是没用过的
    // 使用
    item.use(param)
    winItems.push(new WindowPoolItem())
  }
}

export default InitWindowPool
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243

导入主进程实例化即可,上面winConfigJson 子窗口菜单可自行配置,不明白的可评论区留言

import {
    app,
    BrowserWindow,
    Menu,
    Tray,
    ipcMain,
} from 'electron'
import path from 'path'
import '../renderer/store'
import InitWindowPool from "../renderer/utils/winPool";


/**
 * Set `__static` path to static files in production
 * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
 */
if (process.env.NODE_ENV !== 'development') {
    global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
}
let mainWindow, tray = null,
    trayIcon1 = null,
    trayIcon2 = null
const winURL = process.env.NODE_ENV === 'development' ?
    `http://localhost:9080` :
    `file://${__dirname}/index.html`



function createWindow() {
    /**
     * Initial window options
     */

    mainWindow = new BrowserWindow({
        height: 530,
        useContentSize: true,
        width: 350,
        frame: false,
        transparent: true,
        icon: `${__static}/tray.ico`,
        webPreferences: {
            nodeIntegration: true,
            // devTools: false,
            webSecurity: false, // 跨域
        }
    })
    // 初始化窗口池
    var windowPool = new InitWindowPool(mainWindow)
    console.log("窗口池", windowPool);

    mainWindow.loadURL(winURL);

    mainWindow.on('closed', () => {
        mainWindow = null
        app.quit()
    })
    createTray()
}
ipcMain.on("closeQuit", () => {
    app.quit()
})
app.on('ready', createWindow)



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/936057
推荐阅读
相关标签
  

闽ICP备14008679号