Skip to content

Commit 8d02338

Browse files
committed
chore: scripts load optimization
1 parent d0bc107 commit 8d02338

File tree

6 files changed

+407
-208
lines changed

6 files changed

+407
-208
lines changed

src/components/Favicons.astro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@
9797
<meta name="msapplication-wide310x150logo" content="/favicons/_misc/mstile-310x150.png" />
9898
<meta name="msapplication-square310x310logo" content="/favicons/_misc/mstile-310x310.png" />
9999

100-
<!-- Apple Mobile Web App -->
100+
<!-- Mobile Web App -->
101101
<meta name="apple-mobile-web-app-title" content="Datum" />
102-
<meta name="apple-mobile-web-app-capable" content="yes" />
102+
<meta name="mobile-web-app-capable" content="yes" />
103103
<meta name="apple-mobile-web-app-status-bar-style" content="default" />

src/components/forms/Signup.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import Icon from '@components/Icon.astro';
2222
autocomplete="email"
2323
required
2424
/>
25-
<button class="footer-signup-button">
25+
<button class="footer-signup-button" name="signup-button" aria-label="Sign up button">
2626
<Icon name="circle-arrow-right" size="xl" class="stroke-[1.25]" />
2727
</button>
2828

src/components/starlight/Head.astro

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,23 @@ const hasTwitterImage = head.some(
8888
<!-- Favicons -->
8989
<Favicons />
9090

91+
<!-- DNS Prefetch for external domains (low priority hints) -->
92+
<link rel="dns-prefetch" href="https://api.github.com" />
93+
<link rel="dns-prefetch" href="https://beacon-v2.helpscout.net" />
94+
95+
<!-- Preconnect to critical external domains (loads within ~5s) -->
96+
<link rel="preconnect" href="https://cdn.usefathom.com" crossorigin />
97+
<link rel="preconnect" href="https://edge.marker.io" crossorigin />
98+
99+
<!-- Preload critical font for better performance -->
100+
<link
101+
rel="preload"
102+
href="/fonts/datum/allianceno1-regular-webfont.woff2"
103+
as="font"
104+
type="font/woff2"
105+
crossorigin
106+
/>
107+
91108
<!-- Add og:logo, og:image and twitter:image if not present in Starlight's head -->
92109
<meta property="og:logo" content={new URL('/images/logo-datum.png', Astro.site).href} />
93110
{!hasOgImage && <meta property="og:image" content={ogImage.src} />}

src/components/starlight/PageFrame.astro

Lines changed: 135 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -53,38 +53,142 @@ const shouldRenderSearch =
5353
}
5454
</style>
5555

