2014/01/21

[心得] UltraWebGrid 全選時的效能問題

公司的 Grid 設定每一個 Row 前面會有一個 Checkbox,checkbox 按下去時會去觸發一個 onclick 事件,去檢查所選中的 Rows 的值來判斷畫面上的某些功能作用 or 不作用

另外產品也另外做了一個控件,負責處理全選/全不選等等,該控件的功能為選取(取消選取)全部的checkbox,並且用 fireEvent (for IE) 觸發每 Row 上 checkbox 的 onclick 事件去檢查畫面上的功能於目前的狀態是否適用

素晴らしいです ~~!


but!

在目前的這個案子中,這個功能不知道被怎麼改的,按下全選之後竟然要拖到超過一分鐘才能把所有的資料給選起來,甚至是偶爾在某些功能區一筆一筆勾選時就會選到要當掉去

於是...  讓他變成跟產品差不多快的任務就出現了 XD

仔細看一下 code 會發現,在觸發 checkbox 的 onclick 時會執行這個 function:


  1. function SelectRow(aaaaa, bbbbb, ccccc, ddddd, eeeee) {
  2. //... 前略 ...
  3. if (HidValue > 1 && document.getElementById(strPreText + "hidType").value == "1") {
  4. if (sc == "Y" && scur1 == "Y") {
  5. //...
  6. }
  7. else if (FnChk(strCODE) == false)
  8. {
  9. //...
  10. }
  11. else if (scur1 == "Y" && sc == "N" && end1 == "Y" && end == "N"
  12. && strHdlTrue == "Y" && strHdlFalse == "N" && FnChk(strCODE)) {
  13. //...
  14. }
  15. else if (scur1 == "N" && sc == "Y" && end1 == "Y" && end == "N"
  16. && strHdlTrue == "Y" && strHdlFalse == "N" && FnChk(strCODE)) {
  17. //...
  18. }
  19. else if (scur1 == "Y" && sc == "N" && end1 == "N" && end == "Y"
  20. && strHdlTrue == "Y" && strHdlFalse == "N" && FnChk(strCODE)) {
  21. //...
  22. }
  23. else if (scur1 == "N" && sc == "Y" && end1 == "N" && end == "Y"
  24. && strHdlTrue == "Y" && strHdlFalse == "N" && FnChk(strCODE)) {
  25. //...
  26. }
  27. }
  28. //... 後略 ...
  29. }

先不管這一堆 if else 的code 是不是很髒 XD

在 SelectRow 這個 funciton 裡面有好幾個地方 call 了 FnChk 這個 Funciton 並傳入了 strCODE 的值

那再來看看這個 FnChk 做了啥事:

  1. function FnChk(strCODE) {
  2. var xmlHttp = GetXmlHttpRequest();
  3. strpass = "XXXXXXXXX.ASPX?vstrCODE=" + escape(strCODE) + "&Flag=3";
  4. xmlHttp.open("POST", strpass, false);
  5. xmlHttp.send("");
  6. var result = xmlHttp.responseText;
  7. if (result == "NO")
  8. return false;
  9. else
  10. return true;
  11. }

他做的事情是
  1. 拿到一個變數
  2. 發起一個 XmlHttpRequest
  3. 取回 XmlHttpRequest 回傳的字串
  4. 檢查當回傳字串為"NO"時 return false;
用 XmlHttpRequest 在資料勾選時才回去檢查目前這筆資料的狀態是有其用處在,避免使用者在同一個畫面下停留太久 Grid 的資料已經不是最新的狀態下還針對過期資料做處理

但是....

在一次 SelectRow 執行的途中針對同筆資料重複的去發起 XmlHttpRequest 判斷狀態的作法通常取回的都會是同一個狀態,上面的 code 就花了 5 個連線只為了要一個 Boolean (實際上的code更多...)

而這個問題也間接導致了全選時效率低到哭的問題

假設有 200 筆資料被全選將會對 server 發起 1000 次連線,同時有 10 個人在這個功能上對200筆資料做全選就會發起 10000 次連線

如果 Server 爛一點就會被當做駭客攻擊了 XD

比較健康的作法應該是在 function 的一開始就把這個 Boolean 給拿回來

  1. var chk= FnChk(strCODE);

然後針對這個 chk 去判斷就好了

或者是少用的功能等到那個功能被點下去時再發起 XmlHttpRequest 去檢查資料的正確性

又或者是如果這個資料的異動幾乎不可能存在 (譬如資料的 CreateDate or CreateUser),那更可以在 Grid 撈資料的同時就先撈到 Row 裡面用 Hidden 的方式記住

把 XmlHttpRequest 從這個 function 拔掉之後,Grid 就重振雄風了~  全選超快的科科

沒有留言:

張貼留言