我在使用大量动画元素的页面上渲染速度时遇到了一些麻烦。有一个很大的<table>
(大约500行),还有一些JavaScript通过SSE读取更新的html,并用更新替换现有的行内容。如果我让后端全速运行,浏览器(Chrome或WebKitGtk +)绝对会窒息,所以我将其限制为每秒约100次更新。以此速率页面更新,但帧速率非常低,动画不稳定。
对于表中的行数而言,性能似乎对更新速率更敏感。例如,如果我将表中的行数减半,则动画比将更新速率减半的情况要平滑得多。
查看Chrome的典型帧渲染时间表,我看到一堆对我的EventSource'消息'监听器的调用,与HTML解析和DOM操作(大约280 ms)并行,这看起来是正确的,如果比我慢想。然后我看到大约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'之间随机变化,而'{1}}在'DnArrow'和'UpArrow'之间变化(数据代表股票价格变动)。其他课程保持不变。
相关的风格是:
<img>
JavaScript看起来像
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; }
我意识到我从我简陋的浏览器中提出了很多问题,但我能做些什么才能提高效率?
答案 0 :(得分:0)
我无法肯定地告诉你,但有一条建议不是要预先行。尝试通过直接操纵//-------------------------------------------------------------------
//Program: ClockTester
//Author: D. Spence
//Date: April 4, 2014
//Purpose: Tests the features of the Clock class
//-------------------------------------------------------------------
import java.util.Scanner;
public class ClockTester
{
public static void main (String[] args)
{
//Declare five objects in the Clock class
Clock c1, c2, c3, c4, c5;
//Initialize Clock objects using constructors
c1 = new Clock();
c2 = new Clock(15);
c3 = new Clock(8,30);
c4 = new Clock(12,5,45);
//Show all four objects
System.out.println("c1 is " + c1);
System.out.println("c2 is " + c2);
System.out.println("c3 is " + c3);
System.out.println("c4 is " + c4);
System.out.println();
//Determine if clock times are past noon
System.out.println(c1 + " is " + (c1.isPM() ? "after noon" : "at or before noon"));
System.out.println(c2 + " is " + (c2.isPM() ? "after noon" : "at or before noon"));
System.out.println(c3 + " is " + (c3.isPM() ? "after noon" : "at or before noon"));
System.out.println(c4 + " is " + (c4.isPM() ? "after noon" : "at or before noon"));
System.out.println();
//Manually set a value
c1.setTime(14,15,30);
System.out.println("Changed c1 to " + c3);
//Test for equality
System.out.print (c1 + " is ");
System.out.print ( (c1.equals(c3)) ? "equal" : "NOT equal");
System.out.println (" to " + c3);
System.out.println();
c5 = new Clock(15,0,0);
System.out.print (c5 + " is ");
System.out.print ( (c5.equals(c2)) ? "equal" : "NOT equal");
System.out.print (" to " + c2);
System.out.println();
//Demonstrate math operations
System.out.println ("\n Some Clock Operations:");
System.out.print (c1 + " + 10 hours is ");
c1.addHours(10);
System.out.println (c1);
System.out.print (c3 + " + 45 minutes is ");
c3.addMinutes(45);
System.out.println (c3);
System.out.print (c4 + " + 90 seconds is ");
c4.addSeconds(90);
System.out.println (c4);
System.out.print (c4 + " + 12:59:55 is ");
c4.addTime(12,59,55);
System.out.println (c4);
//TestBonus();
System.out.println();
System.out.println("This concludes the test of the Clock class.");
System.out.println();
}
/*
public static void TestBonus()
{
System.out.println("\n ****TESTING BONUS FEATURE****\n");
Clock c6 = new Clock(2,30,'p');
System.out.println ("Non-military clock time: " + c6);
c6.setMilitary (true);
System.out.println ("Same clock in military: " + c6);
}
*/
}
//-------------------------------------------------------------------
//Program: Clock
//Author: Taylor P.
//Date: November 30, 2016
//Purpose: Creates a clock class
//-------------------------------------------------------------------
public class Clock
{
private int hours;
private int minutes;
private int seconds;
private final int hours_Min = 0;
private final int hours_Max = 23;
private final int minutes_Min = 0;
private final int minutes_Max = 59;
private final int seconds_Min = 0;
private final int seconds_Max = 59;
//Constructor sets default time to midnight (00:00:00)
public Clock ()
{
this.hours = 00;
this.minutes = 00;
this.seconds = 00;
}
//Constructor sets hours to input value
public Clock (int h)
{
this.hours = h;
this.minutes = 00;
this.seconds = 00;
}
//Constructor sets hours and minutes to input value
public Clock (int h, int m)
{
this.hours = h;
this.minutes = m;
this.seconds = 00;
}
//Constructor sets hours, minutes, seconds to input value
public Clock (int h, int m, int s)
{
this.hours = h;
this.minutes = m;
this.seconds = s;
}
//-------------------------------
//Method: getHours
//Return: int - hours
//Parameters: none
//Purpose: returns hours
//-------------------------------
public int getHours()
{
return this.hours;
}
//------------------------------
//Method: getMinutes
//Return: int
//Parameters: none
//Purpose: returns minutes
//------------------------------
public int getMinutes()
{
return this.minutes;
}
//------------------------------
//Method: getSeconds
//Return: int
//Parameters: none
//Purpose: returns seconds
//------------------------------
public int getSeconds()
{
return this.seconds;
}
//------------------------------
//Method: isPM
//Return: boolean
//Parameter: none
//Purpose: Determines if the time is past noon
//------------------------------
public boolean isPM ()
{
if (this.hours < 12)
return false;
else
return true;
}
//------------------------------
//Method: setTime
//Return: void
//Parameter: 3 int types - hours, minutes, seconds
//Purpose: set time to (00:00:00) format
//-----------------------------
public void setTime (int h, int m, int s)
{
this.hours = h;
this.minutes = m;
this.seconds = s;
}
//-----------------------------
//Method: addHours
//Return: void
//Parameter: an int type of hours
//Purpose: to add hours together
//-----------------------------
public void addHours (int h)
{
this.hours = this.hours + h;
}
//-----------------------------
//Method: addMinutes
//Return: void
//Parameter: a int type of minutes
//Purpose: to add minutes together
//-----------------------------
public void addMinutes (int m)
{
this.minutes = this.minutes + m;
}
//----------------------------
//Method: addMinutes
//Return: void
//Parameter: an int type of seconds
//Purpose: to add seconds together
//----------------------------
public void addSeconds (int s)
{
this.seconds = this.seconds + s;
}
//-----------------------------
//Method: addTime
//Return: void
//Parameter: three int types of hours, minutes, seconds
//Purpose:
//-----------------------------
public void addTime (int h, int m, int s)
{
this.hours = this.hours + h;
this.minutes = this.minutes + m;
this.seconds = this.seconds + s;
}
//-----------------------------
//Method: equals
//Return:
//Parameter:
//Purpose:
//----------------------------
public boolean equals (Clock c)
{
boolean equiv = c.equals(c);
return equiv;
}
//------------------------------
//Method: toString
//Returns:
//Parameters:
//Purpose:
//-----------------------------
public String toString()
{
String string = "";
if (this.equals(this.hours) && this.equals(this.minutes) && this.equals (this.seconds))
{
string = "00:00:00";
}
else if (this.equals(this.hours))
{
string = "00";
string = string + ":" + this.minutes + ":" + this.seconds;
}
else if (this.equals(this.minutes))
{
string = "00";
string = this.hours + ":" + string + ":" + this.seconds;
}
else if (this.equals(this.seconds))
{
string = "00";
string = string + ":" + string + ":" + this.seconds;
}
else
string = string + ":" + this.hours + ":" + this.minutes + ":" + this.seconds;
return string;
}
}
和.innerHTML
,使用各自的值更新单个单元格而不依赖.textContent
。这至少应该删除你的HTML解析和DOM构建成本,可能会或可能没有帮助你的布局成本(这里不太确定,需要测试,但如果您的单元大小修复,它可能不需要重新计算,因为你“不改变任何方面。”