56-
<script type="text/javascript" defer is:inline>
57-
/* eslint @typescript-eslint/no-unused-expressions: "off" */
58-
!(function (e, t, n) {
59-
function a() {
60-
var e = t.getElementsByTagName('script')[0],
61-
n = t.createElement('script');
62-
((n.type = 'text/javascript'),
63-
(n.async = !0),
64-
(n.src = 'https://beacon-v2.helpscout.net'),
65-
e.parentNode.insertBefore(n, e));
66-
}
67-
if (
68-
((e.Beacon = n =
69-
function (t, n, a) {
70-
e.Beacon.readyQueue.push({ method: t, options: n, data: a });
71-
}),
72-
(n.readyQueue = []),
73-
'complete' === t.readyState)
74-
)
75-
return a();
76-
e.attachEvent ? e.attachEvent('onload', a) : e.addEventListener('load', a, !1);
77-
})(window, document, window.Beacon || function () {});
78-
</script>
79-
{
80-
import.meta.env.MODE === 'production' && (
81-
<script type="text/javascript" defer is:inline>
82-
window.Beacon('init', '57a7245e-772c-4d51-bdb1-6b898f34f2cb');
83-
</script>
84-
)
85-
}
86-
8756
<script>
8857
import '/src/v1/scripts/lenis-parallax.js';
8958
import '/src/v1/scripts/glossary-tooltip.js';
9059
</script>
60+
61+
{/* HelpScout Beacon open trigger handler */}
62+
<script>
63+
document.addEventListener('DOMContentLoaded', function () {
64+
const beaconTriggers = document.querySelectorAll('.open-beacon');
65+
beaconTriggers.forEach((trigger) => {
66+
trigger.addEventListener('click', function (e) {
67+
e.preventDefault();
68+
// @ts-expect-error Beacon is loaded from HelpScout script
69+
if (window.Beacon) {
70+
// @ts-expect-error Beacon is loaded from HelpScout script
71+
window.Beacon('open');
72+
}
73+
});
74+
});
75+
});
76+
</script>
77+
78+
{/* Hyperping Status Badge - Load on idle to not block main thread */}
79+
<script is:inline>
80+
/* eslint-disable no-undef */
81+
(function () {
82+
function initHyperping() {
83+
var script = document.createElement('script');
84+
script.src = 'https://hyperping.com/badge.js';
85+
script.async = true;
86+
script.onload = function () {
87+
if (typeof Hyperping !== 'undefined') {
88+
Hyperping.init({
89+
statuspage: 'https://www.datumstatus.com',
90+
border: 'none',
91+
borderColor: '#30363D',
92+
uptime: false,
93+
dot: true,
94+
dotSize: 10,
95+
isNeutral: false,
96+
dotOk: '#2BAC76',
97+
dotIncident: '#FFAF36',
98+
dotOutage: '#E95858',
99+
dotMaintenance: '#0070F3',
100+
dotNeutral: '#0070F3',
101+
operational: 'All systems normal',
102+
incident: 'Under investigation',
103+
outage: 'System outage',
104+
maintenance: 'Under maintenance',
105+
});
106+
}
107+
};
108+
document.body.appendChild(script);
109+
}
110+
// Load on idle or after 3s timeout (whichever comes first)
111+
if ('requestIdleCallback' in window) {
112+
requestIdleCallback(initHyperping, { timeout: 3000 });
113+
} else {
114+
setTimeout(initHyperping, 2000);
115+
}
116+
})();
117+
</script>
118+
119+
{/* HelpScout Beacon - Deferred loading on idle */}
120+
<script is:inline data-production={import.meta.env.PROD ? 'true' : 'false'}>
121+
(function () {
122+
var isProduction = document.currentScript.getAttribute('data-production') === 'true';
123+
if (!isProduction) return;
124+
125+
function loadHelpScout() {
126+
if (window.__helpScoutLoaded) return;
127+
window.__helpScoutLoaded = true;
128+
129+
// Initialize Beacon stub
130+
window.Beacon =
131+
window.Beacon ||
132+
function (method, options, data) {
133+
window.Beacon.readyQueue = window.Beacon.readyQueue || [];
134+
window.Beacon.readyQueue.push({ method: method, options: options, data: data });
135+
};
136+
window.Beacon.readyQueue = [];
137+
138+
// Load HelpScout script
139+
var script = document.createElement('script');
140+
script.type = 'text/javascript';
141+
script.async = true;
142+
script.src = 'https://beacon-v2.helpscout.net';
143+
script.onload = function () {
144+
window.Beacon('init', '57a7245e-772c-4d51-bdb1-6b898f34f2cb');
145+
};
146+
document.body.appendChild(script);
147+
}
148+
149+
// Load HelpScout on first user interaction or after 5s
150+
var events = ['mousemove', 'touchstart', 'scroll', 'keydown'];
151+
var loaded = false;
152+
153+
function onInteraction() {
154+
if (loaded) return;
155+
loaded = true;
156+
events.forEach(function (e) {
157+
document.removeEventListener(e, onInteraction);
158+
});
159+
loadHelpScout();
160+
}
161+
162+
events.forEach(function (e) {
163+
document.addEventListener(e, onInteraction, { once: true, passive: true });
164+
});
165+
166+
// Fallback: load after 5 seconds if no interaction
167+
setTimeout(function () {
168+
if (!loaded) {
169+
loaded = true;
170+
loadHelpScout();
171+
}
172+
}, 5000);
173+
})();
174+
</script>
175+
176+
{/* Marker.io - Load on idle for feedback collection */}
177+
<script is:inline data-production={import.meta.env.PROD ? 'true' : 'false'}>
178+
(function () {
179+
var isProduction = document.currentScript.getAttribute('data-production') === 'true';
180+
if (!isProduction) return;
181+
182+
function loadMarker() {
183+
var script = document.createElement('script');
184+
script.src = '/scripts/markerio.js';
185+
script.defer = true;
186+
document.body.appendChild(script);
187+
}
188+
if ('requestIdleCallback' in window) {
189+
requestIdleCallback(loadMarker, { timeout: 4000 });
190+
} else {
191+
setTimeout(loadMarker, 3000);
192+
}
193+
})();
194+
</script>

0 commit comments

Comments
 (0)