如何通过Javascript加速HTML操作,和/或提高动画的渲染速度?

时间:2016-12-01 04:19:56

标签: javascript html css google-chrome webkit

我在使用大量动画元素的页面上渲染速度时遇到了一些麻烦。有一个很大的<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; }

我意识到我从我简陋的浏览器中提出了很多问题,但我能做些什么才能提高效率?

1 个答案:

答案 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构建成本,可能会或可能没有帮助你的布局成本(这里不太确定,需要测试,但如果您的单元大小修复,它可能不需要重新计算,因为你“不改变任何方面。”