From e6787f8d606ea0a53a1a579354c29a65b42eab4b Mon Sep 17 00:00:00 2001 From: Andrea Vos Date: Sun, 23 Feb 2025 14:46:57 +0100 Subject: [PATCH 1/6] (perf) start using speculationrules API --- layouts/default.vue | 6 +++--- plugins/speculationrules.ts | 24 ++++++++++++++++++++++++ plugins/track.client.ts | 27 ++++++++++++++++----------- server/express/profile.ts | 10 +++++----- src/helpers.ts | 10 ++++++++++ 5 files changed, 58 insertions(+), 19 deletions(-) create mode 100644 plugins/speculationrules.ts diff --git a/layouts/default.vue b/layouts/default.vue index bef3db66e..be1f04cb8 100644 --- a/layouts/default.vue +++ b/layouts/default.vue @@ -8,7 +8,7 @@ import useDark from '~/composables/useDark.ts'; import useDialogue from '~/composables/useDialogue.ts'; import { longtimeCookieSetting } from '~/src/cookieSettings.ts'; import { LoadScriptError } from '~/src/errors.ts'; -import { newDate } from '~/src/helpers.ts'; +import { executeUnlessPrerendering, newDate } from '~/src/helpers.ts'; import { useMainStore } from '~/store/index.ts'; // no need to be super secure, just a sign that the page is not public @@ -42,7 +42,7 @@ const checkTesterPassword = (): void => { testerPasswordCookie.value = testerPassword.value; }; -onMounted(() => { +onMounted(executeUnlessPrerendering(() => { sorter(); confirmAge(); @@ -67,7 +67,7 @@ onMounted(() => { window.location.reload(); } }; -}); +})); const dialogue = useDialogue(); const confirmAge = async (): Promise => { diff --git a/plugins/speculationrules.ts b/plugins/speculationrules.ts new file mode 100644 index 000000000..86774a445 --- /dev/null +++ b/plugins/speculationrules.ts @@ -0,0 +1,24 @@ +export default defineNuxtPlugin(() => { + useHead({ + script: [ + { + type: 'speculationrules', + innerHTML: ` +{ + "prerender": [ + { + "where": { + "and": [ + { "href_matches": "/*" }, + { "not": { "selector_matches": ".no-prerender" } }, + { "not": { "selector_matches": "[rel~=nofollow]" } } + ] + } + } + ], + "eagerness": "moderate", +}`, + }, + ], + }); +}); diff --git a/plugins/track.client.ts b/plugins/track.client.ts index d259a7574..748eee328 100644 --- a/plugins/track.client.ts +++ b/plugins/track.client.ts @@ -2,6 +2,8 @@ import * as Sentry from '@sentry/vue'; import { defineNuxtPlugin, useRouter } from 'nuxt/app'; import type { RouteLocationNormalized } from 'vue-router'; +import { executeUnlessPrerendering } from '~/src/helpers.ts'; + const USER_AT = /^\/@.+/; const USER_SUBPAGE = /^\/(u|card)\/.*/; @@ -21,17 +23,20 @@ export default defineNuxtPlugin((nuxtApp) => { const router = useRouter(); const trackPageview = (route: RouteLocationNormalized): void => { - try { - const toUrl = normalizeUrl(new URL(route.fullPath, window.location.href)); - console.debug('[analytics] tracking page view:', toUrl.toString()); - useTrackPageview({ - data: { - url: toUrl.toString(), - }, - }); - } catch (error) { - Sentry.captureException(error); - } + executeUnlessPrerendering(() => { + console.log('tracking:', route.fullPath); + try { + const toUrl = normalizeUrl(new URL(route.fullPath, window.location.href)); + console.debug('[analytics] tracking page view:', toUrl.toString()); + useTrackPageview({ + data: { + url: toUrl.toString(), + }, + }); + } catch (error) { + Sentry.captureException(error); + } + })(); }; // Track the initial page load diff --git a/server/express/profile.ts b/server/express/profile.ts index 0fe84de4c..d75a9a140 100644 --- a/server/express/profile.ts +++ b/server/express/profile.ts @@ -632,9 +632,9 @@ const cleanupOpinions = (opinions: OpinionFormValue[]) => { }; type SaveProfile = Omit - & Partial> - & Pick; +'card' | 'cardDark' | 'circle' | 'markdown' | 'events' | 'customEvents' | 'lastUpdate' | 'id' | 'access'> +& Partial> +& Pick; const saveProfile = async (req: Request, locale: string, { opinions, names, pronouns, description, birthday, timezone, links, flags, customFlags, words, sensitive, @@ -1036,8 +1036,8 @@ interface ProfileExportData { } type ProfileExportProfile = Omit - & Pick; +'card' | 'cardDark' | 'circle' | 'lastUpdate' | 'id' | 'access'> +& Pick; router.get('/profile/export', handleErrorAsync(async (req: Request, res: Response) => { if (!req.user || req.user.bannedReason) { diff --git a/src/helpers.ts b/src/helpers.ts index 792598ac8..de04327f1 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -562,3 +562,13 @@ export const filterObjectKeys = , K extends keyof return filteredObj; }, {} as Pick); }; + +export const executeUnlessPrerendering = (fn: () => void): (() => void) => { + return () => { + if ((document as any).prerendering) { + document.addEventListener('prerenderingchange', fn, { once: true }); + } else { + fn(); + } + }; +}; From 27820c822b3650115fda94aa585bd5c22bafca16 Mon Sep 17 00:00:00 2001 From: Andrea Vos Date: Sun, 23 Feb 2025 14:57:36 +0100 Subject: [PATCH 2/6] revert weird lint behaviour --- server/express/profile.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/express/profile.ts b/server/express/profile.ts index d75a9a140..0fe84de4c 100644 --- a/server/express/profile.ts +++ b/server/express/profile.ts @@ -632,9 +632,9 @@ const cleanupOpinions = (opinions: OpinionFormValue[]) => { }; type SaveProfile = Omit -& Partial> -& Pick; + 'card' | 'cardDark' | 'circle' | 'markdown' | 'events' | 'customEvents' | 'lastUpdate' | 'id' | 'access'> + & Partial> + & Pick; const saveProfile = async (req: Request, locale: string, { opinions, names, pronouns, description, birthday, timezone, links, flags, customFlags, words, sensitive, @@ -1036,8 +1036,8 @@ interface ProfileExportData { } type ProfileExportProfile = Omit -& Pick; + 'card' | 'cardDark' | 'circle' | 'lastUpdate' | 'id' | 'access'> + & Pick; router.get('/profile/export', handleErrorAsync(async (req: Request, res: Response) => { if (!req.user || req.user.bannedReason) { From f15c7fe0307e1b50d1fed835788e77bede01ec62 Mon Sep 17 00:00:00 2001 From: Andrea Vos Date: Sun, 23 Feb 2025 15:06:05 +0100 Subject: [PATCH 3/6] =?UTF-8?q?oh=20json=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/speculationrules.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/speculationrules.ts b/plugins/speculationrules.ts index 86774a445..c90c11dc7 100644 --- a/plugins/speculationrules.ts +++ b/plugins/speculationrules.ts @@ -16,7 +16,7 @@ export default defineNuxtPlugin(() => { } } ], - "eagerness": "moderate", + "eagerness": "moderate" }`, }, ], From 82e9bb0087933d689e346c4522268c6b1ca458bd Mon Sep 17 00:00:00 2001 From: Andrea Vos Date: Sun, 23 Feb 2025 15:24:53 +0100 Subject: [PATCH 4/6] miscommit --- plugins/track.client.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/track.client.ts b/plugins/track.client.ts index 748eee328..cf1b44781 100644 --- a/plugins/track.client.ts +++ b/plugins/track.client.ts @@ -24,7 +24,6 @@ export default defineNuxtPlugin((nuxtApp) => { const trackPageview = (route: RouteLocationNormalized): void => { executeUnlessPrerendering(() => { - console.log('tracking:', route.fullPath); try { const toUrl = normalizeUrl(new URL(route.fullPath, window.location.href)); console.debug('[analytics] tracking page view:', toUrl.toString()); From 54eb35f45c7116ef59da6f91199060564dd712bb Mon Sep 17 00:00:00 2001 From: Andrea Vos Date: Sun, 23 Feb 2025 16:04:15 +0100 Subject: [PATCH 5/6] =?UTF-8?q?speculationrules=20=E2=80=93=20js=20object?= =?UTF-8?q?=20instead=20of=20json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/speculationrules.ts | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/plugins/speculationrules.ts b/plugins/speculationrules.ts index c90c11dc7..d81239b9c 100644 --- a/plugins/speculationrules.ts +++ b/plugins/speculationrules.ts @@ -3,21 +3,20 @@ export default defineNuxtPlugin(() => { script: [ { type: 'speculationrules', - innerHTML: ` -{ - "prerender": [ - { - "where": { - "and": [ - { "href_matches": "/*" }, - { "not": { "selector_matches": ".no-prerender" } }, - { "not": { "selector_matches": "[rel~=nofollow]" } } - ] - } - } - ], - "eagerness": "moderate" -}`, + innerHTML: JSON.stringify({ + prerender: [ + { + where: { + and: [ + { href_matches: "/*" }, + { not: { selector_matches: ".no-prerender" } }, + { not: { selector_matches: "[rel~=nofollow]" } } + ] + } + } + ], + eagerness: "moderate", + }), }, ], }); From b0c7082bbe2712b8eb087904abd7f45ce1feb854 Mon Sep 17 00:00:00 2001 From: Andrea Vos Date: Sun, 23 Feb 2025 16:26:55 +0100 Subject: [PATCH 6/6] lint --- plugins/speculationrules.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/speculationrules.ts b/plugins/speculationrules.ts index d81239b9c..827fc7a48 100644 --- a/plugins/speculationrules.ts +++ b/plugins/speculationrules.ts @@ -8,14 +8,14 @@ export default defineNuxtPlugin(() => { { where: { and: [ - { href_matches: "/*" }, - { not: { selector_matches: ".no-prerender" } }, - { not: { selector_matches: "[rel~=nofollow]" } } - ] - } - } + { href_matches: '/*' }, + { not: { selector_matches: '.no-prerender' } }, + { not: { selector_matches: '[rel~=nofollow]' } }, + ], + }, + }, ], - eagerness: "moderate", + eagerness: 'moderate', }), }, ],