@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
160 lines • 5.18 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NetworkAudit = exports.Audit = exports.SlowFrameDetector = void 0;
const node_perf_hooks_1 = require("node:perf_hooks");
class SlowFrameDetector {
_count = 0;
_duration = 0;
_threshold;
_interval;
constructor(threshold = 200) {
this._threshold = threshold;
}
start() {
if (this._interval) {
throw new Error("already started");
}
let lastFrame = Date.now();
this._interval = setInterval(() => {
const now = Date.now();
const diff = now - lastFrame;
if (diff > this._threshold) {
this._count++;
this._duration += diff;
}
lastFrame = now;
}, 10);
}
stop() {
if (!this._interval) {
throw new Error("not started");
}
clearInterval(this._interval);
this._interval = undefined;
}
result() {
return {
count: this._count,
duration: this._duration,
};
}
}
exports.SlowFrameDetector = SlowFrameDetector;
// all the logic to measure and report back
class Audit {
_jsBootTime;
_startTime;
_startUsage;
_startMemory;
_slowFrameDetector;
_networkAudit;
constructor() {
const jsBootTime = Date.now() - parseInt(process.env.START_TIME || "0", 10);
this._jsBootTime = jsBootTime;
this._startTime = process.hrtime();
this._startUsage = process.cpuUsage();
this._startMemory = process.memoryUsage();
this._slowFrameDetector = new SlowFrameDetector();
this._slowFrameDetector.start();
this._networkAudit = new NetworkAudit();
this._networkAudit.start();
}
_totalTime;
_cpuUserTime;
_cpuSystemTime;
_endMemory;
end() {
const endTime = process.hrtime(this._startTime);
const endUsage = process.cpuUsage(this._startUsage);
const endMemory = process.memoryUsage();
this._totalTime = (endTime[0] * 1e9 + endTime[1]) / 1e6; // ms
this._cpuUserTime = endUsage.user / 1e3; // ms
this._cpuSystemTime = endUsage.system / 1e3; // ms
this._endMemory = endMemory;
this._slowFrameDetector.stop();
this._networkAudit.stop();
}
_accountsJSONSize;
setAccountsJSONSize(size) {
this._accountsJSONSize = size;
}
_preloadJSONSize;
setPreloadJSONSize(size) {
this._preloadJSONSize = size;
}
result() {
if (!this._totalTime) {
throw new Error("audit not ended");
}
return {
jsBootTime: this._jsBootTime,
cpuUserTime: this._cpuUserTime,
cpuSystemTime: this._cpuSystemTime,
totalTime: this._totalTime,
memoryEnd: this._endMemory,
memoryStart: this._startMemory,
accountsJSONSize: this._accountsJSONSize,
preloadJSONSize: this._preloadJSONSize,
network: this._networkAudit.result(),
slowFrames: this._slowFrameDetector.result(),
};
}
}
exports.Audit = Audit;
class NetworkAudit {
_obs;
_totalTime = 0;
_totalCount = 0;
_totalResponseSize = 0;
_totalDuplicateRequests = 0;
_urlsSeen = new Set();
start() {
this._obs = new node_perf_hooks_1.PerformanceObserver(this.onPerformanceEntry);
this._obs.observe({ type: "http" });
}
stop() {
if (this._obs) {
this._obs.disconnect();
this._obs = undefined;
}
}
onPerformanceEntry = (items, _observer) => {
const entries = items.getEntries();
for (const entry of entries) {
if (entry.entryType === "http") {
this._totalCount = (this._totalCount || 0) + 1;
if (entry.duration) {
this._totalTime = (this._totalTime || 0) + entry.duration;
}
const req = entry.detail?.req;
const res = entry.detail?.res;
if (res && req) {
const { url } = req;
if (this._urlsSeen.has(url)) {
this._totalDuplicateRequests = (this._totalDuplicateRequests || 0) + 1;
}
else {
this._urlsSeen.add(url);
}
const { headers } = res;
if (headers) {
const contentLength = headers["content-length"];
if (contentLength) {
this._totalResponseSize = (this._totalResponseSize || 0) + parseInt(contentLength);
}
}
}
}
}
};
result() {
return {
totalTime: this._totalTime,
totalCount: this._totalCount,
totalResponseSize: this._totalResponseSize,
totalDuplicateRequests: this._totalDuplicateRequests,
};
}
}
exports.NetworkAudit = NetworkAudit;
//# sourceMappingURL=audits.js.map