Browse Source

speed up performance

imwald
Silberengel 1 month ago
parent
commit
55b6c2071a
  1. 4
      src/components/ReplyNoteList/index.tsx
  2. 16
      src/constants.ts
  3. 5
      src/hooks/useQuoteEvents.tsx
  4. 6
      src/lib/favorites-feed-relays.ts
  5. 23
      src/lib/relay-extended-tag-req-blocks.ts
  6. 15
      src/pages/primary/SpellsPage/fauxSpellFeeds.ts
  7. 13
      src/services/client-replaceable-events.service.ts
  8. 1
      src/services/client.service.ts
  9. 11
      src/services/note-stats.service.ts

4
src/components/ReplyNoteList/index.tsx

@ -1,5 +1,4 @@ @@ -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({ @@ -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,

16
src/constants.ts

@ -402,7 +402,8 @@ export const DOCUMENT_RELAY_URLS = [ @@ -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 = [ @@ -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 = [ @@ -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.

5
src/hooks/useQuoteEvents.tsx

@ -1,5 +1,4 @@ @@ -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) { @@ -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) { @@ -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)

6
src/lib/favorites-feed-relays.ts

@ -3,7 +3,6 @@ import { @@ -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( @@ -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( @@ -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)
}

23
src/lib/relay-extended-tag-req-blocks.ts

@ -1,18 +1,5 @@ @@ -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<string> | null = null
function extendedTagReqBlockedLowerSet(): Set<string> {
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[]): @@ -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
}

15
src/pages/primary/SpellsPage/fauxSpellFeeds.ts

@ -14,7 +14,6 @@ import { @@ -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 @@ -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 @@ -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<string>()
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)
}

13
src/services/client-replaceable-events.service.ts

@ -8,7 +8,6 @@ import { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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

1
src/services/client.service.ts

@ -30,7 +30,6 @@ import { @@ -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

11
src/services/note-stats.service.ts

@ -1,5 +1,4 @@ @@ -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 { @@ -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 { @@ -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<string[]> {
const blocked = new Set(
E_TAG_FILTER_BLOCKED_RELAY_URLS.map((u) => (normalizeUrl(u) || u).toLowerCase()).filter(Boolean)
)
const seen = new Set<string>()
const add = (url: string | undefined) => {
@ -602,8 +597,7 @@ class NoteStatsService { @@ -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 { @@ -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
})

Loading…
Cancel
Save