Why do most browsers display at 16.7ms?
Because browsers refresh at 60 frames per second, 1 second =1000 ms and 1000/60=16.7ms
Why does the browser lose frames?
If you use a setTimeout of 10ms, you can draw 3 times in 30ms, but the browser is supposed to draw once in 16.7ms and can only draw twice in 30 seconds. This will result in frame loss. (It was supposed to draw 3 times for 30ms, but it only drew 2 times and lost one frame), resulting in the animation showing intermittently (the feeling of traffic jam), which is the problem caused by over-drawing. This is why the minimum value of setTimeout timer is recommended to be 16.7ms.
What are the problems caused by browser frame loss?
- Cause the animation to display intermittently
- Overdrawing can have a negative impact on battery life and can degrade performance in other applications
Describe how it works?
-
RequestAnimationFrame brings together all DOM operations in each frame in a single redraw or reflow that closely tracks the browser refresh rate, which is typically 60 frames per second
-
RequestAnimationFrame will not be redrawn or reflow in hidden or invisible elements, which of course means less CPU, GPU, and memory usage
Usage?
- RequestAnimationFrame calls are made only once, and are recursive to animate.
- Parameter: callback function for animation
- Return value: id Animation frame number
- CancelAnimationFrame (ID)
let timer = 0
function move() {
if (true) {
cancelAnimationFrame(timer)
} else {
timer = requestAnimationFrame(move)
}
}
move()
Copy the code
Which performs better than CSS animation?
No comparison has been made, but the two are neck and neck.
What about compatibility?
IE10+, Firefox, Chrome, Safari, Opera, etc. On mobile devices, ios6 and above and IE Mobile 10 and above support requestAnimationFrame, The only sad thing is that requestAnimationFrame support is not currently available in native Browsers on Android, but it seems to be coming soon. The Android version of Chrome 16+ also supports requestAnimationFrame
How to work with browsers (even IE6 supports it)?
(function () {
// Compatible with WebKit, MOZ kernel
window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;
/ / cancel the animation frames, there are two versions cancelAnimationFrame, cancelRequestAnimationFrame
window.cancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.cancelRequestAnimationFrame || window.webkitCancelRequestAnimationFrame || window.mozCancelRequestAnimationFrame;
if (!window.requestAnimationFrame) {
// setTimeout emulates the animation frame
var lastTime = Date.now(); / / timestamp
window.requestAnimationFrame = function (callback) {
var id;
var nowTime = Date.now();
// Not all browser screens render at 16.7. If the interval between the last time and this time is greater than 16.7, the execution is not delayed
var delay = Math.max(16.7 - (nowTime - lastTime), 0);
id = setTimeout(callback, delay);
lastTime = nowTime + delay; // The last time the animation was executed
return id;
};
}
// Unanimate frames
if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = function (id) {
clearTimeout(id);
};
}
})();
Copy the code
Updated version
(function () {
var lastTime = 0;
var vendors = ['webkit'.'moz'];
// Make a judgment in the for loop! window.requestAnimationFrame
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
// If there is no value, assign it directly
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
window.cancelAnimationFrame =
window[vendors[x] + 'CancelAnimationFrame'] | |window[vendors[x] + 'CancelRequestAnimationFrame'];
}
// setTimeout emulates the animation frame
if (!window.requestAnimationFrame){
window.requestAnimationFrame = function (callback) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0.16.7 - (currTime - lastTime));
var id = window.setTimeout(function () { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
if (!window.cancelAnimationFrame){
window.cancelAnimationFrame = function (id) {
clearTimeout(id);
};
}
}());
Copy the code