简体   繁体   中英

Why is setTimeout game loop experiencing lag when touchstart event fires?

This is a rather specific problem I'm having. The glitch only seems to appear in the latest update of Chrome for Android, so here are the specs:

Application Version: Chrome 45.0.2454.84

Operating System: Android 4.4.4; XT1031 Build/KXB21.14-L2.4

I'm using a Moto G, but the glitch also occurred on a Samsung running the same version of Chrome. Anyway, the problem is clearly that touchstart events interrupt my window.setTimeout game loop. Here's the code:

(
    function rafTouchGlitch() {
        /////////////////
        /* FUNCTIONS. */
        ///////////////

        function touchStartWindow(event_) {
            event_.preventDefault();
        }

        ///////////////////////
        /* OBJECT LITERALS. */
        /////////////////////

        var engine = {
            /* FUNCTIONS. */
            start : function(interval_) {
                var handle = this;

                (function update() {
                    handle.timeout = window.setTimeout(update, interval_);

                    /* Draw the background and the red square. */
                    display.fillStyle = "#303030";
                    display.fillRect(0, 0, display.canvas.width, display.canvas.height);

                    display.fillStyle = "#f00000";
                    display.fillRect(red_square.x, red_square.y, 20, 20);

                    /* Update the square's position. */
                    red_square.x++;

                    if (red_square.x > display.canvas.width) {
                        red_square.x = -20;
                    }
                })();
            },
            /* VARIABLES. */
            timeout : undefined
        };

        red_square = {
            /* VARIABLES. */
            x : 0,
            y : 0
        };

        /////////////////
        /* VARIABLES. */
        ///////////////

        var display = document.getElementById("canvas").getContext("2d");

        //////////////////
        /* INITIALIZE. */
        ////////////////

        window.addEventListener("touchstart", touchStartWindow);

        engine.start(1000 / 60);
    })();

This code works fine in any other browser and even in previous versions of Chrome. It worked fine in the last release, but for some reason now there's a problem. I'm not sure if this is a bug on Chrome's end or if they're doing something new and I'm the one not covering my bases, but the fact remains that there's a glaring lag in my game loop when touchstart events fire.

Here's a fiddle: https://jsfiddle.net/dhjsqqxn/

Tap the screen and see how the red square lags! It's ridiculous. You can basically freeze the Timeout object by tapping the screen fast enough.

If you have an Android phone, I urge you to update Chrome and visit the link to see what I mean. If this is a bug it's a huge one, considering how valuable setTimeout is and how vital touchstart is on mobile. If it's not a bug, I'd really like to know what I'm doing wrong.

Thanks for your time!

See https://bugs.chromium.org/p/chromium/issues/detail?id=567800

Android Chrome does not run scheduled(setTimeout/setInterval) callbacks during touchmove.

As a workaround you can try window.requestAnimationFrame() or run the callback manually in touchmove event which would require to keep/check a last-run time.

Do "return false;" at the end of the touchstart func.

for a swipe the following jquery without jquerymobile..

$("#id").on({'touchstart' : functionforstart, 'touchmove' :onmove, 'touchend' : functionforend});

functionforstart(e){ e.originalEvent.touches[0].pageX usw.. return false;}

function onmove(e){lastMove=e}

function functionforend(){lastMove.originalEvent.touches[0].pageX} usw..    e.prefentDefault(); }

That works for me.. var lastMove have to be global and you need a touchmove step to get the position in touchend.. hope this is also what you needed..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM