Skip to content

Instantly share code, notes, and snippets.

@xvaara
Last active November 10, 2021 14:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xvaara/e01a9c68a9d53f3c6bd331dc36899472 to your computer and use it in GitHub Desktop.
Save xvaara/e01a9c68a9d53f3c6bd331dc36899472 to your computer and use it in GitHub Desktop.
monitor v8 memory usage in chrome based browsers.
<template>
<div ref="el" class="stats" :style="style">
<div class="memory">
Mem: {{ memory }}
</div>
<svg :viewBox="'0 0 60 '+chartHeight" class="chart" :style="'height: ' + chartHeight + 'px;'">
<polyline
:points="chartData"
/>
</svg>
</div>
</template>
<script setup>
import { useDraggable } from '@vueuse/core'
const memory = ref('')
const chartData = ref('')
const chartHeight = ref(40)
const chartBytes = []
const el = ref(null)
// `style` will be a helper computed for `left: ?px; top: ?px;`
const { style } = useDraggable(el, {
initialValue: { x: window.innerWidth - 82, y: 2 },
})
const perf = window.performance || {}
// polyfill usedJSHeapSize
if (!perf && !perf.memory)
perf.memory = { usedJSHeapSize: 0 }
if (perf && !perf.memory)
perf.memory = { usedJSHeapSize: 0 }
// support of the API?
if (perf.memory.totalJSHeapSize === 0)
console.warn('totalJSHeapSize === 0... performance.memory is only available in Chrome .')
// TODO, add a sanity check to see if values are bucketed.
// If so, reminde user to adopt the --enable-precise-memory-info flag.
// open -a "/Applications/Google Chrome.app" --args --enable-precise-memory-info
let lastTime = Date.now()
let lastUsedHeap = perf.memory.usedJSHeapSize
let msMin = lastUsedHeap
let msMax = lastUsedHeap
function updateChart() {
const ms = lastUsedHeap
msMin = Math.min(msMin, ms)
msMax = Math.max(msMax, ms)
chartBytes.shift()
chartBytes.push(ms)
chartData.value = chartBytes.map(b => b ? (b - msMin) / (msMax - msMin) : null).reduce((acc, cur, index) => cur ? `${acc}${index},${(1 - cur) * chartHeight.value} ` : '', '')
}
function bytesToSize(bytes, nFractDigit) {
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']
if (bytes == 0) return 'n/a'
nFractDigit = nFractDigit !== undefined ? nFractDigit : 0
const precision = Math.pow(10, nFractDigit)
const i = Math.floor(Math.log(bytes) / Math.log(1024))
return `${Math.round(bytes * precision / Math.pow(1024, i)) / precision} ${sizes[i]}`
}
function update() {
// refresh only 30time per second
if (Date.now() - lastTime < 1000 / 30) return
lastTime = Date.now()
const delta = perf.memory.usedJSHeapSize - lastUsedHeap
lastUsedHeap = perf.memory.usedJSHeapSize
const color = delta < 0 ? '#830' : '#131'
const ms = perf.memory.usedJSHeapSize
memory.value = bytesToSize(ms, 2)
if (chartBytes.length < 60)
chartBytes.push(ms)
}
let loop = true
requestAnimationFrame(function rAFloop() {
update()
if (loop)
requestAnimationFrame(rAFloop)
})
const interval = setInterval(updateChart, 1000)
onBeforeUnmount(() => {
loop = false
clearInterval(interval)
})
</script>
<style scoped>
.stats{
width: 80px;
opacity:0.8;
cursor:pointer;
background-color:#020;
position: fixed;
z-index: 9999999;
display: flex;
flex-flow: column;
}
.stats .memory {
color:#0f0;
font-family:Helvetica,Arial,sans-serif;
font-size:9px;
font-weight:bold;
line-height:15px;
flex: 0 1 auto;
}
.stats .chart {
background-color: #131;
flex: 1 1 auto;
margin: 2px
}
.stats .chart polyline {
fill: none;
stroke: #0f0;
stroke-width: 1px;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment