mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-04-10 04:39:19 +02:00
fix performance issue
This commit is contained in:
parent
6ccd9ea736
commit
4258a10d36
@ -56,7 +56,7 @@
|
||||
"match-sorter": "^6.3.1",
|
||||
"nanoid": "^5.0.4",
|
||||
"ngeohash": "^0.6.3",
|
||||
"nostr-idb": "^2.1.0",
|
||||
"nostr-idb": "^2.1.1",
|
||||
"nostr-tools": "^2.1.3",
|
||||
"react": "^18.2.0",
|
||||
"react-chartjs-2": "^5.2.0",
|
||||
|
@ -114,15 +114,20 @@ export function UserFollowButton({ pubkey, showLists, ...props }: UserFollowButt
|
||||
const isFollowing = isPubkeyInList(contacts, pubkey);
|
||||
const isDisabled = account?.readonly ?? true;
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const handleFollow = useAsyncErrorHandler(async () => {
|
||||
setLoading(true);
|
||||
const draft = listAddPerson(contacts || createEmptyContactList(), pubkey);
|
||||
const signed = await requestSignature(draft);
|
||||
await publish("Follow", signed);
|
||||
setLoading(false);
|
||||
}, [contacts, requestSignature]);
|
||||
const handleUnfollow = useAsyncErrorHandler(async () => {
|
||||
setLoading(true);
|
||||
const draft = listRemovePerson(contacts || createEmptyContactList(), pubkey);
|
||||
const signed = await requestSignature(draft);
|
||||
await publish("Unfollow", signed);
|
||||
setLoading(false);
|
||||
}, [contacts, requestSignature]);
|
||||
|
||||
if (showLists) {
|
||||
@ -139,11 +144,11 @@ export function UserFollowButton({ pubkey, showLists, ...props }: UserFollowButt
|
||||
</MenuButton>
|
||||
<MenuList>
|
||||
{isFollowing ? (
|
||||
<MenuItem onClick={handleUnfollow} icon={<UnfollowIcon />} isDisabled={isDisabled}>
|
||||
<MenuItem onClick={handleUnfollow} icon={<UnfollowIcon />} isDisabled={isDisabled || loading}>
|
||||
Unfollow
|
||||
</MenuItem>
|
||||
) : (
|
||||
<MenuItem onClick={handleFollow} icon={<FollowIcon />} isDisabled={isDisabled}>
|
||||
<MenuItem onClick={handleFollow} icon={<FollowIcon />} isDisabled={isDisabled || loading}>
|
||||
Follow
|
||||
</MenuItem>
|
||||
)}
|
||||
@ -168,13 +173,27 @@ export function UserFollowButton({ pubkey, showLists, ...props }: UserFollowButt
|
||||
);
|
||||
} else if (isFollowing) {
|
||||
return (
|
||||
<Button onClick={handleUnfollow} colorScheme="primary" icon={<UnfollowIcon />} isDisabled={isDisabled} {...props}>
|
||||
<Button
|
||||
onClick={handleUnfollow}
|
||||
colorScheme="primary"
|
||||
icon={<UnfollowIcon />}
|
||||
isDisabled={isDisabled}
|
||||
isLoading={loading}
|
||||
{...props}
|
||||
>
|
||||
Unfollow
|
||||
</Button>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Button onClick={handleFollow} colorScheme="primary" icon={<FollowIcon />} isDisabled={isDisabled} {...props}>
|
||||
<Button
|
||||
onClick={handleFollow}
|
||||
colorScheme="primary"
|
||||
icon={<FollowIcon />}
|
||||
isDisabled={isDisabled}
|
||||
isLoading={loading}
|
||||
{...props}
|
||||
>
|
||||
Follow
|
||||
</Button>
|
||||
);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Filter, kinds, nip25 } from "nostr-tools";
|
||||
import _throttle from "lodash.throttle";
|
||||
|
||||
import NostrRequest from "../classes/nostr-request";
|
||||
import Subject from "../classes/subject";
|
||||
@ -22,6 +23,7 @@ class EventReactionsService {
|
||||
this.pending.get(eventId).add(relay);
|
||||
}
|
||||
}
|
||||
this.throttleBatchRequest();
|
||||
|
||||
return subject;
|
||||
}
|
||||
@ -41,9 +43,20 @@ class EventReactionsService {
|
||||
if (cache) localRelay.publish(event);
|
||||
}
|
||||
|
||||
throttleBatchRequest = _throttle(this.batchRequests, 2000);
|
||||
batchRequests() {
|
||||
if (this.pending.size === 0) return;
|
||||
|
||||
// load events from cache
|
||||
const uids = Array.from(this.pending.keys());
|
||||
const ids = uids.filter((id) => !id.includes(":"));
|
||||
const cords = uids.filter((id) => id.includes(":"));
|
||||
const filters: Filter[] = [];
|
||||
if (ids.length > 0) filters.push({ "#e": ids, kinds: [kinds.Reaction] });
|
||||
if (cords.length > 0) filters.push({ "#a": cords, kinds: [kinds.Reaction] });
|
||||
if (filters.length > 0)
|
||||
relayRequest(localRelay, filters).then((events) => events.forEach((e) => this.handleEvent(e, false)));
|
||||
|
||||
const idsFromRelays: Record<relay, eventId[]> = {};
|
||||
for (const [id, relays] of this.pending) {
|
||||
for (const relay of relays) {
|
||||
@ -53,14 +66,17 @@ class EventReactionsService {
|
||||
}
|
||||
|
||||
for (const [relay, ids] of Object.entries(idsFromRelays)) {
|
||||
const filter: Filter = { "#e": ids, kinds: [kinds.Reaction] };
|
||||
const eventIds = ids.filter((id) => !id.includes(":"));
|
||||
const coordinates = ids.filter((id) => id.includes(":"));
|
||||
const filters: Filter[] = [];
|
||||
if (eventIds.length > 0) filters.push({ "#e": eventIds, kinds: [kinds.Reaction] });
|
||||
if (coordinates.length > 0) filters.push({ "#a": coordinates, kinds: [kinds.Reaction] });
|
||||
|
||||
// load from local relay
|
||||
relayRequest(localRelay, [filter]).then((events) => events.forEach((e) => this.handleEvent(e, true)));
|
||||
|
||||
const request = new NostrRequest([relay]);
|
||||
request.onEvent.subscribe(this.handleEvent, this);
|
||||
request.start(filter);
|
||||
if (filters.length > 0) {
|
||||
const request = new NostrRequest([relay]);
|
||||
request.onEvent.subscribe(this.handleEvent, this);
|
||||
request.start(filters);
|
||||
}
|
||||
}
|
||||
this.pending.clear();
|
||||
}
|
||||
@ -68,8 +84,9 @@ class EventReactionsService {
|
||||
|
||||
const eventReactionsService = new EventReactionsService();
|
||||
|
||||
setInterval(() => {
|
||||
eventReactionsService.batchRequests();
|
||||
}, 1000 * 2);
|
||||
if (import.meta.env.DEV) {
|
||||
//@ts-expect-error
|
||||
window.eventReactionsService = eventReactionsService;
|
||||
}
|
||||
|
||||
export default eventReactionsService;
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Filter, kinds } from "nostr-tools";
|
||||
import _throttle from "lodash.throttle";
|
||||
|
||||
import NostrRequest from "../classes/nostr-request";
|
||||
import Subject from "../classes/subject";
|
||||
import SuperMap from "../classes/super-map";
|
||||
import { NostrEvent, isATag, isETag } from "../types/nostr-event";
|
||||
import { isHexKey } from "../helpers/nip19";
|
||||
import { relayRequest } from "../helpers/relay";
|
||||
import { localRelay } from "./local-relay";
|
||||
|
||||
@ -23,6 +23,7 @@ class EventZapsService {
|
||||
this.pending.get(eventUID).add(relay);
|
||||
}
|
||||
}
|
||||
this.throttleBatchRequest();
|
||||
|
||||
return subject;
|
||||
}
|
||||
@ -42,9 +43,20 @@ class EventZapsService {
|
||||
if (cache) localRelay.publish(event);
|
||||
}
|
||||
|
||||
throttleBatchRequest = _throttle(this.batchRequests, 2000);
|
||||
batchRequests() {
|
||||
if (this.pending.size === 0) return;
|
||||
|
||||
// load events from cache
|
||||
const uids = Array.from(this.pending.keys());
|
||||
const ids = uids.filter((id) => !id.includes(":"));
|
||||
const cords = uids.filter((id) => id.includes(":"));
|
||||
const filters: Filter[] = [];
|
||||
if (ids.length > 0) filters.push({ "#e": ids, kinds: [kinds.Zap] });
|
||||
if (cords.length > 0) filters.push({ "#a": cords, kinds: [kinds.Zap] });
|
||||
if (filters.length > 0)
|
||||
relayRequest(localRelay, filters).then((events) => events.forEach((e) => this.handleEvent(e, false)));
|
||||
|
||||
const idsFromRelays: Record<relay, eventUID[]> = {};
|
||||
for (const [id, relays] of this.pending) {
|
||||
for (const relay of relays) {
|
||||
@ -54,19 +66,17 @@ class EventZapsService {
|
||||
}
|
||||
|
||||
for (const [relay, ids] of Object.entries(idsFromRelays)) {
|
||||
const request = new NostrRequest([relay]);
|
||||
request.onEvent.subscribe(this.handleEvent, this);
|
||||
const eventIds = ids.filter(isHexKey);
|
||||
const eventIds = ids.filter((id) => !id.includes(":"));
|
||||
const coordinates = ids.filter((id) => id.includes(":"));
|
||||
const filter: Filter[] = [];
|
||||
if (eventIds.length > 0) filter.push({ "#e": eventIds, kinds: [kinds.Zap] });
|
||||
if (coordinates.length > 0) filter.push({ "#a": coordinates, kinds: [kinds.Zap] });
|
||||
|
||||
const queries: Filter[] = [];
|
||||
if (eventIds.length > 0) queries.push({ "#e": eventIds, kinds: [kinds.Zap] });
|
||||
if (coordinates.length > 0) queries.push({ "#a": coordinates, kinds: [kinds.Zap] });
|
||||
|
||||
// load from local relay
|
||||
relayRequest(localRelay, queries).then((events) => events.forEach((e) => this.handleEvent(e, false)));
|
||||
|
||||
request.start(queries);
|
||||
if (filter.length > 0) {
|
||||
const request = new NostrRequest([relay]);
|
||||
request.onEvent.subscribe(this.handleEvent, this);
|
||||
request.start(filter);
|
||||
}
|
||||
}
|
||||
this.pending.clear();
|
||||
}
|
||||
@ -79,8 +89,4 @@ if (import.meta.env.DEV) {
|
||||
window.eventZapsService = eventZapsService;
|
||||
}
|
||||
|
||||
setInterval(() => {
|
||||
eventZapsService.batchRequests();
|
||||
}, 1000 * 2);
|
||||
|
||||
export default eventZapsService;
|
||||
|
@ -65,21 +65,11 @@ async function connectRelay() {
|
||||
|
||||
export const localRelay = await connectRelay();
|
||||
|
||||
function pruneLocalDatabase() {
|
||||
if (localRelay instanceof CacheRelay) {
|
||||
pruneLastUsed(localRelay.db, 20_000);
|
||||
}
|
||||
}
|
||||
|
||||
// keep the relay connection alive
|
||||
setInterval(() => {
|
||||
if (!localRelay.connected) localRelay.connect().then(() => log("Reconnected"));
|
||||
}, 1000 * 5);
|
||||
|
||||
setInterval(() => {
|
||||
pruneLocalDatabase();
|
||||
}, 1000 * 60);
|
||||
|
||||
if (import.meta.env.DEV) {
|
||||
//@ts-ignore
|
||||
window.localDatabase = localDatabase;
|
||||
|
@ -201,7 +201,7 @@ class ReplaceableEventLoaderService {
|
||||
|
||||
loading.set(cord, p);
|
||||
}
|
||||
const filters = Array.from(Object.values(kindFilters));
|
||||
const filters = Object.values(kindFilters);
|
||||
|
||||
for (const [cord] of loading) this.readFromCachePromises.delete(cord);
|
||||
|
||||
|
@ -164,7 +164,7 @@ function CommunitiesHomePage() {
|
||||
</Flex>
|
||||
</Flex>
|
||||
) : (
|
||||
<Center aspectRatio={3 / 4} flexDirection="column" gap="4">
|
||||
<Center py="20" flexDirection="column" gap="4">
|
||||
<Heading size="md">No communities :(</Heading>
|
||||
<Text>
|
||||
go find a cool one to join.{" "}
|
||||
|
@ -5244,10 +5244,10 @@ normalize-package-data@^2.5.0:
|
||||
semver "2 || 3 || 4 || 5"
|
||||
validate-npm-package-license "^3.0.1"
|
||||
|
||||
nostr-idb@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/nostr-idb/-/nostr-idb-2.1.0.tgz#81ba6381086e7e10a2e916a026101caa8d77218e"
|
||||
integrity sha512-hAdLn3b3S5JJ77CuMo7tD25BsKnJ1XXuuGBLad8pjdhVEG9RIJhLvUYmgfx0Ylwj4Xuar57csaepSDJzKj/sYw==
|
||||
nostr-idb@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/nostr-idb/-/nostr-idb-2.1.1.tgz#5aaf4ebb793266c87ab7c9d72ed4be3bcae79fc2"
|
||||
integrity sha512-vUdRPOJkWtEovsL0CqnniiuwIqastHby7nf2NKyhvO5MV5Dyl9CBxs9nIcAHB5GJHDV7nt+t6SF193Odorp/1g==
|
||||
dependencies:
|
||||
debug "^4.3.4"
|
||||
idb "^8.0.0"
|
||||
|
Loading…
x
Reference in New Issue
Block a user