Add graph showing how much data is received per plugin

Summary:
Added a graph to show how much data is sent to plugins. The tooltip shows a sorted overview of the amount of data.

Will put up a GK so that plugin devs can get this data also more easily

Reviewed By: jknoxville

Differential Revision: D20919321

fbshipit-source-id: f2b78b21ef34551e0ed562b009589d2a5dba9ff3
This commit is contained in:
Michel Weststrate
2020-04-08 13:03:41 -07:00
committed by Facebook GitHub Bot
parent bc6165bbfe
commit f53846e0ca
3 changed files with 80 additions and 1 deletions

View File

@@ -84,7 +84,12 @@ export default function FpsGraph({
return (
<div>
<canvas ref={canvasRef} width={width} height={height} />
<canvas
ref={canvasRef}
width={width}
height={height}
title="Current framerate in FPS"
/>
</div>
);
}

View File

@@ -0,0 +1,72 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import React, {useEffect, useRef, useState} from 'react';
import {onBytesReceived} from '../dispatcher/tracking';
export default function NetworkGraph({
width,
height,
}: {
width: number;
height: number;
}) {
const canvasRef = useRef<HTMLCanvasElement>(null);
const lastTime = useRef(performance.now());
const lastBytes = useRef(0);
const pluginStats = useRef<Record<string, number>>({});
const [hoverText, setHoverText] = useState('');
useEffect(() => {
return onBytesReceived((plugin, bytes) => {
lastBytes.current += bytes;
if (!pluginStats.current[plugin]) {
pluginStats.current[plugin] = bytes;
} else {
pluginStats.current[plugin] += bytes;
}
});
}, []);
useEffect(() => {
const interval = setInterval(() => {
const deltaTime = performance.now() - lastTime.current;
lastTime.current = performance.now();
const deltaBytes = lastBytes.current;
lastBytes.current = 0;
// cause kiloBytesPerSecond === bytes per millisecond
const kiloBytesPerSecond = Math.round(deltaBytes / deltaTime);
const ctx = canvasRef.current!.getContext('2d')!;
ctx.clearRect(0, 0, width, height);
ctx.strokeStyle = kiloBytesPerSecond >= 1000 ? '#f00' : '#ccc';
ctx.textAlign = 'end';
ctx.strokeText(`${kiloBytesPerSecond} kB/s`, width - 5, 5 + height / 2);
setHoverText(
'Total data traffic per plugin:\n\n' +
Object.entries(pluginStats.current)
.sort(([_p, bytes], [_p2, bytes2]) => bytes2 - bytes)
.map(([key, bytes]) => `${key}: ${Math.round(bytes / 1000)}kb`)
.join('\n'),
);
}, 1000);
return () => {
clearInterval(interval);
};
}, []);
return (
<div>
<canvas ref={canvasRef} width={width} height={height} title={hoverText} />
</div>
);
}

View File

@@ -45,6 +45,7 @@ import React from 'react';
import {State} from '../reducers';
import {reportUsage} from '../utils/metrics';
import FpsGraph from './FpsGraph';
import NetworkGraph from './NetworkGraph';
import MetroButton from './MetroButton';
const AppTitleBar = styled(FlexRow)<{focused?: boolean}>(({focused}) => ({
@@ -167,6 +168,7 @@ class TitleBar extends React.Component<Props, StateFromProps> {
)}
<Spacer />
{!isProduction() && <NetworkGraph height={20} width={60} />}
{!isProduction() && <FpsGraph height={20} width={60} />}
{config.showFlipperRating ? <RatingButton /> : null}