Skip to content

Commit 87f8897

Browse files
committed
perf directory
1 parent 7e6fb4f commit 87f8897

File tree

5 files changed

+63
-35
lines changed

5 files changed

+63
-35
lines changed

astro.config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ export default defineConfig({
110110
vite: {
111111
plugins: [yaml()],
112112
build: {
113+
target: "es2020",
113114
// Optimize CSS delivery
114115
cssMinify: true,
115116
// Increase the threshold for inlining assets
@@ -121,6 +122,9 @@ export default defineConfig({
121122
// }
122123
// },
123124
},
125+
esbuild: {
126+
target: "es2020",
127+
},
124128
css: {
125129
devSourcemap: false,
126130
},

src/components/CCIP/Search/Search.tsx

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,22 @@ function Search({ chains, tokens, small, environment, lanes }: SearchProps) {
5252
const [lanesResults, setLanesResults] = useState<typeof lanes>([])
5353
const searchRef = useRef<HTMLDivElement>(null)
5454
const workerRef = useRef<Worker | null>(null)
55+
const workerReadyRef = useRef(false)
5556

56-
// Initialize Web Worker
57-
useEffect(() => {
58-
if (typeof window !== "undefined") {
59-
// Import the worker as a URL that Vite will process
60-
workerRef.current = new Worker(new URL("~/workers/data-worker.ts", import.meta.url), { type: "module" })
61-
62-
workerRef.current.onmessage = (event: MessageEvent<WorkerResponse>) => {
63-
const { networks, tokens: workerTokens, lanes: workerLanes } = event.data
64-
setNetworksResults(networks || [])
65-
setTokensResults(workerTokens || [])
66-
setLanesResults(workerLanes || [])
67-
}
57+
// Lazily initialize Web Worker on first interaction
58+
const ensureWorker = () => {
59+
if (workerReadyRef.current || typeof window === "undefined") return
60+
workerRef.current = new Worker(new URL("~/workers/data-worker.ts", import.meta.url), { type: "module" })
61+
workerRef.current.onmessage = (event: MessageEvent<WorkerResponse>) => {
62+
const { networks, tokens: workerTokens, lanes: workerLanes } = event.data
63+
setNetworksResults(networks || [])
64+
setTokensResults(workerTokens || [])
65+
setLanesResults(workerLanes || [])
6866
}
67+
workerReadyRef.current = true
68+
}
6969

70+
useEffect(() => {
7071
return () => {
7172
if (workerRef.current) {
7273
workerRef.current.terminate()
@@ -92,6 +93,8 @@ function Search({ chains, tokens, small, environment, lanes }: SearchProps) {
9293
return
9394
}
9495

96+
// Ensure worker exists before posting message
97+
if (!workerReadyRef.current) ensureWorker()
9598
if (workerRef.current) {
9699
const message: WorkerMessage = {
97100
search: debouncedSearch,
@@ -114,7 +117,7 @@ function Search({ chains, tokens, small, environment, lanes }: SearchProps) {
114117
}
115118
}, [debouncedSearch])
116119

117-
useClickOutside(searchRef, () => setOpenSearchMenu(false))
120+
useClickOutside(searchRef, () => setOpenSearchMenu(false), { enabled: openSearchMenu })
118121

119122
const generateExplorerUrl = (lane): ExplorerInfo => {
120123
const directory = directoryToSupportedChain(lane.sourceNetwork.key)
@@ -146,7 +149,10 @@ function Search({ chains, tokens, small, environment, lanes }: SearchProps) {
146149
placeholder="Network/Token/Lane"
147150
value={search}
148151
onChange={(e) => setSearch(e.target.value)}
149-
onFocus={() => setIsActive(true)}
152+
onFocus={() => {
153+
setIsActive(true)
154+
ensureWorker()
155+
}}
150156
onBlur={() => setIsActive(false)}
151157
/>
152158
{openSearchMenu && (

src/components/HeadCommon.astro

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,7 @@ const { title } = Astro.props
3232
<link rel="preconnect" href="https://js.usemessages.com" crossorigin />
3333

3434
<!-- Preload critical fonts -->
35-
<link
36-
rel="preload"
37-
href="https://smartcontract.imgix.net/fonts/Inter-VariableFont_opsz,wght.ttf"
38-
as="font"
39-
type="font/ttf"
40-
crossorigin
41-
/>
35+
<!-- Remove heavy TTF preload to cut ~1.7MB; rely on system fonts or WOFF2 subsets -->
4236
<link
4337
rel="preload"
4438
href="https://smartcontract.imgix.net/fonts/TASAOrbiterDisplay-SemiBold.woff"
@@ -50,20 +44,41 @@ const { title } = Astro.props
5044
<!-- Scrollable a11y code helper - defer to not block render -->
5145
<script src="/make-scrollable-code-focusable.js" defer></script>
5246

53-
<!-- Google Tag Manager -->
47+
<!-- Preconnects to speed GTM/GA when they load -->
48+
<link rel="preconnect" href="https://www.googletagmanager.com" crossorigin />
49+
<link rel="preconnect" href="https://www.google-analytics.com" crossorigin />
50+
51+
<!-- Google Tag Manager (lazy init on first interaction or idle) -->
5452
<script type="text/javascript">
5553
;(function (w, d, s, l, i) {
5654
w[l] = w[l] || []
5755
w[l].push({ "gtm.start": new Date().getTime(), event: "gtm.js" })
58-
var f = d.getElementsByTagName(s)[0],
59-
j = d.createElement(s),
60-
dl = l != "dataLayer" ? "&l=" + l : ""
61-
j.async = true
62-
j.src = "https://www.googletagmanager.com/gtm.js?id=" + i + dl
63-
f.parentNode.insertBefore(j, f)
56+
function loadGTM() {
57+
if (w.__gtmLoaded) return
58+
w.__gtmLoaded = true
59+
var f = d.getElementsByTagName(s)[0],
60+
j = d.createElement(s),
61+
dl = l != "dataLayer" ? "&l=" + l : ""
62+
j.async = true
63+
j.src = "https://www.googletagmanager.com/gtm.js?id=" + i + dl
64+
f.parentNode.insertBefore(j, f)
65+
}
66+
function onFirstInput() {
67+
loadGTM()
68+
;["pointerdown", "keydown", "wheel", "touchstart"].forEach((evt) =>
69+
d.removeEventListener(evt, onFirstInput, { passive: true })
70+
)
71+
}
72+
;["pointerdown", "keydown", "wheel", "touchstart"].forEach((evt) =>
73+
d.addEventListener(evt, onFirstInput, { passive: true })
74+
)
75+
if ("requestIdleCallback" in w) {
76+
requestIdleCallback(loadGTM, { timeout: 3000 })
77+
} else {
78+
setTimeout(loadGTM, 3000)
79+
}
6480
})(window, document, "script", "dataLayer", "GTM-N6DQ47T")
6581
</script>
66-
<!-- End Google Tag Manager -->
6782

6883
<meta name="algolia-site-verification" content="5C6E2FAC077D2F49" />
6984

src/features/utils/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,11 @@ const transformTokenName = (token: string): string => {
132132
.replace(/\+/g, "%2B") // Step 3: Replace plus signs with %2B
133133
}
134134

135-
export const getTokenIconUrl = (token: string, size = 80) => {
135+
export const getTokenIconUrl = (token: string, size = 40) => {
136136
if (!token) return ""
137137
// Request appropriately sized images from CloudFront
138138
// For 40x40 display, request 80x80 for retina displays (2x)
139-
return `https://d2f70xi62kby8n.cloudfront.net/tokens/${transformTokenName(token)}.webp?auto=compress%2Cformat&w=${size}&h=${size}&fit=cover`
139+
return `https://d2f70xi62kby8n.cloudfront.net/tokens/${transformTokenName(token)}.webp?auto=compress%2Cformat&q=60&w=${size}&h=${size}&fit=cover`
140140
}
141141

142142
export const fallbackTokenIconUrl = "/assets/icons/generic-token.svg"

src/hooks/useClickOutside.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,23 @@ import { RefObject, useEffect } from "react"
22

33
export const useClickOutside = <T extends HTMLElement>(
44
ref: RefObject<T | null>,
5-
handleOnClickOutside: (event: MouseEvent | TouchEvent) => void
5+
handleOnClickOutside: (event: MouseEvent | TouchEvent) => void,
6+
options?: { enabled?: boolean }
67
) => {
78
useEffect(() => {
9+
if (options?.enabled === false) return
10+
811
const listener = (event: MouseEvent | TouchEvent) => {
912
if (!ref.current || ref.current.contains(event.target as Node)) {
1013
return
1114
}
1215
handleOnClickOutside(event)
1316
}
14-
document.addEventListener("mousedown", listener)
15-
document.addEventListener("touchstart", listener)
17+
document.addEventListener("mousedown", listener, { passive: true })
18+
document.addEventListener("touchstart", listener, { passive: true })
1619
return () => {
1720
document.removeEventListener("mousedown", listener)
1821
document.removeEventListener("touchstart", listener)
1922
}
20-
}, [ref, handleOnClickOutside])
23+
}, [ref, handleOnClickOutside, options?.enabled])
2124
}

0 commit comments

Comments
 (0)