如何知道我的 JS 的哪一部分导致了延迟?

问题描述 投票:0回答:1

我是一名 javascript 初学者,我正在努力提高我的技能。 我目前正在通过网站制作画布和动画。

我想做的是“模拟”城市汽车交通。我知道它毫无用处,但它让我致力于编码的不同方面。

目前,我的代码正在按我想要的方式工作,但动画很慢并且有点滞后。有时,代码需要时间来计算汽车的位置。

以下是完整 HTML 页面的代码:

<!DOCTYPE html>
<html>
    <head>
    <meta charset="utf-8" />

    <style>
        *{
            margin: 0;
            position: absolute;
        }
        #background{
            z-index: 1;
        }
        #cars{
            z-index: 2;
        }
    </style>

</head>
<body>


    <p id='debug'></p>

    <canvas id="background"></canvas>
    <canvas id="cars"></canvas>

    <script type="text/javascript">

    // BACKGROUND CANVAS -------------------------------------------
        var background = document.getElementById("background");
        background.height=window.innerHeight;
        background.width=window.innerWidth;
        var bkg=background.getContext("2d");
    //--------------------------------------------------------------


    // ANIMATED CANVAS ------------------------------------------------
        var anim = document.getElementById("cars");
        anim.height=window.innerHeight;
        anim.width=window.innerWidth;
        var anm=anim.getContext("2d");
    // -------------------------------------------------------------




    // VARIABLES ------------------------------------------

        var width = anim.width;
        var height = anim.height;

        var numCars = 10;

        var numRoads = 7;

        if(width/numRoads/2<height/numRoads/2){
            var roadWidth = ~~(width/numRoads/2);
        } else {
            var roadWidth = ~~(height/numRoads/2);
        }

        var klaxon = new Audio('res/sounds/klaxon.wav');
    //------------------------------------------------------------------    



    // CROSSROAD LIST -----------------------------------
        var roads = [];

        for(i=0;i<numRoads+2;i++){
            for(j=0;j<numRoads+2;j++){
                var create = getRandomInt(3);
                if(create>0){
                    roads.push([~~(width/(numRoads+1)*j),~~(height/(numRoads+1)*i),1])
                } else {
                    roads.push([~~(width/(numRoads+1)*j),~~(height/(numRoads+1)*i),0])
                }
            }
        }
    // ------------------------------------------------------------




    // TURN LIST -----------------------------------------
        var turns = [];
        var roadLength = roads.length;
        for(i=0;i<roadLength;i++){
            var road = roads[i];
            if(road[2]==1){
                if(i>numRoads+1 && (i+1)%(numRoads+2)!=0 && (i)%(numRoads+2)!=0 && i<roadLength-(numRoads+2)){
                    var rightbot = [~~(road[0]+roadWidth/4),~~(road[1]+roadWidth/4),0,0,0,0];
                    var righttop = [~~(road[0]+roadWidth/4),~~(road[1]-roadWidth/4),0,0,0,0];
                    var leftbot = [~~(road[0]-roadWidth/4),~~(road[1]+roadWidth/4),0,0,0,0];
                    var lefttop = [~~(road[0]-roadWidth/4),~~(road[1]-roadWidth/4),0,0,0,0];
                    if(roads[i+1][2]==1){
                        var right = true;

                        rightbot[3] = 1;
                        leftbot[3] = 1;

                        lefttop[4] = 1;
                        leftbot[3] = 1;
                        rightbot[2] = 1;
                        righttop[5] = 1;
                    }
                    if(roads[i-1][2]==1){
                        var left = true;

                        righttop[5] = 1;
                        lefttop[5] = 1;

                        lefttop[4] = 1;
                        leftbot[3] = 1;
                        rightbot[2] = 1;
                        righttop[5] = 1;
                    }
                    if(roads[i+(numRoads+2)][2]==1){
                        var bot = true;

                        lefttop[4] = 1;
                        leftbot[4] = 1;

                        lefttop[4] = 1;
                        leftbot[3] = 1;
                        rightbot[2] = 1;
                        righttop[5] = 1;
                    }
                    if(roads[i-(numRoads+2)][2]==1){
                        var top = true;

                        rightbot[2] = 1;
                        righttop[2] = 1;

                        lefttop[4] = 1;
                        leftbot[3] = 1;
                        rightbot[2] = 1;
                        righttop[5] = 1;
                    }
                    turns.push(rightbot,righttop,leftbot,lefttop);
                }


            }
        }
    //----------------------------------------------------------------------------------




    // SPAWNPOINT LIST --------------------------------------------------
        var spawnPoints = [];
        for(i=1;i<roadLength;i++){

            if(i!=(numRoads+1) && i!=(roadLength) && i!=(roadLength-1) && i!=(roadLength-(numRoads+2))){

                var road = roads[i];
                if(road[2]==1){
                    if(i<numRoads+1 && roads[i+numRoads+2][2]==1){
                        var spawnPoint = [~~(road[0]-roadWidth/4),~~(road[1]),"bot"];
                        spawnPoints.push(spawnPoint);
                    } else if(((i+1)%(numRoads+2))==0 && roads[i-1][2]==1){
                        var spawnPoint = [~~(road[0]),~~(road[1]-roadWidth/4),"left"];
                        spawnPoints.push(spawnPoint);
                    } else if(i>=(numRoads+2)){
                        if(i>roadLength-(numRoads+2) && roads[i-(numRoads+2)][2]==1){
                            var spawnPoint = [~~(road[0]+roadWidth/4),~~(road[1]),"top"];
                            spawnPoints.push(spawnPoint);
                        } else if(i<roadLength){
                            if((i)%(numRoads+2)==0 && roads[i+1][2]==1){
                                var spawnPoint = [~~(road[0]),~~(road[1]+roadWidth/4),"right"];
                                spawnPoints.push(spawnPoint);
                            }
                        }
                    }
                }
            }
        }
    //---------------------------------------------------------------------------




    // BACKGROUND GEN ------------------------------------------------------
        bkg.beginPath();
        bkg.fillStyle = 'green';
        bkg.rect(0,0,width,height);
        bkg.fill();

        for(i=0;i<roadLength;i++){
            var road = roads[i];
            if(road[2]==1){
                if(i>numRoads+1 && (i+1)%(numRoads+2)!=0 && i<roadLength-(numRoads+2)){
                    if(roads[i+1][2]==1){

                        bkg.beginPath();
                        bkg.fillStyle = 'grey';
                        bkg.rect(road[0]-roadWidth/2,road[1]-roadWidth/2,roads[i+1][0]-road[0]+roadWidth,roadWidth);
                        bkg.fill();

                    }
                }
                if((i+1)%(numRoads+2)!=0 && i<roadLength-(numRoads+2) && (i)%(numRoads+2)!=0){
                    if(roads[i+numRoads+2][2]==1){

                        bkg.beginPath();
                        bkg.fillStyle = 'grey';
                        bkg.rect(road[0]-roadWidth/2,road[1]-roadWidth/2,roadWidth,roads[i+numRoads+2][1]-road[1]+roadWidth);
                        bkg.fill();

                    }
                }


            }
        }
        for(i=0;i<roadLength;i++){
            var road = roads[i];
            if(road[2]==1){
                if(i>numRoads+1 && (i+1)%(numRoads+2)!=0 && i<roadLength-(numRoads+2)){
                    if(roads[i+1][2]==1){

                        bkg.beginPath();
                        bkg.setLineDash([5, 3]);
                        bkg.strokeStyle = 'white';
                        bkg.moveTo(road[0],road[1]);
                        bkg.lineTo(roads[i+1][0],roads[i+1][1]);
                        bkg.stroke();
                        bkg.fill();

                    }
                }
                if((i+1)%(numRoads+2)!=0 && i<roadLength-(numRoads+2) && (i)%(numRoads+2)!=0){
                    if(roads[i+numRoads+2][2]==1){

                        bkg.beginPath();
                        bkg.setLineDash([5, 3]);
                        bkg.strokeStyle = 'white';
                        bkg.moveTo(road[0],road[1]);
                        bkg.lineTo(roads[i+numRoads+2][0],roads[i+numRoads+2][1]);
                        bkg.stroke();
                        bkg.fill();

                    }
                }


            }
        }

    //-----------------------------------------------------------------------------------------





    // CAR CLASS ---------------------------------------------------------------------------    
        function Car(){

            this.size = ~~(roadWidth/4);


            var rand = getRandomInt(spawnPoints.length);

            try {
                var initDir = spawnPoints[rand][2];
            } catch {
                location.reload(); 
            }

            this.x = spawnPoints[rand][0];
            this.y = spawnPoints[rand][1];

            switch(initDir){
                case "right":
                    this.dir = 0;
                    break;
                case "bot":
                    this.dir = (Math.PI)/2;
                    break;
                case "top":
                    this.dir = -(Math.PI)/2;
                    break;
                case "left":
                    this.dir = (Math.PI);
                    break;
            }

            this.timer = 0;

            this.speedRand = 2+Math.random();

            this.dx = Math.cos(this.dir)*(2+this.speedRand);
            this.dy = Math.sin(this.dir)*(2+this.speedRand);

            this.col = "red";
            //this.col = '#'+(~~(Math.random()*16777215).toString(16);
        }
    // -----------------------------------------------------------------------------------------




    // CAR LIST INIT ---------------------------------------------------------------
        var cars = [];
        for(i = 0 ; i < numCars ; i++){
            var car = new Car();
            cars.push(car);
        }
    //-----------------------------------------------------------------------------------------




        var backRect = document.getElementById("background");
        var intervalTurns = roadWidth/15;
        var turnsLength = turns.length;




    // DRAW UPDATE ----------------------------------------------------------------------------
        function draw(){

            // if(getRandomInt(50)==1){
                // var car = new Car();
                // cars.push(car);
            // }

            anm.globalAlpha = 0.1;
            anm.drawImage(backRect,0,0);
            anm.globalAlpha = 1;

            var carsLength = cars.length;
            for(i = 0; i < cars.length ; i++){
                var car = cars[i];
                anm.fillStyle=car.col;
                anm.beginPath();

                car.x = ~~(car.x+car.dx);
                car.y = ~~(car.y+car.dy);

                anm.rect(~~(car.x-car.size/2), ~~(car.y-car.size/2), car.size, car.size);
                anm.fill();

                if(car.timer==0){
                    for(j=0;j<turnsLength;j++){
                        var turn = turns[j];
                        if(car.x<turn[0]+intervalTurns && car.x>turn[0]-intervalTurns && car.y<turn[1]+intervalTurns && car.y>turn[1]-intervalTurns){

                            var possibleTurn = [];
                            for(i=2;i<turnsLength;i++){
                                if(turn[i]==1){
                                    possibleTurn.push(i);
                                }
                            }

                            var change = getRandomInt(possibleTurn.length);

                            var newDir = possibleTurn[change];



                            switch(newDir){
                                case 2:
                                    car.dir = -(Math.PI)/2;
                                    car.dx = Math.cos(car.dir)*(2+car.speedRand);
                                    car.dy = Math.sin(car.dir)*(2+car.speedRand);
                                    break;
                                case 5:
                                    car.dir = Math.PI;
                                    car.dx = Math.cos(car.dir)*(2+car.speedRand);
                                    car.dy = Math.sin(car.dir)*(2+car.speedRand);
                                    break;
                                case 4:
                                    car.dir = (Math.PI)/2;
                                    car.dx = Math.cos(car.dir)*(2+car.speedRand);
                                    car.dy = Math.sin(car.dir)*(2+car.speedRand);
                                    break;
                                case 3:
                                    car.dir = 0;
                                    car.dx = Math.cos(car.dir)*(2+car.speedRand);
                                    car.dy = Math.sin(car.dir)*(2+car.speedRand);
                                    break;
                            }
                            car.timer = 3;
                            break;
                        }
                    }
                } else if(car.timer > 0){
                    car.timer-=1;
                }

                if(car.x<0 || car.x>width || car.y<0 || car.y>height){
                    var rand = getRandomInt(spawnPoints.length);

                    try {
                        var initDir = spawnPoints[rand][2];
                    } catch {
                        location.reload(); 
                    }

                    car.x = spawnPoints[rand][0];
                    car.y = spawnPoints[rand][1];
                    //cars.splice(i,1);
                    switch(initDir){
                        case "right":
                            car.dir = 0;
                            car.dx = Math.cos(car.dir)*(2+car.speedRand);
                            car.dy = Math.sin(car.dir)*(2+car.speedRand);
                            break;
                        case "bot":
                            car.dir = (Math.PI)/2;
                            car.dx = Math.cos(car.dir)*(2+car.speedRand);
                            car.dy = Math.sin(car.dir)*(2+car.speedRand);
                            break;
                        case "top":
                            car.dir = -(Math.PI)/2;
                            car.dx = Math.cos(car.dir)*(2+car.speedRand);
                            car.dy = Math.sin(car.dir)*(2+car.speedRand);
                            break;
                        case "left":
                            car.dir = (Math.PI);
                            car.dx = Math.cos(car.dir)*(2+car.speedRand);
                            car.dy = Math.sin(car.dir)*(2+car.speedRand);
                            break;
                    }
                }
            }
        }
    //---------------------------------------------------------------------------------------


        setInterval(draw, 30);



    // KEYBINDS ------------------------------------------------------------------------
        document.body.onkeyup = function(e){
            if(e.keyCode == 32){
                klaxon.play();
            }
        }
    //-------------------------------------------------------------------------------

        function getRandomInt(max) {
            return ~~(Math.random() * max);
        }           
    </script>

</body>
</html>

我很确定滞后来自于绘制函数中对转弯的不断检查(因为有很多),但我想确保这是问题所在。

另外,我尝试使用

~~
而不是
Math.floor()
、列表长度变量和中断来减少延迟,但我不确定这会产生很大的差异,不是吗?

javascript arrays performance optimization html5-canvas
1个回答
2
投票

您可以使用任何主要现代浏览器中的开发人员工具查看代码将时间花在哪里。从菜单中选择开发工具,或按 Ctrl+Shift+I 或 F12(或在 Mac OS 上按 Cmd+Shift+I)。可能有一个“性能”或“分析”选项卡(例如,在 Chrome 中,它是“性能”)。您可以使用其中的功能来运行您的代码,并查看它在哪些功能上花费最多时间等。您的浏览器的开发工具可能会有相当详细的文档记录。有一篇关于使用 Chrome 性能选项卡的文章这里

© www.soinside.com 2019 - 2024. All rights reserved.