今天客戶有一個需求
就是把一個excel匯出成html的table吃進來之後
偵測td裡面幾個關鍵字變化表格
例如說凍結欄,凍結列
小弟製作凍結欄凍結列的方法是
偵測好座標之後
將table以此兩座標切割成4塊table重組擺進容器裡
處理上百個td的報表都游刃有餘
上千個td也還ok
但有的表格有1萬3千多的td
在firefox跑8秒會出現結果
在chrome跑5秒會出現結果
但在IE會出現js執行過久是否要停止的警告
我覺得現在的code已經沒有什麼可以再精簡的空間了
因為重點是td過多吧
1萬3千多個td,我連跑個基本td迴圈檢查IE都快死了
所以不知道有沒有比較好得作法可以分攤js的執行可以讓警告不要出現
我本想把程式碼貼到這,可是ithome可輸入字數很少
若想要看code的話可以移駕至小舖
http://www.blueshop.com.tw/board/show.asp?subcde=BRD20100826080137CSQ&fumcde=FUM20041006152641OLG
jQuery不是萬靈丹,雖然他速度很快,但是你對DOM用了幾十個query把結果做出來,再加上資料筆數,這個延遲是很可怕的。對樹做大量的訪問本來就是很吃重的運算。
而且你的操作中,不斷的做訪問與dom tree reflow,這是最影響速度的操作,Javascript本身的速度很快,但是改變DOM時速度就很慢了。通常對於Javascript效能的建議中,有一個重點就是盡量集中做reflow的動作,減少reflow次數,以提高程式效率。這個過程如果還包在迴圈中,後果會更恐怖。
所以在你的例子中,要提高效能的話,建議一次把表格中所有的值parse到一個Object或陣列中,然後再一次產生新的表格。舊的表格就刪掉吧。
建議你看看:
http://www.yuiblog.com/blog/2008/12/23/video-crockford-performance/
<object height="322" width="512"><param name="movie" value="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.46"></param><param name="allowFullScreen" value="true"></param><param name="AllowScriptAccess" value="always"></param><param name="bgcolor" value="#000000"></param><param name="flashVars" value="id=11157560&vid=4141759&lang=en-us&intl=us&thumbUrl=http%3A//l.yimg.com/a/p/i/bcst/videosearch/6543/76907810.jpeg&embed=1"></param><embed allowfullscreen="true" allowscriptaccess="always" bgcolor="#000000" flashvars="id=11157560&vid=4141759&lang=en-us&intl=us&thumbUrl=http%3A//l.yimg.com/a/p/i/bcst/videosearch/6543/76907810.jpeg&embed=1" height="322" src="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.46" type="application/x-shockwave-flash" width="512"></embed></object>Douglas Crockford: "Ajax Performance" @ Yahoo! Video
1萬3千多筆.你8秒完成已經很快了.
但~你要寫什麼系統?
你是寫資料系統?還是寫資訊系統?
一般資訊系統是使用者要什麼就給什麼,有非常多的View去做.比如要看什麼統計,要看哪一個細目.系統可以很快的帶到.
資料系統就跟你寫的一樣,一次好幾萬筆沒處理完整呈現.
一次1萬3千筆.使用者會一筆筆去看嗎?
我覺得你可以用分頁處理.或特殊的運算.比如使用者看到第500筆前,將接下來500筆算出來.
使用者沒看到的就不用Show.
一般都會做分頁吧!
這麼多筆的資料,使用者一次也看不完,我是認為要做分頁,可能是每次10、25、100筆的給,我是會做出動態的連結去切換頁面,連結去Query你要的資料範圍,一來是Query的速度快,再者是使用者那端的資料處理量也不會太大導致處理速度過慢。
他的問題應該不在這裡啦...
不過這個需求還蠻奇怪,應該要跟客戶好好溝通,不要用這類補釘的方法來做。架構能解決的問題比用技術解決效率差很多。
他們頁面是excel直接產出的,也沒有什麼辦法改架構或內容,因為東西就是這麼多,只能硬幹
如果可以另存成CSV格式,處理起來還比較方便...
如果你想設計一個可以存取大量資料的 UI
你需要懂一些 Javascript 的 奇技淫巧 及 Pure DOM (不倚賴 Library 操作 DOM)
搞這種設計只能硬幹,如果真的在逼不得已的情況下還是得做這玩意
也許你可以參考一下小弟的設計方向
首先,先計算客戶的表格欄與列的數量及儲存格的尺寸大小
(不少的儲存格尺寸皆一致,算其中一個也可以)
然後將表格內的儲存格全部讀出來,存放到陣列變數裡面
事先藏好的容器也只要用三個就好 (左上、左下、右上) 並利用 CSS (position、z-index 屬性) 將容器疊在你表格的上面,再幫它設一個 overflow 的屬性,值為 hidden
當使用者使用凍結欄或列時
可以利用使用者滑鼠在按下畫面時的座標、畫面捲軸的位置、儲存格的寬高、表格的寬高
推測出使用者的欲凍結的是哪一列或哪一欄
然後將計算結果換算成索引位置,並利用欄列長度
去推出左上、左下、右上容器,會用到的儲存格的索引位置
再分別透過這些位置,從陣列變數抽取會用到的資料,放到對應的容器內,顯示在網頁上
至於有關凍結窗格的捲動,除了左上方的可以不需要外
可以根據使用者捲動畫上的水平或垂直捲軸,去決定右上或左下的容器需不需要同步
我這個方法,除可以了達到像 Excel 凍結窗格般的效果外
再效能上有很大的改善,你可以參考一下。