Frame-rate limiter for m.mount/m.route

This commit is contained in:
Pat Cavit 2016-05-17 14:49:48 -07:00
parent 5ec06e7c08
commit db609b9142
5 changed files with 147 additions and 13 deletions

View file

@ -575,21 +575,58 @@ var createRenderer = function($window) {
return {render: render, setEventCallback: setEventCallback}
}
var FRAME_BUDGET = 16 // 60 frames per second = 1 call per 16 ms
var limiter = function($window, render) {
var rAF = $window.requestAnimationFrame || $window.setTimeout
var cAF = $window.cancelAnimationFrame || $window.clearTimeout
var last = 0
var pending
return function() {
var now = new Date()
// First render, OR if the time since the last render is greater
// than the frame budget
// just immediately render
if(!last || now - last > FRAME_BUDGET) {
last = now;
return render()
}
// Redraw already pending, abort
if(pending) {
return
}
// Schedule a redraw for the next tick
pending = rAF(function() {
render()
last = new Date()
pending = null
}, FRAME_BUDGET - (now - last))
}
}
;
var createMounter = function($window, redraw) {
return function(root, component) {
var renderer = createRenderer($window)
renderer.setEventCallback(draw)
function draw() {
var draw = limiter($window, function draw() {
renderer.render(root, {tag: component})
}
})
renderer.setEventCallback(draw)
redraw.run = draw
draw()
}
}
var buildQueryString = function buildQueryString(object) {
if (Object.prototype.toString.call(object) !== "[object Object]") return ""
@ -758,15 +795,17 @@ var createRouter = function($window) {
return {setPrefix: setPrefix, getPath: getPath, setPath: setPath, defineRoutes: defineRoutes, link: link}
}
var createRouterInstance = function($window, redraw) {
var renderer = createRenderer($window)
var router = createRouter($window)
var route = function(root, defaultRoute, routes) {
var replay = router.defineRoutes(routes, function(component, args) {
var replay = limiter($window, router.defineRoutes(routes, function(component, args) {
renderer.render(root, {tag: component, attrs: args})
}, function() {
router.setPath(defaultRoute)
})
}))
renderer.setEventCallback(replay)
redraw.run = replay
}