Skip to content

Commit

Permalink
Add hidden delta to FPS calculation 🍯
Browse files Browse the repository at this point in the history
  • Loading branch information
xaviervia committed Jan 13, 2017
1 parent 26d32ff commit 5cbe9b7
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 4 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@
"bugs": {
"url": "https://github.com/pirelenito/collect-fps/issues"
}
}
}
35 changes: 35 additions & 0 deletions src/calculate-fps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export default (frames, visibilityEvents) =>
1000 / (
(
(frames[frames.length - 1] - frames[0]) -
getHiddenDelta(visibilityEvents)
) /
(frames.length - 1)
)

export const getHiddenDelta = (visibilityEvents) =>
visibilityEvents
.reduce((deltas, [visible, timestamp]) => {
const last = deltas.slice(-1)[0]
const remaining = deltas.slice(0, -1)
if (visible && !last) { return deltas }

if (!visible) {
return [
...deltas,
[timestamp]
]
} else {
return [
...remaining,
[last[0], timestamp]
]
}
}, [])
.reduce(
(delta, [start, end]) =>
end
? delta + (end - start)
: delta
, 0
)
42 changes: 42 additions & 0 deletions src/calculate-fps.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import calculateFPS, { getHiddenDelta } from './calculate-fps'

describe('calculate-fps', () => {
describe('calculateFPS', () => {
it('should calculate the fps', () => {
const frames = [200, 400, 600, 800, 1000]

expect(calculateFPS(frames, [])).toBe(5)
})

it('should calculate the fps taking into account the hidden delta', () => {
const frames = [200, 400, 600, 800, 1000]
const visibilityEvents = [[false, 0], [true, 300]]

expect(calculateFPS(frames, visibilityEvents)).toBe(8)
})
})

describe('getHiddenDelta', () => {
it('should calculate the amount of time that it spent hidden', () => {
const visibilityEvents = [
[false, 1000],
[true, 1010],
[false, 1100],
[true, 1200]
]

expect(getHiddenDelta(visibilityEvents)).toBe(110)
})

it('should ignore unfinished hidden sequences', () => {
const visibilityEvents = [
[true, 100],
[false, 1000],
[true, 1010],
[false, 1100]
]

expect(getHiddenDelta(visibilityEvents)).toBe(10)
})
})
})
15 changes: 12 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import calculateFPS from './calculate-fps'

export default function collectFPS (...args) {
const customMaxFrames = typeof args[0] === 'number'

Expand All @@ -10,15 +12,22 @@ export default function collectFPS (...args) {
return
}

const visibilityEvents = []

const onVisibilityChange = () =>
visibilityEvents.push([!document.hidden, Date.now()])

document.addEventListener('visibilitychange', onVisibilityChange)

const update = () => {
frames.push(Date.now())

if (frames.length < maxFrames) {
window.requestAnimationFrame(update)
} else {
const timePerFrame = (frames[frames.length - 1] - frames[0]) / frames.length
const fps = 1000 / timePerFrame
cb(null, fps)
document.removeEventListener('visibilitychange', onVisibilityChange)

cb(null, calculateFPS(frames, visibilityEvents))
}
}

Expand Down

0 comments on commit 5cbe9b7

Please sign in to comment.