Files
oneuptime/Home/Views/head-basic.ejs
Nawaz Dhandala 83baa4d9c2 fix: Improve Core Web Vitals (LCP and CLS) for mobile and desktop
- Remove redundant Tailwind CDN from /docs pages (fixes CLS 0.21 → <0.1)
  The compiled CSS in style.css already contains all needed utilities;
  the CDN was re-processing styles causing layout shifts on 35 desktop URLs.

- Defer PostHog analytics via requestIdleCallback to unblock rendering
- Reduce Google Fonts to wght@400..800 (only weights actually used)
- Move meta charset/viewport to top of <head> for faster parsing
- Add defer to highlight.js on blog posts to unblock LCP
- Add DNS prefetch for PostHog domain

These changes target the 311 mobile URLs with LCP >2.5s and
35 desktop URLs with CLS >0.1 reported by Google Search Console.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 14:46:05 +00:00

286 lines
13 KiB
Plaintext

<!-- Critical meta tags MUST be first (within first 1024 bytes) -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover" />
<meta name="theme-color" content="#000000" />
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#000000" />
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1E293B" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- Resource hints - start fetching critical resources early -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<!-- Preconnect to external image/avatar domains to reduce layout shift & latency -->
<link rel="preconnect" href="https://avatars.githubusercontent.com" crossorigin>
<link rel="dns-prefetch" href="//avatars.githubusercontent.com">
<!-- DNS prefetch for deferred analytics -->
<link rel="dns-prefetch" href="//eu.posthog.com">
<!-- Preload Tailwind CDN to reduce FOUC/CLS -->
<link rel="preload" href="https://cdn.tailwindcss.com" as="script">
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Inter:wght@400..800&display=swap" as="style">
<!-- Google Fonts - only load weights actually used (400-800) -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400..800&display=swap"
rel="stylesheet">
<!-- Font and form element styles -->
<style>
* {
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
input[type="datetime-local"]::-webkit-calendar-picker-indicator {
background: transparent;
bottom: 0;
color: transparent;
cursor: pointer;
height: auto;
left: 0;
position: absolute;
right: 0;
top: 0;
width: auto;
appearance: none; /* standard */
-webkit-appearance: none; /* vendor */
}
input[type="date"]::-webkit-calendar-picker-indicator {
background: transparent;
bottom: 0;
color: transparent;
cursor: pointer;
height: auto;
left: 0;
position: absolute;
right: 0;
top: 0;
width: auto;
appearance: none;
-webkit-appearance: none;
}
/*Chrome*/
@media screen and (-webkit-min-device-pixel-ratio:0) {
input[type='range']::-webkit-slider-thumb {
width: 20px;
-webkit-appearance: none;
border-radius: 50%;
height: 20px;
cursor: pointer;
background: #4b5563;
}
}
/*Firefox*/
input[type='range']::-moz-range-thumb {
width: 16px;
-webkit-appearance: none;
border-radius: 50%;
height: 16px;
cursor: pointer;
background: #4b5563;
border-color: #4b5563;
}
</style>
<!-- Critical CSS to prevent layout shift before Tailwind loads -->
<style>
/* Critical layout styles to prevent CLS - these match Tailwind utility classes */
.bg-white { background-color: #fff; }
.relative { position: relative; }
.flex { display: flex; }
.hidden { display: none; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.justify-start { justify-content: flex-start; }
.justify-center { justify-content: center; }
.text-center { text-align: center; }
.mx-auto { margin-left: auto; margin-right: auto; }
.max-w-7xl { max-width: 80rem; }
.max-w-3xl { max-width: 48rem; }
.px-6 { padding-left: 1.5rem; padding-right: 1.5rem; }
.py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem; }
.py-12 { padding-top: 3rem; padding-bottom: 3rem; }
.py-24 { padding-top: 6rem; padding-bottom: 6rem; }
.border-b-2 { border-bottom-width: 2px; border-bottom-style: solid; }
.border-gray-100 { border-color: #f3f4f6; }
.overflow-hidden { overflow: hidden; }
.w-auto { width: auto; }
.h-8 { height: 2rem; }
.h-10 { height: 2.5rem; }
.space-x-10 > :not([hidden]) ~ :not([hidden]) { margin-left: 2.5rem; }
.inline-flex { display: inline-flex; }
.grid { display: grid; }
.gap-4 { gap: 1rem; }
.gap-5 { gap: 1.25rem; }
.isolate { isolation: isolate; }
.fixed { position: fixed; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; }
@media (min-width: 640px) {
.sm\:h-10 { height: 2.5rem; }
.sm\:py-16 { padding-top: 4rem; padding-bottom: 4rem; }
.sm\:grid-cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.sm\:gap-5 { gap: 1.25rem; }
}
@media (min-width: 768px) {
.md\:hidden { display: none; }
.md\:flex { display: flex; }
.md\:justify-start { justify-content: flex-start; }
.md\:space-x-10 > :not([hidden]) ~ :not([hidden]) { margin-left: 2.5rem; }
}
@media (min-width: 1024px) {
.lg\:w-0 { width: 0; }
.lg\:flex-1 { flex: 1 1 0%; }
.lg\:px-8 { padding-left: 2rem; padding-right: 2rem; }
.lg\:py-40 { padding-top: 10rem; padding-bottom: 10rem; }
}
.grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.auto-rows-fr { grid-auto-rows: minmax(0, 1fr); }
/* Reserve space for logo-roll section to prevent CLS */
.marquee-container { overflow: hidden; min-height: 60px; }
.logo-item { min-width: 160px; height: 60px; }
.logo-item img { max-height: 36px; max-width: 140px; }
</style>
<!-- Tailwind CSS (render-critical) -->
<script src="https://cdn.tailwindcss.com"></script>
<% if(typeof enableGoogleTagManager !== 'undefined' ? enableGoogleTagManager : false){ %>
<!-- Google Tag Manager -->
<script>(function (w, d, s, l, i) {
w[l] = w[l] || []; w[l].push({
'gtm.start':
new Date().getTime(), event: 'gtm.js'
}); var f = d.getElementsByTagName(s)[0],
j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : ''; j.async = true; j.src =
'https://www.googletagmanager.com/gtm.js?id=' + i + dl; f.parentNode.insertBefore(j, f);
})(window, document, 'script', 'dataLayer', 'GTM-PKQD5WH');</script>
<!-- End Google Tag Manager -->
<!-- GA4 gtag helper (works with GTM) -->
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
</script>
<% } %>
<!-- Deferred analytics - PostHog loads after page render to improve LCP -->
<script>
// PostHog stub - capture calls are queued until the library loads
window.posthog = window.posthog || [];
window.posthog._i = [];
window.posthog.init = window.posthog.init || function(){};
window.posthog.capture = window.posthog.capture || function(){window.posthog.push(['capture'].concat(Array.prototype.slice.call(arguments, 0)));};
// Defer PostHog initialization until after page render
(function() {
function initPostHog() {
!function (t, e) { var o, n, p, r; e.__SV || (window.posthog = e, e._i = [], e.init = function (i, s, a) { function g(t, e) { var o = e.split("."); 2 == o.length && (t = t[o[0]], e = o[1]), t[e] = function () { t.push([e].concat(Array.prototype.slice.call(arguments, 0))) } } (p = t.createElement("script")).type = "text/javascript", p.async = !0, p.src = s.api_host + "/static/array.js", (r = t.getElementsByTagName("script")[0]).parentNode.insertBefore(p, r); var u = e; for (void 0 !== a ? u = e[a] = [] : a = "posthog", u.people = u.people || [], u.toString = function (t) { var e = "posthog"; return "posthog" !== a && (e += "." + a), t || (e += " (stub)"), e }, u.people.toString = function () { return u.toString(1) + ".people (stub)" }, o = "capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys".split(" "), n = 0; n < o.length; n++)g(u, o[n]); e._i.push([i, s, a]) }, e.__SV = 1) }(document, window.posthog || []);
posthog.init('phc_lrbfSHsDc1YOhfbabPI8ncLCKz8eqeGdmu0O6IRKaz1', { api_host: 'https://eu.posthog.com', autocapture: false });
}
// Use requestIdleCallback to defer PostHog until browser is idle
if ('requestIdleCallback' in window) {
requestIdleCallback(initPostHog);
} else {
setTimeout(initPostHog, 1);
}
})();
</script>
<script>
document.addEventListener('DOMContentLoaded', function () {
// Track page view
if (typeof posthog !== 'undefined' && posthog && posthog.capture) {
posthog.capture('home/page_view', {
'page': {
'path': window.location.pathname,
'referrer': document.referrer,
'search': window.location.search,
'url': window.location.href,
'title': document.title,
}
});
}
// Track CTA clicks for conversion funnel analysis
document.querySelectorAll('a[href="/accounts/register"], a[href="/enterprise/demo"], a[href*="register"], a[href*="demo"]').forEach(function(link) {
link.addEventListener('click', function(e) {
var href = this.getAttribute('href');
var eventName = href.includes('register') ? 'cta_get_started' : 'cta_request_demo';
// PostHog
if (typeof posthog !== 'undefined' && posthog && posthog.capture) {
posthog.capture('home/' + eventName, {
'page': window.location.pathname,
'href': href,
'text': this.innerText.trim()
});
}
// GA4 via dataLayer
if (typeof dataLayer !== 'undefined') {
dataLayer.push({
'event': eventName,
'eventCategory': 'cta_click',
'eventAction': eventName,
'eventLabel': window.location.pathname
});
}
});
});
var urlParams = new URLSearchParams(window.location.search);
var utm_source = urlParams.get('utm_source');
var utm_medium = urlParams.get('utm_medium');
var utm_campaign = urlParams.get('utm_campaign');
var utm_term = urlParams.get('utm_term');
var utm_content = urlParams.get('utm_content');
var utm_url = window.location.href;
if (utm_source != null) {
localStorage.setItem('utmSource', utm_source);
localStorage.setItem('utmMedium', utm_medium);
localStorage.setItem('utmCampaign', utm_campaign);
localStorage.setItem('utmTerm', utm_term);
localStorage.setItem('utmContent', utm_content);
localStorage.setItem('utmUrl', utm_url);
if (typeof posthog !== 'undefined' && posthog && posthog.capture) {
posthog.capture('home/utm_event', {
utm_source: utm_source,
utm_medium: utm_medium,
utm_campaign: utm_campaign,
utm_term: utm_term,
utm_content: utm_content,
utm_url: utm_url
})
}
}
});
</script>
<!-- PWA Meta Tags -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="apple-mobile-web-app-title" content="OneUptime">
<meta name="mobile-web-app-capable" content="yes">
<meta name="application-name" content="OneUptime">
<!-- Icons -->
<link rel="shortcut icon" href="/img/favicons/favicon.ico">
<link rel="apple-touch-icon" sizes="180x180" href="/img/favicons/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicons/favicon-16x16.png">
<link rel="mask-icon" href="/img/favicons/safari-pinned-tab.svg" color="#000000">
<!-- Microsoft Tiles -->
<meta name="msapplication-TileColor" content="#000000">
<meta name="msapplication-TileImage" content="/img/favicons/mstile-144x144.png">
<!-- Legacy and compatibility -->
<link rel="apple-touch-icon-precomposed" href="/img/ou-wb.svg">
<link rel="icon" href="/img/ou-wb.svg">
<link rel="image_src" type="image/png" href="/img/hou-wb.svg">
<!-- Canonical URL -->
<% const canonicalUrl = (typeof seo !== 'undefined' && seo.fullCanonicalUrl) ? seo.fullCanonicalUrl : (typeof homeUrl !== 'undefined' ? homeUrl : 'https://oneuptime.com'); %>
<link rel="canonical" href="<%= canonicalUrl %>">