2016-12-01 2 views
1

Meine Aufgabe ist es, um ein div in einer HTML-Seite zu ziehen, und es so schnell wie möglich zu tun, weil die Zielplattform ist beweglich (Chrome Android) Aber ich fand es ein bisschen laggy Auf Chrome (Android), also habe ich angefangen, die App zu profilieren und festgestellt, dass meine Berührungsereignisse für ca. 10ms auf einem huawei p8 auf den Haupt-Thread warten.So minimieren Sie das Warten auf den Hauptthread für touchmove

Meine Frage ist, wie kann ich diese Zeit minimieren, hatte keine Lösung gefunden, scheint, als ob es nicht möglich ist.

hier ist ein Beispiel jsfiddle (https://jsfiddle.net/bbvarga/p94btq6e/):

js Teil:

document.addEventListener('touchmove', function(e) { 
    e.preventDefault(); 
}) 

var box = document.getElementById('box'); 
var x = 0; 
var y = 0; 
var px = 0; 
var py = 0; 
var handler = null; 


function paint() { 
    box.style.setProperty(
    'transform', 
    `translate3d(${px}0px, ${py}px, 0px)`, 
    'important' 
); 
    handler = null; 
} 

box.addEventListener('touchstart', function(e) { 
    console.log('ts'); 
    x = e.touches[0].pageX; 
    y = e.touches[0].pageY; 
}); 

box.addEventListener('touchend', function() { 
    console.log('te'); 
    if (handler) { 
    window.cancelAnimationFrame(handler); 
    handler = null; 
    } 
}); 

box.addEventListener('touchmove', function(e) { 
    console.log('tm'); 
    px = e.touches[0].pageX; 
    py = e.touches[0].pageY; 
    if (!handler) { 
    window.requestAnimationFrame(paint); 
    } 
}); 

html:

<div id="container"> 
    <div id="wrapper"> 
    <div id="box"> 
    </div> 
    </div> 
</div> 

css:

#container { 
    position: fixed; 
    top: 0; 
    right: 0; 
    bottom: 0; 
    left: 0; 
    color: #efefef; 
} 
#wrapper { 
    width: 100%; 
    height: 100%; 
    position: relative; 
} 
#box { 
    position: absolute; 
    background-color: green; 
    width: 100px; 
    height: 100px; 
} 

und hier ist ein Screenshot aus th Die Zeitleiste zeigt, dass die roten Linien unter den Touch-Move-Ereignissen ziemlich lang sind (das heißt, während der Browser auf den Haupt-Thread wartet, ist er auch unter der Zusammenfassung des Touch-Move-Ereignisses unten im angehängten Screen-Shoot zu sehen)). Der wirkliche Job, den Stil neu zu berechnen, zu malen, zu komponieren, ist im Vergleich zur Wartezeit ziemlich schnell erledigt. Die Framerate in diesem minimalistischen Beispiel ist akzeptabel, aber ich habe das Gefühl, dass wenn ich Bilder und andere Sachen in diesem div, einige Berechnungen habe, diese langen Touchmove-Events meine Framerate verlangsamen.

Wenn Sie eine 60fps erreichen möchten, haben Sie ~ 17ms für jeden Frame, und wenn Warten ~ 10 ist, haben Sie nur 7ms für den eigentlichen Job. :(

enter image description here

Eine Anmerkung:. In der mobilen Safari es schnell ist, und das Gefühl, nicht diese Verzögerung

Antwort

0

Die ~ 10 ms des Wartens ist die Zeit aus, wenn das Eingabeereignis kommt, bis der Haupt Faden hebt es auf, wenn es das nächste Bild erzeugt. von dass Zeit Sie haben ~ 16ms Rahmenbudget

Was Sie sehen, ist die Eingangslatenz. es wird nicht die Glätte Ihrer Wirkung beeinflussen (Ihre JS-Handler ist innerhalb des Budgets), aber es fügt ~ 1 Frame der Latenz hinzu (so die Box doesn nicht genau an den Finger kleben. Dies geschieht, weil das Betriebssystem das Eingabeereignis an den Browserprozess übergibt. Es wird dann an den Rendererprozess gesendet, der Ihre Seite enthält. Von dort wird es in den Hauptthread eingereiht, aber erst wieder aufgenommen, wenn der Hauptthread bereit ist, einen neuen Frame zu generieren (und bei jedem Schritt gibt es ein bisschen Warteschlangen). Die Touch-Bewegung in der Timeline endet, sobald der Frame zur GPU verschoben wurde.

Leider ist vieles davon nicht wirklich unter Ihrer Kontrolle, aber es sollte relativ konstant sein, solange Ihr Haupt-Thread nicht gesättigt ist.

Verwandte Themen