feat(rtk-query): improve formatting of timings and display average loading time

This commit is contained in:
FaberVitale 2021-06-23 11:45:22 +02:00
parent f1430bf748
commit 07eefb5f63
5 changed files with 88 additions and 3 deletions

View File

@ -72,7 +72,7 @@ See also
- query state
- tags
- subscriptions
- api slice config
- api state
- api stats
## TODO

View File

@ -114,6 +114,7 @@ export interface QueryTimings {
readonly latestFetch: { key: string; at: string } | null;
readonly slowest: { key: string; duration: string } | null;
readonly fastest: { key: string; duration: string } | null;
readonly average: string;
}
export interface ApiTimings {

View File

@ -0,0 +1,31 @@
export function formatMs(milliseconds: number): string {
if (!Number.isFinite(milliseconds)) {
return 'NaN';
}
const absInput = Math.abs(Math.round(milliseconds));
let millis = (absInput % 1000).toString();
if (millis.length < 3) {
if (millis.length === 2) {
millis = '0' + millis;
} else {
millis = '00' + millis;
}
}
const seconds = Math.floor(absInput / 1_000) % 60;
const minutes = Math.floor(absInput / 60_000);
let output = `${seconds}.${millis}s`;
if (minutes > 0) {
output = `${minutes}m${output}`;
}
if (milliseconds < 0) {
output = `-${output}`;
}
return output;
}

View File

@ -19,6 +19,8 @@ import { missingTagId } from '../monitor-config';
import { Comparator } from './comparators';
import { emptyArray } from './object';
import { SubscriptionState } from '@reduxjs/toolkit/dist/query/core/apiState';
import { formatMs } from './formatters';
import { mean } from './statistics';
const rtkqueryApiStateKeys: ReadonlyArray<keyof RtkQueryApiState> = [
'queries',
@ -213,6 +215,8 @@ function computeQueryApiTimings(
duration: Number.MAX_SAFE_INTEGER,
};
const pendingDurations: number[] = [];
const queryKeys = Object.keys(queriesOrMutations);
for (let i = 0, len = queryKeys.length; i < len; i++) {
@ -239,6 +243,8 @@ function computeQueryApiTimings(
) {
const pendingDuration = fulfilledTimeStamp - startedTimeStamp;
pendingDurations.push(pendingDuration);
if (pendingDuration > slowest.duration) {
slowest.key = queryKey;
slowest.duration = pendingDuration;
@ -265,22 +271,26 @@ function computeQueryApiTimings(
}
if (slowest.key !== null) {
slowest.duration = `${((slowest.duration as number) / 1_000).toFixed(3)}s`;
slowest.duration = formatMs(slowest.duration as number);
} else {
slowest = null;
}
if (fastest.key !== null) {
fastest.duration = `${((fastest.duration as number) / 1_000).toFixed(3)}s`;
fastest.duration = formatMs(fastest.duration as number);
} else {
fastest = null;
}
const average =
pendingDurations.length > 0 ? formatMs(mean(pendingDurations)) : '-';
return {
latestFetch,
oldestFetch,
slowest,
fastest,
average,
} as QueryTimings;
}

View File

@ -0,0 +1,43 @@
/**
* An implementation of `Kahan-Babuska algorithm`
* that reduces numerical floating point errors.
* @param {number[]} nums
* @returns {number}
* @see https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.582.288&rep=rep1&type=pdf
*/
function sum(nums: number[]): number {
if (nums.length === 0) {
return 0;
}
let t;
let correction = 0;
let output = nums[0];
for (let i = 1, len = nums.length; i < len; i++) {
t = output + nums[i];
if (Math.abs(output) >= Math.abs(nums[i])) {
correction += output - t + nums[i];
} else {
correction += nums[i] - t + output;
}
output = t;
}
return output + correction;
}
/**
* Returns mean, also known as average, of numerical sequences.
* @param nums
* @returns
*/
export function mean(nums: number[]): number {
if (nums.length === 0) {
return NaN;
}
return sum(nums) / nums.length;
}