gpt4 book ai didi

javascript - 使用 Chrome DevTools 对 HTML5 图形进行渲染测量

转载 作者:太空狗 更新时间:2023-10-29 13:46:09 25 4
gpt4 key购买 nike

我想在 HTML5 中测量 canvas 和 svg 之间的性能。

到目前为止我已经完成了。我在 svg 和 canvas 中创建了多个圆圈。两者都有 500 x 500 的元素宽度和高度。

我发现我正在测量脚本编写时间。如果我在 Chrome 中使用开发工具,脚本时间几乎等于我测量的时间。现在,我如何测量渲染时间?将具有单独的 Canvas 和 svg 圆创建和 devtools 的代码用于渲染比较 svg 和 Canvas 渲染性能的好方法吗?

<html>
<head>
<script type="text/javascript">
var svgNS = "http://www.w3.org/2000/svg";
function createCircle1() {
var t3 = performance.now();
for (var x = 1; x <= 1000; x++) {
for (var y = 1; y <= 100; y++) {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(x, y, 5, 0, 2 * Math.PI);
ctx.stroke();

}
}
var t4 = performance.now();

console.log("canvas time " + (t4 - t3) + " milliseconds.")

var t0 = performance.now();
for (var x = 1; x <= 1000; x++) {
for (var y = 1; y <= 100; y++) {
var myCircle = document.createElementNS(svgNS, "circle"); //to create a circle, for rectangle use rectangle
myCircle.setAttributeNS(null, "cx", x);
myCircle.setAttributeNS(null, "cy", y);
myCircle.setAttributeNS(null, "r", 5);
myCircle.setAttributeNS(null, "stroke", "none");
document.getElementById("mySVG").appendChild(myCircle);
}
}
var t1 = performance.now();

console.log("svg time " + (t1 - t0) + " milliseconds.")
}
</script>
</head>
<body onload="createCircle1();">
<svg id="mySVG" width="500" height="500" style="border:1px solid #d3d3d3;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"></svg>
<canvas id="myCanvas" width="500" height="500" style="border:1px solid #d3d3d3;"></canvas>
</body>
</html>

This is the result of my code enter image description here

脚本编写时间和我测量的性能时间不知何故不同。谁能告诉我这种性能比较是否有用?

我做了多次测试,性能时间总是不同,但 canvas 在渲染和脚本方面比 svg 快。

为什么在渲染中?脚本应该是因为svg的DOM引用?

这个测试我用单独的 svg 和 Canvas 做了,我只是先渲染 svg,在下一个测试中只渲染 Canvas 。

最佳答案

SVG 的问题。

下面是在 Canvas 上画一个大圆圈和一张SVG图片的性能测试。

两者在我的机器和 chrome 上每圈 30 毫秒的性能大致相同。

运行测试并查看结果。如果您观察进度,您可能会注意到它开始稍微慢下来。当第一个测试运行时,再次单击该按钮,这次您会注意到速度变慢了很多。

进行第 3 次测试,速度仍然更慢,但是 Canvas 和 SVG 的每圈性能没有改变,减速从何而来。

DOM 不是 javascript。

向 SVG 添加节点的代码并不关心 SVG 有多少节点,但是当向 SVG 图像添加节点并且您的代码退出时,您已经通知 DOM 您的 SVG 元素已脏,需要重新绘制。

我在退出前将测试分为 ~10 组。这意味着每添加十个圆圈,DOM 将从头开始重新绘制所有 SVG 节点,并在 javascript 上下文和您衡量或控制它的能力之外重新绘制。

当您第二次单击测试时,SVG 已经有 10000 个圆圈,因此在添加前 10 个圆圈后,DOM 会愉快地重新渲染 10000+10 个圆圈。

准确衡量 SVG 性能几乎是不可能的。

使用时间轴

我用时间线记录运行了下面的代码片段。我运行了两次测试。

接下来的两张图片显示的是同一时期。最上面的一个在测试开始时,下一个在第二个测试结束时。

我已经标记了可能参与渲染 SVG 的 GPU 部分。请注意它们如何从微不足道变为过多。

enter image description here

enter image description here

此图显示了第二个测试周期中 10 个测试渲染的一个周期。代码执行在 ~1ms 时几乎看不到,但 GPU 耗费了巨大的 175ms 再次绘制所有 SVG 圆圈。

enter image description here

当您使用 SVG 时,您必须记住,当您对其进行更改时,DOM 将重新呈现所有内容。它不关心它是否可见。如果您更改大小,则会重新绘制。

