iT邦幫忙

0

js執行效能寫法問題

chan15 2010-08-26 08:03:3210257 瀏覽

今天客戶有一個需求
就是把一個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

12
fillano
iT邦超人 1 級 ‧ 2010-08-26 10:39:01
最佳解答

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

8
pantc328
iT邦研究生 1 級 ‧ 2010-08-26 09:50:04

1萬3千多筆.你8秒完成已經很快了.
但~你要寫什麼系統?
你是寫資料系統?還是寫資訊系統?
一般資訊系統是使用者要什麼就給什麼,有非常多的View去做.比如要看什麼統計,要看哪一個細目.系統可以很快的帶到.
資料系統就跟你寫的一樣,一次好幾萬筆沒處理完整呈現.
一次1萬3千筆.使用者會一筆筆去看嗎?
我覺得你可以用分頁處理.或特殊的運算.比如使用者看到第500筆前,將接下來500筆算出來.
使用者沒看到的就不用Show.

chan15 iT邦新手 5 級 ‧ 2010-08-26 10:10:24 檢舉

我只是要把客戶很醜的報表轉成漂亮的,並且賦予像excel的凍結欄跟凍結列效果
不是一萬三千多筆,是一個table一次有一萬三千多個td
我不能用分頁,因為table一體成形

4
sula3065408
iT邦研究生 1 級 ‧ 2010-08-30 09:07:37

一般都會做分頁吧!
這麼多筆的資料,使用者一次也看不完,我是認為要做分頁,可能是每次10、25、100筆的給,我是會做出動態的連結去切換頁面,連結去Query你要的資料範圍,一來是Query的速度快,再者是使用者那端的資料處理量也不會太大導致處理速度過慢。

看更多先前的回應...收起先前的回應...
fillano iT邦超人 1 級 ‧ 2010-08-30 09:57:21 檢舉

他的問題應該不在這裡啦...

不過這個需求還蠻奇怪,應該要跟客戶好好溝通,不要用這類補釘的方法來做。架構能解決的問題比用技術解決效率差很多。

chan15 iT邦新手 5 級 ‧ 2010-08-30 10:50:06 檢舉

他們頁面是excel直接產出的,也沒有什麼辦法改架構或內容,因為東西就是這麼多,只能硬幹

fillano iT邦超人 1 級 ‧ 2010-08-30 17:30:54 檢舉

如果可以另存成CSV格式,處理起來還比較方便...

chan15 iT邦新手 5 級 ‧ 2010-08-31 11:18:37 檢舉

CSV不是只有逗號或tag嗎?如何處理layout部份?

sula3065408 iT邦研究生 1 級 ‧ 2010-09-03 14:49:35 檢舉

IE對Javascript本來就很慢,可能需要用空間換時間出來,你架構要改掉吧!
把Table的資料格式先一筆一筆的讀入記憶體內,再以你想要呈現的方式一次呈現出來,刪除舊的表格,會比較快一點。(與樓上意見相同)

fillano iT邦超人 1 級 ‧ 2010-09-05 09:22:27 檢舉

layout就要自己做阿...CSV資料處理起來很快的。要固定的列,你再把他filter出來。

6
logoooit
iT邦新手 4 級 ‧ 2010-09-05 07:39:59

如果你想設計一個可以存取大量資料的 UI

你需要懂一些 Javascript 的 奇技淫巧 及 Pure DOM (不倚賴 Library 操作 DOM)

搞這種設計只能硬幹,如果真的在逼不得已的情況下還是得做這玩意

也許你可以參考一下小弟的設計方向

首先,先計算客戶的表格欄與列的數量及儲存格的尺寸大小
(不少的儲存格尺寸皆一致,算其中一個也可以)

然後將表格內的儲存格全部讀出來,存放到陣列變數裡面

事先藏好的容器也只要用三個就好 (左上、左下、右上) 並利用 CSS (position、z-index 屬性) 將容器疊在你表格的上面,再幫它設一個 overflow 的屬性,值為 hidden

當使用者使用凍結欄或列時

可以利用使用者滑鼠在按下畫面時的座標、畫面捲軸的位置、儲存格的寬高、表格的寬高

推測出使用者的欲凍結的是哪一列或哪一欄

然後將計算結果換算成索引位置,並利用欄列長度
去推出左上、左下、右上容器,會用到的儲存格的索引位置

再分別透過這些位置,從陣列變數抽取會用到的資料,放到對應的容器內,顯示在網頁上

至於有關凍結窗格的捲動,除了左上方的可以不需要外

可以根據使用者捲動畫上的水平或垂直捲軸,去決定右上或左下的容器需不需要同步

我這個方法,除可以了達到像 Excel 凍結窗格般的效果外

再效能上有很大的改善,你可以參考一下。

chan15 iT邦新手 5 級 ‧ 2010-09-06 10:34:40 檢舉

其實你的講法跟我的寫法好像差不多…

logoooit iT邦新手 4 級 ‧ 2010-09-06 11:31:54 檢舉

順便說,find 裡面 還有 find 是一見很可怕的事情

logoooit iT邦新手 4 級 ‧ 2010-09-06 11:32:32 檢舉

資料少是感受不出來,但資料量一大,效能是你無法想像的低落

我要發表回答

立即登入回答