mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-10-03 16:09:52 +02:00
performance improvement
This commit is contained in:
@@ -5,9 +5,11 @@ export type MenuIconButtonProps = IconButtonProps & {
|
|||||||
children: MenuListProps["children"];
|
children: MenuListProps["children"];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MenuIconButton = ({ children, ...props }: MenuIconButtonProps) => (
|
export function MenuIconButton({ children, ...props }: MenuIconButtonProps) {
|
||||||
<Menu isLazy>
|
return (
|
||||||
<MenuButton as={IconButton} icon={<MoreIcon />} {...props} />
|
<Menu isLazy>
|
||||||
<MenuList>{children}</MenuList>
|
<MenuButton as={IconButton} icon={<MoreIcon />} {...props} />
|
||||||
</Menu>
|
<MenuList>{children}</MenuList>
|
||||||
);
|
</Menu>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import React from "react";
|
import { ReactNode, memo } from "react";
|
||||||
import { Text } from "@chakra-ui/react";
|
import { Text } from "@chakra-ui/react";
|
||||||
import { Kind } from "nostr-tools";
|
import { Kind } from "nostr-tools";
|
||||||
|
|
||||||
@@ -16,36 +16,44 @@ import EmbeddedArticle from "../../embed-event/event-types/embedded-article";
|
|||||||
import { isReply } from "../../../helpers/nostr/events";
|
import { isReply } from "../../../helpers/nostr/events";
|
||||||
import ReplyNote from "./reply-note";
|
import ReplyNote from "./reply-note";
|
||||||
|
|
||||||
const RenderEvent = React.memo(({ event }: { event: NostrEvent }) => {
|
function RenderEvent({ event }: { event: NostrEvent }) {
|
||||||
|
let content: ReactNode | null = null;
|
||||||
switch (event.kind) {
|
switch (event.kind) {
|
||||||
case Kind.Text:
|
case Kind.Text:
|
||||||
return isReply(event) ? <ReplyNote event={event} /> : <Note event={event} showReplyButton />;
|
content = isReply(event) ? <ReplyNote event={event} /> : <Note event={event} showReplyButton />;
|
||||||
|
break;
|
||||||
case Kind.Repost:
|
case Kind.Repost:
|
||||||
return <RepostNote event={event} />;
|
content = <RepostNote event={event} />;
|
||||||
|
break;
|
||||||
case Kind.Article:
|
case Kind.Article:
|
||||||
return <EmbeddedArticle article={event} />;
|
content = <EmbeddedArticle article={event} />;
|
||||||
|
break;
|
||||||
case STREAM_KIND:
|
case STREAM_KIND:
|
||||||
return <StreamNote event={event} />;
|
content = <StreamNote event={event} />;
|
||||||
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
const safeUrl = safeRelayUrl(event.content);
|
const safeUrl = safeRelayUrl(event.content);
|
||||||
return safeUrl ? <RelayCard url={safeUrl} /> : null;
|
content = safeUrl ? <RelayCard url={safeUrl} /> : null;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return <Text>Unknown event kind: {event.kind}</Text>;
|
content = <Text>Unknown event kind: {event.kind}</Text>;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
const GenericNoteTimeline = React.memo(({ timeline }: { timeline: TimelineLoader }) => {
|
return content && <ErrorBoundary>{content}</ErrorBoundary>;
|
||||||
|
}
|
||||||
|
const RenderEventMemo = memo(RenderEvent);
|
||||||
|
|
||||||
|
function GenericNoteTimeline({ timeline }: { timeline: TimelineLoader }) {
|
||||||
const notes = useSubject(timeline.timeline);
|
const notes = useSubject(timeline.timeline);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{notes.map((note) => (
|
{notes.map((note) => (
|
||||||
<ErrorBoundary key={note.id}>
|
<RenderEventMemo key={note.id} event={note} />
|
||||||
<RenderEvent event={note} />
|
|
||||||
</ErrorBoundary>
|
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
|
||||||
export default GenericNoteTimeline;
|
export default memo(GenericNoteTimeline);
|
||||||
|
@@ -72,20 +72,26 @@ class TimeMeasure implements RelayMeasure, PersistentMeasure {
|
|||||||
}
|
}
|
||||||
addTime(time: number, date: Date = new Date()) {
|
addTime(time: number, date: Date = new Date()) {
|
||||||
this.measures.unshift([time, date]);
|
this.measures.unshift([time, date]);
|
||||||
|
this.averageCache = null;
|
||||||
}
|
}
|
||||||
getCount(since?: Date) {
|
getCount() {
|
||||||
const points = since ? this.measures.filter((m) => m[1] > since) : this.measures;
|
return this.measures.length;
|
||||||
return points.length;
|
|
||||||
}
|
}
|
||||||
getAverage(since?: Date, undef: number = Infinity) {
|
|
||||||
const points = since ? this.measures.filter((m) => m[1] > since) : this.measures;
|
/** cache the average since it gets called a lot */
|
||||||
if (points.length === 0) return undef;
|
private averageCache: number | null = null;
|
||||||
const total = points.reduce((total, [time]) => total + time, 0);
|
getAverage(undef: number = Infinity) {
|
||||||
return total / points.length;
|
if (this.measures.length === 0) return undef;
|
||||||
|
if (this.averageCache !== null) {
|
||||||
|
const total = this.measures.reduce((total, [time]) => total + time, 0);
|
||||||
|
this.averageCache = total / this.measures.length;
|
||||||
|
}
|
||||||
|
return this.averageCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.measures = [];
|
this.measures = [];
|
||||||
|
this.averageCache = null;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
prune(cutOff: Date): this {
|
prune(cutOff: Date): this {
|
||||||
@@ -94,6 +100,7 @@ class TimeMeasure implements RelayMeasure, PersistentMeasure {
|
|||||||
if (!last) break;
|
if (!last) break;
|
||||||
if (last[1] >= cutOff) {
|
if (last[1] >= cutOff) {
|
||||||
this.measures.push(last);
|
this.measures.push(last);
|
||||||
|
this.averageCache = null;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,6 +110,7 @@ class TimeMeasure implements RelayMeasure, PersistentMeasure {
|
|||||||
load(data: any) {
|
load(data: any) {
|
||||||
if (!Array.isArray(data)) return this;
|
if (!Array.isArray(data)) return this;
|
||||||
this.measures = data;
|
this.measures = data;
|
||||||
|
this.averageCache = null;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
save() {
|
save() {
|
||||||
@@ -128,25 +136,25 @@ class RelayScoreboardService {
|
|||||||
// for (const [relay, measure] of this.relayTimeouts) measure.prune(cutOff);
|
// for (const [relay, measure] of this.relayTimeouts) measure.prune(cutOff);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAverageResponseTime(relay: string, since?: Date) {
|
getAverageResponseTime(relay: string) {
|
||||||
return this.relayResponseTimes.get(relay).getAverage(since);
|
return this.relayResponseTimes.get(relay).getAverage();
|
||||||
}
|
}
|
||||||
getAverageEjectTime(relay: string, since?: Date) {
|
getAverageEjectTime(relay: string) {
|
||||||
return this.relayEjectTime.get(relay).getAverage(since);
|
return this.relayEjectTime.get(relay).getAverage();
|
||||||
}
|
}
|
||||||
getAverageConnectionTime(relay: string, since?: Date) {
|
getAverageConnectionTime(relay: string) {
|
||||||
return this.relayConnectionTime.get(relay).getAverage(since);
|
return this.relayConnectionTime.get(relay).getAverage();
|
||||||
}
|
}
|
||||||
// getTimeoutCount(relay: string, since?: Date) {
|
// getTimeoutCount(relay: string) {
|
||||||
// return this.relayTimeouts.get(relay).getCount(since);
|
// return this.relayTimeouts.get(relay).getCount();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
hasConnected(relay: string, since?: Date) {
|
hasConnected(relay: string) {
|
||||||
return this.relayConnectionTime.get(relay).getCount(since) > 0;
|
return this.relayConnectionTime.get(relay).getCount() > 0;
|
||||||
}
|
}
|
||||||
getResponseTimeScore(relay: string, since?: Date) {
|
getResponseTimeScore(relay: string) {
|
||||||
const responseTime = this.getAverageResponseTime(relay, since);
|
const responseTime = this.getAverageResponseTime(relay);
|
||||||
const connected = this.hasConnected(relay, since);
|
const connected = this.hasConnected(relay);
|
||||||
|
|
||||||
// no points if we have never connected
|
// no points if we have never connected
|
||||||
if (!connected) return 0;
|
if (!connected) return 0;
|
||||||
@@ -154,8 +162,8 @@ class RelayScoreboardService {
|
|||||||
// 1 point (max 10) for ever 10 ms under 1000. negative points for over 1000
|
// 1 point (max 10) for ever 10 ms under 1000. negative points for over 1000
|
||||||
return clamp(Math.round(-(responseTime - 1000) / 100), -10, 10);
|
return clamp(Math.round(-(responseTime - 1000) / 100), -10, 10);
|
||||||
}
|
}
|
||||||
getConnectionTimeScore(relay: string, since?: Date) {
|
getConnectionTimeScore(relay: string) {
|
||||||
const connectionTime = this.getAverageConnectionTime(relay, since);
|
const connectionTime = this.getAverageConnectionTime(relay);
|
||||||
|
|
||||||
// no points if we have never connected
|
// no points if we have never connected
|
||||||
if (connectionTime === Infinity) return 0;
|
if (connectionTime === Infinity) return 0;
|
||||||
@@ -163,9 +171,9 @@ class RelayScoreboardService {
|
|||||||
// 1 point (max 10) for ever 10 ms under 1000. negative points for over 1000
|
// 1 point (max 10) for ever 10 ms under 1000. negative points for over 1000
|
||||||
return clamp(Math.round(-(connectionTime - 1000) / 100), -10, 10);
|
return clamp(Math.round(-(connectionTime - 1000) / 100), -10, 10);
|
||||||
}
|
}
|
||||||
getEjectTimeScore(relay: string, since?: Date) {
|
getEjectTimeScore(relay: string) {
|
||||||
const ejectTime = this.getAverageEjectTime(relay, since);
|
const ejectTime = this.getAverageEjectTime(relay);
|
||||||
const connected = this.hasConnected(relay, since);
|
const connected = this.hasConnected(relay);
|
||||||
|
|
||||||
// no points if we have never connected
|
// no points if we have never connected
|
||||||
if (!connected) return 0;
|
if (!connected) return 0;
|
||||||
@@ -177,18 +185,18 @@ class RelayScoreboardService {
|
|||||||
if (ejectTime > 1000 * 200) score += 5;
|
if (ejectTime > 1000 * 200) score += 5;
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
// getTimeoutsScore(relay: string, since?: Date) {
|
// getTimeoutsScore(relay: string) {
|
||||||
// const timeouts = this.getTimeoutCount(relay, since);
|
// const timeouts = this.getTimeoutCount(relay);
|
||||||
// // subtract 5 points for ever time its timed out
|
// // subtract 5 points for ever time its timed out
|
||||||
// return -(timeouts * 5);
|
// return -(timeouts * 5);
|
||||||
// }
|
// }
|
||||||
getRelayScore(relay: string, since?: Date) {
|
getRelayScore(relay: string) {
|
||||||
let score = 0;
|
let score = 0;
|
||||||
|
|
||||||
score += this.getResponseTimeScore(relay, since);
|
score += this.getResponseTimeScore(relay);
|
||||||
score += this.getConnectionTimeScore(relay, since);
|
score += this.getConnectionTimeScore(relay);
|
||||||
score += this.getEjectTimeScore(relay, since);
|
score += this.getEjectTimeScore(relay);
|
||||||
// score += this.getTimeoutsScore(relay, since);
|
// score += this.getTimeoutsScore(relay);
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user