公司需要做一個同步盤的用戶端,架構技術選型方面使用了支援跨平台的Electron架構,其中一些核心功能就是檔案的上傳,和下載下傳,考慮到node操作檔案比較友善,起初把檔案的下載下傳上傳操作放到主程序,在大量檔案下載下傳和上傳時,造成了界面的卡頓,現在就這個問題進行剖析和優化。
方案一
首先要确定是什麼因素導緻的卡頓,在平時,沒有上傳下載下傳檔案時,electron用戶端沒有出現卡頓的情況,然後對下載下傳的流程進行跟蹤,通過列印log日記發現,在執行一個方法後後面的log無法輸出,然後界面失去了響應,其代碼如下
好家夥,在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)
);
就是這段代碼。
于是我就将擷取狀态的方案重新整改。通過緩存的方式擷取,放到主程序的全局變量裡,兩個渲染程序共同操作這個全局變量
并且使用防抖,把重新整理的頻率降低下來,
經過這次的方案整改後,整體的感覺沒有卡頓,用的比較流暢,當然後續還有優化空間
總結
用electron進行pc用戶端的開發坑還是有點多的,特别是優化這一塊,electron的優勢是js和html,他的缺點也是js和html,本來是想用多線程做這次的優化的,發現js 的Web Worker太難用了,而且不能使用electron子產品,這樣在web Worker處理的邏輯就不能友善的通知到渲染程序,是以對于卡頓優化這一塊,還是得通過其他方式進行優化,最最重要的是防止主程序阻塞。