要使用 SVG,您必须将所有调用捆绑到一个执行上下文中以获得最佳性能。

Canvas V SVG

SVG 和 Canvas 都使用具有非常相似着色器的 GPU 来完成工作。在 SVG 或 Canvas 中绘制一个圆需要相同的时间。 Canvas 相对于 SVG 的优势在于您可以控制渲染,何时何地。对于 SVG,您只能控制内容,对渲染几乎没有发言权。

    
var running = false;
var test = function(){
if(running){
return;
}
var mySVG = document.getElementById("mySVG");
var myCanvas = document.getElementById("myCanvas");
var ctx = myCanvas.getContext("2d");
var myCircle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
running = true;
const testCount = 1000;
const groupCount = 10;
var times = [[],[]];
var names =["Canvas test.","SVG test."];
var indexs = [0,0];
var tests = [function(){
now = performance.now();
ctx.beginPath();
ctx.arc(250, 250, 250, 0, 2 * Math.PI);
ctx.fill();
return performance.now()-now;
},
function(){
now = performance.now();
var circle = myCircle.cloneNode();
circle.setAttributeNS(null, "cx", 250);
circle.setAttributeNS(null, "cy", 250);
circle.setAttributeNS(null, "r", 250);
circle.setAttributeNS(null, "stroke", "none");
mySVG.appendChild(circle);
return performance.now()-now;
}];
for(var i = 0; i < testCount; i ++){ // preallocate and zeor arrays
times[0][i] = 0;
times[1][i] = 0;
}
var testComplete = false;
function doTests(){
for(i = 0; i < groupCount; i ++){
var testIndex = Math.floor(Math.random()*2);
times[testIndex][indexs[testIndex]] = tests[testIndex]();
indexs[testIndex] += 1;
if(indexs[testIndex] >= testCount){
testComplete = true;
return;
}
}
}
function getResults(){
// get the mean
var meanA = 0;
var meanB = 0;
var varianceA = 0;
var varianceB = 0;
var totalA = 0;
var totalB = 0;
for(var i = 0; i < testCount; i ++){ // preallocate and zero arrays
totalA += i < indexs[0] ? times[0][i] : 0;
totalB += i < indexs[1] ? times[1][i] : 0;
}
meanA = Math.floor((totalA / indexs[0]) * 1000) / 1000;
meanB = Math.floor((totalB / indexs[1]) * 1000) / 1000;

for(var i = 0; i < testCount; i ++){ // preallocate and zero arrays
varianceA += i < indexs[0] ? Math.pow((times[0][i] - meanA),2) : 0;
varianceB += i < indexs[1] ? Math.pow((times[1][i] - meanB),2) : 0;
}
varianceA = Math.floor((varianceA / indexs[0]) * 1000) / 1000;
varianceB = Math.floor((varianceB / indexs[1]) * 1000) / 1000;
result1.textContent = `Test ${names[0]} Mean : ${meanA}ms Variance : ${varianceA}ms Total : ${totalA.toFixed(3)}ms over ${indexs[0]} tests.`;
result2.textContent = `Test ${names[1]}. Mean : ${meanB}ms Variance : ${varianceB}ms Total : ${totalB.toFixed(3)}ms over ${indexs[1]} tests.`;

}

function test(){
doTests();
var p = Math.floor((((indexs[0] + indexs[1]) /2)/ testCount) * 100);
if(testComplete){
getResults();
p = 100;
running = false;
}else{
setTimeout(test,10);
}
progress.textContent = p+"%";
}

test()
}

startBut.addEventListener("click",test);
    #ui {
font-family : Arial;
}
    <div id="ui">
<h3>Comparative performance test</h3>
Adding circles to canvas V adding circles to SVG.<br> The test adds 1000 * 10 circles to the canvas or SVG with as much optimisation as possible and to be fair.<br>
<input id="startBut" type="button" value = "Start test"/>
<div id="progress"></div>
<div id="result1"></div>
<div id="result2"></div>
<h3>SVG element</h3>
<svg id="mySVG" width="500" height="500" style="border:1px solid #d3d3d3;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"></svg>
<h3>Canvas element</h3>
<canvas id="myCanvas" width="500" height="500" style="border:1px solid #d3d3d3;"></canvas>
</div>

关于javascript - 使用 Chrome DevTools 对 HTML5 图形进行渲染测量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42534559/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com