前面我用React + AntDesign 實現了一個簡單的時序圖,可是後來有了更復雜的需求,而且要求同時展現2000個任務的展現,這就涉及到了性能問題,本人先使用React+antd+ts實現了一個基本知足下面需求的demo,可是react的渲染機制形成了較大的性能問題,利用chrome自帶的Performance,測試發現demo的首次渲染高達10s以上,而且後續的操做也會使整個頁面很是卡。時序圖設計到的摺疊和展開功能涉及到整個頁面的重繪,通過思索後決定使用原生js+css去實現,由於原生js下性能是最優的。javascript
下面先來講說新版本的需求:css
圖一:html
圖二:前端
鼠標縮放產生時序圖X軸的縮放。時序圖的縮放,在這裏提供三種思路:html5
三種思路的優缺點:java
// 計算寬度百分比的函數
// endTime: 任務的結束時間
// startTime: 任務的開始時間
// maxTime: 全部任務結束時間最大的值
// minTime: 全部任務開始時間最小的值
// time: 全部任務開始時間與結束時間的排序 升序
// task_width: 任務的長度、水平鏈接線的長度、垂直鏈接線的left值
const widthFun = function (endTime, startTime, maxTime, minTime) {
const task_width =
(((Number (endTime) - Number (startTime)) /
((maxTime || time[time.length - 1]) - (minTime || time[0])) *
(body_width - tree_box_dom.offsetWidth)) / dom.offsetWidth)*100;
return task_width> 100 ? 100 : task_width;
};
複製代碼
先放推理過程圖:react
// 上圖解釋
// dom = 時序圖的dom元素
// domL1, domeL2 = dom.scrollLeft;
// domeL1表示前一次的dom.scrollLeft;
// domeL2表示當前的dom.scrollLeft;
// scale 表示當前的放大的比例
// scale1 表示上一次的放大比例
// tree_dom.offsetWidth表示左側樹的寬度
// clientX1 表示上一次的鼠標位置距離時序圖左側的距離 = e.clientX - tree_dom.offsetWidth
// clientX2 表示當前鼠標位置距離時序圖的距離
<!-- 當鼠標縮放時,獲得公式 -->
domL2 = domeL1(scale/scale1) + clientX1(scale/scale1) - e.clientX + tree_dom.offsetWidth
// 公式講解:
// 1. scale/scale1表示本次的縮放比例除以上一次的縮放比例,表示當前的縮放比例
// 左側捲去的寬度在第二次縮放時也會跟着縮放,因此左側的寬度須要乘以縮放比例
// 鼠標位置距離時序圖左側的寬度在縮放時也會跟着縮放,因此也要乘以縮放比例
// 最後面減去鼠標位置距離時序圖左側的實際距離就等於縮放時左側捲去的長度
// 頁面代碼
time_box_parent.scrollLeft = (time_box_parent.scrollLeft + e.clientX - tree_box_dom.offsetWidth) * (scale_x / scale_x1) - e.clientX + tree_box_dom.offsetWidth;
複製代碼
方案:css3
優缺點:git
實現思路:github
用一個變量記錄每一個任務的層級深度,層級深都以當前任務的父任務爲起點,就是說是從哪一個任務產生的當前任務,同級的子任務進行累加操做。用累加的變量按照必定的比例獲取垂直連線的高度以及水平連線的top值,水平連線的長度由任務的建立時間和開始時間決定。(使用上面的寬度百分比函數)
這個比較簡單,實現思路:
由於本demo的時間4刻度是個刻度,判斷最小時間戳與最大時間戳之間的差除以4,是否還有一天的時間(60 * 60 * 24,換算成秒),從大到小的降序獲取時間單位。
使用原生js+html+css比使用框架渲染大量demo性能更好。完成了一樣的效果與功能,使用chrome工具測試,渲染時間直用了1.3s左右,相較於以前的性能提升了10倍以上。固然框架有框架的優點,React中,render執行後得到的並非真正的DOM節點,而是一個虛擬的Virtual DOM (JavaScript對象),虛擬DOM具備batching(批處理)和高效的Diff算法,虛擬DOM與真實DOM造成對比,當虛擬DOM發生變化時,把變化的部分同步到真實的DOM上面去,造成局部更新。假如咱們2000個元素分紅20個邏輯塊,每一個邏輯塊包含50個元素,這時若是咱們採用React的話就只須要更新對應的邏輯塊,在這種狀況下React的Virtual DOM的渲染效率就會更高。由於咱們的時序圖是整個頁面的刷新,大量DOM的重繪,因此用原生效率更高。最後在多說一句:框架要會用,原生是根本。
思路指導:yalishizhude
參考資料:
做者信息:寧文飛,人和將來大數據前端工程師