pgadmin的導出圖實現(xiàn)

PostgreSQL18的pgadmin中有一個ERDTool.jsx有1132行,這個體量理論上說非常龐大,但做過現(xiàn)實工程的都知道,其實只能算重組件中的mini尺寸了。pgadmin功能并不算有多豐富,怎么還是做成這樣呢,當然不是維護團隊不會拆分,畢竟還是做了199個jsx的。

首先映入眼簾的是registerEvents對19個EventBus的監(jiān)聽,這東西讓人倒吸一口涼氣,其中最醒目的莫過于this.eventBus.registerListener(ERD_EVENTS.DOWNLOAD_IMAGE, this.onImageClick),名字就不對勁,實現(xiàn)能如何呢?

這種百行級函數(shù),存在合理性且不論,無論如何它都不應該叫xxClick了,畢竟誰敢相信它所有的代碼都是為了完成一個導出png功能?

當然只籠統(tǒng)的說它完成了「一個功能」,那也是委屈它了,這函數(shù)實質(zhì)上究竟做了什么?

狀態(tài)管理: setLoading。

DOM 劫持: 直接操作樣式和類名。

復雜的幾何計算: 處理包圍盒(Bounding Box)。

IO 操作: 生成圖片并觸發(fā)下載。

異常處理: 恢復狀態(tài)彈出 notifier 警告。

每一項都是焦點,如果換成Java,這段代碼還能再套上10個trycatch膨脹到500行,當然如果換成Java必然能規(guī)矩許多,不至于如此粗糙。

當然這函數(shù)遠不止違法單一原則那么簡單,幾何計算中 margin = 10 和屏幕坐標轉(zhuǎn)換邏輯非常硬核且粗糙,幾乎宣判了這塊UI已經(jīng)不可更改了,同時否定了縮放/偏移變化,非常容易出 off-by-one 錯誤,已經(jīng)消耗極大了,不想做復雜只想簡單實現(xiàn)也可以克隆DOM做一個離屏渲染,還不需要關(guān)心什么margin偏移。

toPng還是html-to-image的,這種場景用這個本身就如同兒戲,而且既然都做這么復雜了,哪怕直接再補上一套原生代碼,手動繪制,全丟這函數(shù)里,不用任何庫,這段代碼也不會更丑了。

檢測到圖片到了瀏覽器 canvas 限制,就直接剪裁+警告,不做一個執(zhí)行前popup確認和zoom,可以說有些不可理喻了,現(xiàn)實中這個警告幾乎不可能彈出來,因為符合的這個邏輯時,其占用的原始內(nèi)存將達到驚人的 4GB,做這種巨型 DOM 樹時UI會進行密集的像素計算。而且計算是同步的,會直接鎖死瀏覽器主線程!程序早已卡死,一行代碼都別想執(zhí)行了。

還有setTimeout為什么 1000ms?為什么不是 500 或 2000?這是典型的“等它渲染完”的 hack,因為修改 transform / width/height 后,瀏覽器需要時間重排/重繪,html2canvas才能捕獲正確內(nèi)容。用requestAnimationFrame 循環(huán)檢查或MutationObserver/ResizeObserver來檢測實際變化完成不好么?

最后還是回到名字上,一個函數(shù)如果叫“xx點擊”,它就沒有資格去負責“計算并導出32767像素的位圖”。

patek-shs.fdcpx.net

patek-bjs.fdcpx.net

patek-shenzhen.fdcpx.net

patek-shenzhen.longinesshwx.com

patek-shs.biaoshouhou.cn

patek-bjs.biaoshouhou.cn

patek-shenzhen.biaoshouhou.cn

patek-gzs.biaoshouhou.cn

patek-shs.szwatchpg.cn

patek-shs.buchererweixiu.com

patek-shenzhen.buchererweixiu.com

patek-gzs.buchererweixiu.com

patek-shs.audemarsweixiu.com

patek-bjs.audemarsweixiu.com

patek-shenzhen.audemarsweixiu.com

patek-shenzhen.mosershwx.com

patek-shs.hidcwatch.com

patek-bjs.hidcwatch.com

patek-shenzhen.hidcwatch.com

patek-gzs.hidcwatch.com

patek-shs.kpkwatch.com

patek-shs.watchgz.cn

patek-shenzhen.watchgz.cn

patek-gzs.watchgz.cn

patek-shs.fjfsx.com

patek-bjs.fjfsx.com

patek-shenzhen.fjfsx.com

patek-shenzhen.tagheueru.cn

patek-shs.hntwx.cn

patek-bjs.hntwx.cn

patek-shenzhen.hntwx.cn

patek-gzs.hntwx.cn

patek-shs.ywbzn.com

patek-shs.aysza.cn

patek-shenzhen.aysza.cn

patek-gzs.aysza.cn

patek-shs.hx626.com

patek-bjs.hx626.com

patek-shenzhen.hx626.com

patek-shenzhen.ernestshwx.com

patek-shs.watchjwf.cn

patek-bjs.watchjwf.cn

patek-shenzhen.watchjwf.cn

patek-gzs.watchjwf.cn

patek-shs.watchrhc.cn

patek-shs.zzjshd.com

patek-shenzhen.zzjshd.com

patek-gzs.zzjshd.com

patek-shs.shjshdzb.com

patek-bjs.shjshdzb.com

不過綜合來說,這東西整體上也算勉強還行了,畢竟它是一個最終節(jié)點組件,而且基本上不太可能被依賴,只是功能性問題,不像它旁邊那個1560行有15個useEffect的ResultSet.jsx,那都不能叫組件了,那是試圖給React塞一個子系統(tǒng),等PostgreSQL20發(fā)布,估計就沒人敢改它了。還有用1300行的FormInput.tsx管理著FormIcon、StyledGrid、FormInput、InputSQL、FormInputSQL等子組件的超級組件,這幾乎是想做一套擴展UI庫。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容