• 优化electron客户端卡顿的几种方案


    背景

    公司需要做一个同步盘的客户端,框架技术选型方面使用了支持跨平台的Electron框架,其中一些核心功能就是文件的上传,和下载,考虑到node操作文件比较方便,起初把文件的下载上传操作放到主进程,在大量文件下载和上传时,造成了界面的卡顿,现在就这个问题进行剖析和优化。

     

    解决卡顿

    方案一

    首先要确定是什么因素导致的卡顿,在平时,没有上传下载文件时,electron客户端没有出现卡顿的情况,然后对下载的流程进行跟踪,通过打印log日记发现,在执行一个方法后后面的log无法输出,然后界面失去了响应,其代码如下

    const  parentExist = (rpath: string) => {
    const  root = store.get("syncPath") as  string;
    let  parent = path.parse(rpath).dir.replaceAll("\", "/");
    let  localFilePath = path.join(root, parent);
    let  isFalse = parent !== "/";
    const  dirs = [];
    try {
    while (!fs.existsSync(localFilePath) && isFalse) {
    dirs.push(localFilePath);
    parent = path.parse(rpath).dir.replaceAll("\", "/");
    localFilePath = path.join(root, parent);
    isFalse = parent !== "/";
    }
    for (const  dir  of  dirs) {
    fs.mkdirSync(dir);
    }
    } catch (error) {
    console.log(error);
    }
    };
    

    好家伙,在while 循环里我做了parent = path.parse(rpath).dir.replaceAll(““, “/“);,应该是parent = path.parse(parent).dir.replaceAll(““, “/“); 不然parent 一直不等于”/“,这样就一直循环出不来了,导致主进程卡顿失去响应。
    解决这个问题后发现,卡顿依然存在,还需要继续优化。

     

    方案二

    一般来说,造成卡顿的主要原因是主进程被阻塞了,虽然我使用的异步,但是,像之前的while 循环无线递归,虽然放在主进程,但是也会阻塞主进程,而下载上传这样的同步逻辑涉及到很多计算和资源的等待,于是,我对同步逻辑进行了整改,我把同步逻辑放在一个隐藏的渲染进程进行运行,通过ipc再进行交互.

    进行了这一轮改造后,发现优化后的效果不太明显。

     

    方案三

    经过前几轮的优化,让我对我渲染进程的逻辑有些思考,会不会是我的渲染进程的js代码有问题,于是我重新审视了我的代码,发现在获取状态图标的时候,每个文件都需要调用ipc,通过主进程获取文件的状态,并且,每一个触发同步操作时,都会通知渲染进程进行重新渲染,如果触发频率过高,就会一直触发渲染,而且发现获取状态的回调时长有点长,平均每个1s,

    const resust = await ipcRenderer.invoke("getFileStatus",
       this.getRLPath(filedir)
    );
    

    就是这段代码。

    于是我就将获取状态的方案重新整改。通过缓存的方式获取,放到主进程的全局变量里,两个渲染进程共同操作这个全局变量

     const statusCache: any = new mapCache();
      const statusCacheinit = async () => {
      const meta = new MetaData();
      const dbFile = await meta.getAll("");
      statusCache.clear();
      if (dbFile) {
        for (const file of dbFile) {
          if (statusCache.containKey(file.path)) {
            continue;
          } else {
            statusCache.add(file.path,  {
              path: file.path,
              status: "success",
              fileID: file.fileid,
              sharePerm: file.remotePerm.includes("R"),
              perm: file.remotePerm,
              collect: false,
              isShared: false
            });
          }
        }
      }
    };
       global.statusCache = statusCache;
    

     
    并且使用防抖,把刷新的频率降低下来,

     debounce(
          () => {
            ipcRenderer.sendTo(this.mainID, "dirChange", filePath, evt);
          },
          2000,
          { maxWait: 5000 }
        )();
    

    经过这次的方案整改后,整体的感觉没有卡顿,用的比较流畅,当然后续还有优化空间

     

    总结

    用electron进行pc客户端的开发坑还是有点多的,特别是优化这一块,electron的优势是js和html,他的缺点也是js和html,本来是想用多线程做这次的优化的,发现js 的Web Worker太难用了,而且不能使用electron模块,这样在web Worker处理的逻辑就不能方便的通知到渲染进程,所以对于卡顿优化这一块,还是得通过其他方式进行优化,最最重要的是防止主进程阻塞。

  • 相关阅读:
    web前端(4)—— 常用标签1
    web前端(3)—— html标签及web页面结构
    web前端(2)—— 前端技术介绍
    web前端(1)——了解什么是前端,以及与后端的关系
    数据库之redis篇(2)—— redis配置文件,常用命令,性能测试工具
    数据库之redis篇(1)—— redis数据库安装,简单使用
    数据库之mysql篇(6)—— mysql常用函数函数/自定义函数
    洗礼灵魂,修炼python(91)-- 知识拾遗篇 —— pymysql模块之python操作mysql增删改查
    LINUX新建和增加SWAP分区
    Configuring SSL for SAP Host Agent on UNIX
  • 原文地址:https://www.cnblogs.com/eflypro/p/14074745.html
Copyright © 2020-2023  润新知