Electron 窗口卡顿问题的处理
最近发现使用 Electron 做跨平台桌面软件开发是一种很有意思的体验:只要你熟悉最基础的前端知识,在配合 Electron Document 就可以开发跨平台的桌面软件,想想还是很香的。
Electron 在其 官方 demo 中提供了常见桌面软件大部分基础性事件处理模式,包括:BrowserWindow
的创建及切换、系统菜单管理、main process
以及 renderer process
之间的通信、系统托盘处理、消息通知体系等。如果想要快速了解并掌握 Electron 开发的话,相信这应该是最好的教材。
然而,在官方提供的 demo 中有两段个人认为处理的并不是特别好的代码。首先是创建窗口时对 close
事件的响应:
function createWindow() {
mainWindow = new BrowserWindow(windowOptions)
//.....
mainWindow.on('closed', () => {
mainWindow = null
})
}
按照 Electron 提供的文档中对 close
的说明:close 事件 会在当前窗口关闭时触发。上面给出的代码中,对窗口的关闭事件响应为:将窗口对象置空。这种处理方式看似没有问题,但在 macOS
系统中窗口被关闭时,一般情况下的默认操作并不是停止运行软件,而是在 Dock 中保留软件以备用户再次点击时恢复。为了解决这个问题,官方 demo 中又引入了 activate 事件,其代码处理方式为:
app.on('activate', () => {
if (mainWindow === null) {
createWindow()
}
})
每次用户点击窗口关闭按钮时,将窗口对象释放,再点击时又重新创造一次窗口。这样的处理方式实在不敢苟同。想象一下,如果创建窗口的过程较为复杂(eg:判断登录状态、执行部分逻辑判断、网络请求之后再做业务逻辑等等),在体验上就会出现问题。实际上,官方提供的 demo 运行起来,在 macOS
系统中重复关闭再打开时,就会出现非常明显的「卡顿」情况,而卡顿的原因自然是因为每次窗口重新创建时,系统开销是很大的。
那么,假如我们在窗口关闭时,只是将其隐藏处理呢?
mainWindow.on('close', function (event) {
event.preventDefault()
mainWindow.hide()
})
如果 mainWindow
对象没有被销毁,在 activate
事件处就可以这样做:
app.on('activate', () => {
if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.show()
mainWindow.focus()
}
})
实际上,让 window
对象一直存在与内存中直至 app
被销毁,并不是最佳实践。为了让代码能够更加严谨,可以深挖 Electron 的文档,在其中发现了 before-quit 事件。于是,修改上述的代码之后,最终的处理方式变成:
app.on('before-quit', function () {
app.quitting = true
})
mainWindow.on('close', function (event) {
if (app.quitting) {
mainWindow = null // 如果当前操作确实是需要关闭窗口的话,就将其置空
} else {
event.preventDefault()
mainWindow.hide()
}
})
至于为什么一定要这样做,就留给大家去猜吧!能看懂的人,会懂。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
技术干货 | mPaaS 小程序高玩带你起飞:客户端预置小程序无视网络质量
传统的小程序技术容易受到网络环境影响,当网络质量不佳时可能导致拉取不到小程序包的情况。通过预置小程序,即可规避该问题。本文介绍了预置小程序的原理和预置小程序的实现过程。 什么是预置小程序 预置小程序是指将小程序的渲染、逻辑、配置等静态资源打包在一个压缩包内,客户端预先下载小程序包到本地、直接从本地加载资源的过程。预置小程序可以最大程度地摆脱网络环境对 mPaaS 小程序页面的影响。使用预置包能够为客户端带来以下优势: 提升用户体验 通过预置包的方式把页面内静态资源嵌入到应用中并随应用一起发布,可以使用户第一次开启应用时即无需依赖网络环境下载资源,可以直接开始使用。 实现动态更新 在推出新版本或紧急发布的时候,可以在小程序 IDE 中进行迭代开发,通过 mPaaS 控制台发布,客户端中集成的小程序 SDK 会自动将小程序更新到最新的版本。这种发布无需通过应用商店审核,可以让用户及早接收到更新。 预置小程序的实现原理 本文从以下方面介绍了预置小程序的实现原理: 小程序预置包的结构 小程序预置包的使用过程 小程序预置包的结构 小程序预置包是一个 .amr 格式的压缩文件,将后缀 amr ...
-
下一篇
sqltoy-orm 4.18.3 已经发布,ORM 框架
sqltoy-orm 4.18.3 已经发布,这是一个 ORM 框架。 此版本更新内容包括: 1、级联操作进行优化,精简级联配置,增加OneToOne类型的支持 // 可以自行定义oneToMany 和oneToOne // fields:表示当前表字段(当单字段关联且是主键时可不填) // mappedFields:表示对应关联表的字段 // delete:表示是否执行级联删除,考虑安全默认为false(有实际外键时quickvo生成会是true) @OneToOne(fields = { "transDate", "transCode" }, mappedFields = { "transDate", "transId" }, delete = true) private ComplexpkItemVO complexpkItemVO; 2、修复xml定义sql中number-format和date-format多个参数换行没有trim的缺陷 3、优化cache-arg 反向通过名称匹配key,将之前字符串包含变为类似数据库like模式,可以实现:中国 苏州 带空格...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Dcoker安装(在线仓库),最新的服务器搭配容器使用
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- MySQL数据库在高并发下的优化方案