From 55b6c2071a5382fe000aad71e9df968d7372cd6b Mon Sep 17 00:00:00 2001 From: Silberengel Date: Sat, 16 May 2026 20:05:52 +0200 Subject: [PATCH] speed up performance --- src/components/ReplyNoteList/index.tsx | 4 +--- src/constants.ts | 16 +++---------- src/hooks/useQuoteEvents.tsx | 5 ---- src/lib/favorites-feed-relays.ts | 6 ++--- src/lib/relay-extended-tag-req-blocks.ts | 23 +++---------------- .../primary/SpellsPage/fauxSpellFeeds.ts | 15 ++---------- .../client-replaceable-events.service.ts | 13 +++++------ src/services/client.service.ts | 1 - src/services/note-stats.service.ts | 11 ++------- 9 files changed, 19 insertions(+), 75 deletions(-) diff --git a/src/components/ReplyNoteList/index.tsx b/src/components/ReplyNoteList/index.tsx index 30d7f7c3..3b33d89f 100644 --- a/src/components/ReplyNoteList/index.tsx +++ b/src/components/ReplyNoteList/index.tsx @@ -1,5 +1,4 @@ import { - E_TAG_FILTER_BLOCKED_RELAY_URLS, ExtendedKind, NOTE_STATS_OP_REFERENCE_KINDS, NOTE_STATS_OP_REFERENCE_KINDS_WITHOUT_HIGHLIGHT @@ -1127,8 +1126,7 @@ function ReplyNoteList({ ...new Set([...relayHintsFromEventTags(event), ...seenOn, ...fromBrowsingFeed]) ] const replyBlockedRelays = [ - ...(blockedRelays || []), - ...E_TAG_FILTER_BLOCKED_RELAY_URLS + ...(blockedRelays || []) ] const finalRelayUrls = await buildReplyReadRelayList( opAuthorPubkey, diff --git a/src/constants.ts b/src/constants.ts index 7fa8e8b0..2d2f00a0 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -402,7 +402,8 @@ export const DOCUMENT_RELAY_URLS = [ /** * Relays that must never receive publishes: search engines, index mirrors, and similar endpoints that only ingest - * or aggregate for read. Distinct from {@link SOCIAL_KIND_BLOCKED_RELAY_URLS} (kind-coverage limits, not write policy). + * or aggregate for read. Use only to strip URLs from publish / write / publish-picker paths — do not prepend this + * list to generic read REQ stacks. Distinct from {@link SOCIAL_KIND_BLOCKED_RELAY_URLS} (kind-coverage limits). */ export const READ_ONLY_RELAY_URLS = [ 'wss://aggr.nostr.land', @@ -440,16 +441,6 @@ export const SOCIAL_KIND_BLOCKED_RELAY_URLS = [ 'wss://hist.nostr.land', ] -/** - * Relays that reject certain tag filters in REQs (e.g. `#e` on some stacks) and, on nostr.sovbit.host, - * filter keys whose tag letter is uppercase (`#E`, `#A`, `#I`, …). Skip for reply/quote/stats fetches and - * whenever filters use a capital letter after `#` in a tag key (see `relayFiltersUseCapitalLetterTagKeys` in - * `relay-extended-tag-req-blocks.ts`). - */ -export const E_TAG_FILTER_BLOCKED_RELAY_URLS = [ - 'wss://nostr.v0l.io', -] - // Optimized relay list for read operations (includes aggregator) export const FAST_READ_RELAY_URLS = [ 'wss://theforest.nostr1.com', @@ -464,8 +455,7 @@ export const FAST_WRITE_RELAY_URLS = [ 'wss://relay.damus.io', 'wss://relay.primal.net', 'wss://thecitadel.nostr1.com', - 'wss://nos.lol', - 'wss://freelay.sovbit.host' + 'wss://nos.lol' ] /** Relays used for NIP-94 file metadata (kind 1063) / GIF discovery and publish. diff --git a/src/hooks/useQuoteEvents.tsx b/src/hooks/useQuoteEvents.tsx index 1f0f9fc5..20240790 100644 --- a/src/hooks/useQuoteEvents.tsx +++ b/src/hooks/useQuoteEvents.tsx @@ -1,5 +1,4 @@ import { - E_TAG_FILTER_BLOCKED_RELAY_URLS, ExtendedKind, FAST_READ_RELAY_URLS, NOTE_STATS_OP_REFERENCE_KINDS_WITHOUT_HIGHLIGHT, @@ -81,9 +80,6 @@ export function useQuoteEvents(event: Event | null, enabled: boolean) { const userRelays = userRelayList?.read || [] const fromFeed = browsingRelayUrls.map((u) => normalizeAnyRelayUrl(u) || u).filter(Boolean) const seenOn = client.getSeenEventRelayUrls(ev.id) - const eTagBlockedSet = new Set( - E_TAG_FILTER_BLOCKED_RELAY_URLS.map((u) => normalizeUrl(u) || u) - ) const finalRelayUrls = Array.from( new Set([ ...fromFeed, @@ -94,7 +90,6 @@ export function useQuoteEvents(event: Event | null, enabled: boolean) { ]) ) .filter(Boolean) - .filter((u) => !eTagBlockedSet.has(normalizeUrl(u) || u)) .filter((u) => !userBlockedRelaysNorm.has((normalizeUrl(u) || u).toLowerCase())) const filterQeId = isReplaceableEvent(ev.kind) diff --git a/src/lib/favorites-feed-relays.ts b/src/lib/favorites-feed-relays.ts index 0fec7f10..4843b017 100644 --- a/src/lib/favorites-feed-relays.ts +++ b/src/lib/favorites-feed-relays.ts @@ -3,7 +3,6 @@ import { DOCUMENT_RELAY_URLS, FAST_READ_RELAY_URLS, PROFILE_RELAY_URLS, - READ_ONLY_RELAY_URLS, isDocumentRelayKind, relayFilterIncludesSocialKindBlockedKind } from '@/constants' @@ -102,7 +101,7 @@ export function buildAuthorInboxOutboxRelayUrls( /** * Profile pins + Medien: author NIP-65 tier (pass from {@link buildAuthorInboxOutboxRelayUrls}), then - * {@link READ_ONLY_RELAY_URLS}, then {@link FAST_READ_RELAY_URLS}; dedupe, blocked-stripped, capped. + * {@link FAST_READ_RELAY_URLS}; dedupe, blocked-stripped, capped. */ const PROFILE_AUGMENTED_READ_MAX_RELAYS = 16 @@ -112,12 +111,11 @@ export function buildProfileAugmentedReadRelayUrls( maxRelays: number = PROFILE_AUGMENTED_READ_MAX_RELAYS, useGlobalRelayBootstrap = true ): string[] { - const readOnlyLayer = READ_ONLY_RELAY_URLS.map((u) => normalizeUrl(u) || u).filter(Boolean) const fastReadLayer = useGlobalRelayBootstrap ? (FAST_READ_RELAY_URLS.map((u) => normalizeUrl(u) || u).filter(Boolean) as string[]) : [] - const merged = mergeRelayUrlLayers([authorRelayUrls, readOnlyLayer, fastReadLayer], blockedRelays) + const merged = mergeRelayUrlLayers([authorRelayUrls, fastReadLayer], blockedRelays) return merged.slice(0, maxRelays) } diff --git a/src/lib/relay-extended-tag-req-blocks.ts b/src/lib/relay-extended-tag-req-blocks.ts index 179e39fe..f8f70b3f 100644 --- a/src/lib/relay-extended-tag-req-blocks.ts +++ b/src/lib/relay-extended-tag-req-blocks.ts @@ -1,18 +1,5 @@ -import { E_TAG_FILTER_BLOCKED_RELAY_URLS } from '@/constants' -import { normalizeUrl } from '@/lib/url' import type { Filter } from 'nostr-tools' -let blockedLowerMemo: Set | null = null - -function extendedTagReqBlockedLowerSet(): Set { - if (!blockedLowerMemo) { - blockedLowerMemo = new Set( - E_TAG_FILTER_BLOCKED_RELAY_URLS.map((u) => (normalizeUrl(u) || u).toLowerCase()).filter(Boolean) - ) - } - return blockedLowerMemo -} - /** NIP-01 tag filters are `#` + tag name; keys like `#E` / `#A` / `#I` are uppercase variants. */ const CAPITAL_LEADING_TAG_FILTER_KEY = /^#[A-Z]/ @@ -33,13 +20,9 @@ export function relayFiltersUseCapitalLetterTagKeys(filter: Filter | Filter[]): } /** - * Relays in {@link E_TAG_FILTER_BLOCKED_RELAY_URLS} reject `#e`-style queries and, on some stacks, any tag - * filter key that uses a capital letter after `#`. Drop them before REQ so we do not spam NOTICE/rate-limit responses. + * Legacy hook after {@link E_TAG_FILTER_BLOCKED_RELAY_URLS} was removed. Call sites that still + * run when filters use `#E`-style keys are unchanged; no relays are stripped here anymore. */ export function relayUrlsStripExtendedTagReqBlocked(urls: string[]): string[] { - const blocked = extendedTagReqBlockedLowerSet() - return urls.filter((u) => { - const n = normalizeUrl(u) || u.trim() - return n && !blocked.has(n.toLowerCase()) - }) + return urls } diff --git a/src/pages/primary/SpellsPage/fauxSpellFeeds.ts b/src/pages/primary/SpellsPage/fauxSpellFeeds.ts index 061e02e5..6ce5764e 100644 --- a/src/pages/primary/SpellsPage/fauxSpellFeeds.ts +++ b/src/pages/primary/SpellsPage/fauxSpellFeeds.ts @@ -14,7 +14,6 @@ import { ExtendedKind, FAST_READ_RELAY_URLS, PROFILE_MEDIA_TAB_KINDS, - READ_ONLY_RELAY_URLS } from '@/constants' import { RENDERABLE_NOTE_KINDS_SORTED } from '@/lib/note-renderable-kinds' import { buildProfileAugmentedReadRelayUrls } from '@/lib/favorites-feed-relays' @@ -83,11 +82,6 @@ const INTERESTS_MAX_TOPICS = 80 */ const INTERESTS_MAX_TOPIC_TAG_VALUES = INTERESTS_MAX_TOPICS * 4 -/** - * Put {@link READ_ONLY_RELAY_URLS} (e.g. aggr) **first**, then curated relays. Faux spells cap URL count - * ({@link FAUX_SPELL_MAX_RELAYS}); appending read-only at the end dropped mirrors whenever inbox+favorites - * filled the cap. - */ /** * {@link buildPrioritizedReadRelayUrls} merges inbox → favorites → FAST_READ under {@link FAUX_SPELL_MAX_RELAYS}. * Long NIP-65 read lists can fill the cap before FAST_READ is reached, so every REQ shard was only dead/private @@ -147,19 +141,14 @@ export function ensureFauxSpellRelayStackTouchesFastRead(urls: string[]): string }) } +/** Dedupe curated read relays and drop user-blocked URLs (no {@link READ_ONLY_RELAY_URLS} prepend). */ export function appendCuratedReadOnlyRelays(curated: string[], blockedRelays: string[]): string[] { const blocked = new Set(blockedRelays.map((b) => normalizeAnyRelayUrl(b) || b)) const seen = new Set() const out: string[] = [] - for (const u of READ_ONLY_RELAY_URLS) { - const k = normalizeAnyRelayUrl(u) || u - if (!k || blocked.has(k) || seen.has(k)) continue - seen.add(k) - out.push(k) - } for (const u of curated) { const k = normalizeAnyRelayUrl(u) || u - if (!k || seen.has(k)) continue + if (!k || blocked.has(k) || seen.has(k)) continue seen.add(k) out.push(k) } diff --git a/src/services/client-replaceable-events.service.ts b/src/services/client-replaceable-events.service.ts index 1a5e7e10..124784f0 100644 --- a/src/services/client-replaceable-events.service.ts +++ b/src/services/client-replaceable-events.service.ts @@ -8,7 +8,6 @@ import { METADATA_BATCH_QUERY_GLOBAL_TIMEOUT_MS, PROFILE_BATCH_NETWORK_LOAD_TIMEOUT_MS, PROFILE_RELAY_URLS, - READ_ONLY_RELAY_URLS, RECOMMENDED_BLOSSOM_SERVERS } from '@/constants' import { kinds, nip19 } from 'nostr-tools' @@ -558,7 +557,7 @@ export class ReplaceableEventService { // and 100ms EOSE loses the race when several relays are down. relayUrls = Array.from( new Set( - [...READ_ONLY_RELAY_URLS, ...PROFILE_RELAY_URLS, ...FAST_READ_RELAY_URLS].map( + [...PROFILE_RELAY_URLS, ...FAST_READ_RELAY_URLS].map( (u) => normalizeUrl(u) || u ) ) @@ -567,7 +566,7 @@ export class ReplaceableEventService { // Contacts (kind 3): aggregators + profile mirrors + fast read. relayUrls = Array.from( new Set( - [...READ_ONLY_RELAY_URLS, ...PROFILE_RELAY_URLS, ...FAST_READ_RELAY_URLS].map( + [...PROFILE_RELAY_URLS, ...FAST_READ_RELAY_URLS].map( (u) => normalizeUrl(u) || u ) ) @@ -576,7 +575,7 @@ export class ReplaceableEventService { // NIP-65 (10002): aggregators + profile mirrors + fast read. relayUrls = Array.from( new Set( - [...READ_ONLY_RELAY_URLS, ...PROFILE_RELAY_URLS, ...FAST_READ_RELAY_URLS].map( + [...PROFILE_RELAY_URLS, ...FAST_READ_RELAY_URLS].map( (u) => normalizeUrl(u) || u ) ) @@ -585,7 +584,7 @@ export class ReplaceableEventService { // Mute / bookmark lists: same distribution as contacts; FAST_READ + mirrors. relayUrls = Array.from( new Set( - [...READ_ONLY_RELAY_URLS, ...PROFILE_RELAY_URLS, ...FAST_READ_RELAY_URLS].map( + [...PROFILE_RELAY_URLS, ...FAST_READ_RELAY_URLS].map( (u) => normalizeUrl(u) || u ) ) @@ -594,7 +593,7 @@ export class ReplaceableEventService { // NIP-A3 kind 10133: aggregators + profile mirrors + fast read. relayUrls = Array.from( new Set( - [...READ_ONLY_RELAY_URLS, ...PROFILE_RELAY_URLS, ...FAST_READ_RELAY_URLS].map( + [...PROFILE_RELAY_URLS, ...FAST_READ_RELAY_URLS].map( (u) => normalizeUrl(u) || u ) ) @@ -1244,7 +1243,7 @@ export class ReplaceableEventService { /** * Fetch follow list event. * When relayUrls are provided (e.g. user write + search relays), queries those directly. - * Otherwise uses the default relay set (READ_ONLY + PROFILE_FETCH + FAST_READ). + * Otherwise uses the default relay set (PROFILE_RELAY_URLS + FAST_READ). */ /** Hard cap: {@link fetchReplaceableEvent} can otherwise wedge the DataLoader chain when relays never answer. */ private static readonly FETCH_FOLLOW_LIST_REPLACEABLE_TIMEOUT_MS = 14_000 diff --git a/src/services/client.service.ts b/src/services/client.service.ts index 79795465..6d13e2ca 100644 --- a/src/services/client.service.ts +++ b/src/services/client.service.ts @@ -30,7 +30,6 @@ import { DEFAULT_FAVORITE_RELAYS, NIP66_DISCOVERY_RELAY_URLS, PROFILE_RELAY_URLS, - PROFILE_RELAY_URLS, READ_ONLY_RELAY_URLS, NIP42_POOL_AUTOMATIC_AUTH_RELAY_URLS, SEARCHABLE_RELAY_URLS diff --git a/src/services/note-stats.service.ts b/src/services/note-stats.service.ts index c4486b50..b3868d12 100644 --- a/src/services/note-stats.service.ts +++ b/src/services/note-stats.service.ts @@ -1,5 +1,4 @@ import { - E_TAG_FILTER_BLOCKED_RELAY_URLS, ExtendedKind, FAST_READ_RELAY_URLS, NOTE_STATS_OP_REFERENCE_KINDS_WITHOUT_HIGHLIGHT, @@ -35,7 +34,7 @@ import { getNip25ReactionTargetHexFromTags, tagNameEquals } from '@/lib/tag' -import { normalizeAnyRelayUrl, normalizeUrl } from '@/lib/url' +import { normalizeAnyRelayUrl } from '@/lib/url' import client, { eventService } from '@/services/client.service' import { TEmoji, type TRelayList } from '@/types' import dayjs from 'dayjs' @@ -589,12 +588,8 @@ class NoteStatsService { /** * Build relay list for note stats: SEARCHABLE + FAST_READ + optional user favorites + seen relays + * `e`-tag hints on the note + hints from session-cached referrers + author NIP-65 read (slice 10). - * Excludes E_TAG_FILTER_BLOCKED_RELAY_URLS (stats use #e filters). */ private async buildNoteStatsRelayList(event: Event, favoriteRelays?: string[] | null): Promise { - const blocked = new Set( - E_TAG_FILTER_BLOCKED_RELAY_URLS.map((u) => (normalizeUrl(u) || u).toLowerCase()).filter(Boolean) - ) const seen = new Set() const add = (url: string | undefined) => { @@ -602,8 +597,7 @@ class NoteStatsService { // Must use normalizeAnyRelayUrl, not normalizeUrl: the latter converts http(s):// // index relay URLs into ws(s):// which then hit the WebSocket pool. const n = normalizeAnyRelayUrl(url) - if (!n || blocked.has(n.toLowerCase()) || seen.has(n)) return - seen.add(n) + if (n) seen.add(n) } // 1. Search / discovery relay set (includes read-only index mirrors; see READ_ONLY_RELAY_URLS in constants) @@ -660,7 +654,6 @@ class NoteStatsService { return feedRelayPolicyUrls([{ source: 'fallback', urls: Array.from(seen) }], { operation: 'read', - blockedRelays: E_TAG_FILTER_BLOCKED_RELAY_URLS, applySocialKindBlockedFilter: false, allowThirdPartyLocalRelays: true })