[英]How can I speed up HTML manipulation via Javascript, and/or improve rendering speed of animations?
我在包含許多動畫元素的頁面上渲染速度時遇到一些麻煩。 有一個很大的<table>
(約500行),還有一些JavaScript通過SSE讀取更新的html,並用更新替換了現有的行內容。 如果我讓后端全速運行,那么瀏覽器(Chrome或WebKitGtk +)絕對會阻塞,因此我將其限制為每秒約100次更新。 頁面以這種速率更新,但是幀速率非常低,動畫也很生澀。
對於表中的行數,性能似乎比對更新速率更敏感。 例如,如果我將表中的行數減半,則動畫比我將更新率減半的平滑得多。
查看Chrome的時間軸以獲取典型的幀渲染,我看到了對EventSource'消息'偵聽器的大量調用,同時還進行了HTML解析和DOM操作(大約280毫秒),這似乎是正確的,如果比我想的要慢的話。 然后,我看到大約50毫秒的“重新計算樣式”,113毫秒的“布局”,30毫秒的“更新層樹”和30毫秒的“繪畫”,它們都是串行執行的,即沒有其他任何事情同時發生。
在更新頁面時,CPU圖形顯示一個內核處於100%的狀態,而其他內核則基本上處於空閑狀態。 因此,我猜想WebKit正在使用單個線程來進行布局等,並且使該線程負擔過重。
頁面結構基本上是:
<html>
<body>
<div class='mainTable'>
<table id='mainTable' style="width:100%">
<thead><!-- header stuff --></thead>
<tbody>
<!-- About 500 <tr>s -->
</tbody>
</table>
</div>
<script src='quotes/tickUpd.js' type='text/javascript'></script>
</body>
</html>
每個〜500 <tr>
看起來像:
<tr id = 'IBM'>
<td class='cond'>128</td>
<td class='exch'>*</td>
<td class='size'>1</td>
<td class='tickDown'>88.53<img class='arrow' src='quotes/DnArrow.png'/></td>
<td class='symb'>GPC</td>
<td class='tickDown'>102.66<img class='arrow' src='quotes/DnArrow.png'/></td>
<td class='size'>1</td>
<td class='exch'>*</td>
<td class='time'>02:13:24.455186</td>
</tr>
<tr>
的id用於查找行,並且更新僅包含一系列<td>
。 類'tickDown'的<td>
通常在該類和'tickUp'之間隨機變化,而<img>
在'DnArrow'和'UpArrow'之間變化(數據代表股價走勢)。 其他類別保持不變。
相關樣式為:
div.mainTable { width: 100%; font-size: 12px; columns: 32em; }
.symb { color: red; text-shadow: 1px 1px rgba( 0, 0, 0, .6 ); }
@keyframes greenToBlack { from { background-color: #69BE28; } }
.tickUp { animation: greenToBlack 2s;color: white; }
@keyframes redToBlack { from { background-color: red; } }
.tickDown { animation: redToBlack 2s; color: white; }
@keyframes greenToRed { from { color: #69BE28; } to { color: red; } }
.symb { animation: greenToRed 30s; }
.arrow { vertical-align: middle; width: 5px; height: 5px; }
JavaScript看起來像
document.addEventListener( "DOMContentLoaded",
function(event) {
var rows = document.getElementById('mainTable').rows;
new EventSource("/upd").addEventListener(
'message',
function(event) {
var update = JSON.parse(event.data);
var row = rows.namedItem(update.rowId);
row.innerHTML = update.html;
// Was previously: $("tr#"+update.rowId).html(update.html);
}
);
}
);
我意識到我在低調的瀏覽器中提出了很多要求,但是我可以做些什么使它更有效嗎?
我不能肯定地告訴你,但是一個建議是不要預渲染行。 嘗試通過直接操作.textContent
和.classList
,以不依賴.innerHTML
使用其各自的值更新單個單元格。 這至少應該消除您的HTML解析和DOM構造成本,並且可能會或可能不會幫助您節省布局成本(此處不太確定,需要進行測試,但是如果您確定了單元格的大小,則可能不需要像您一樣重新計算它不會更改任何尺寸)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.