From efd60a7ccb52b7d33f4d10d701691c6f389eb3f1 Mon Sep 17 00:00:00 2001 From: Allo Date: Tue, 9 May 2023 10:48:31 +0800 Subject: [PATCH 1/2] fix(content): only collect needed translations Gather all translation would slow down the static document build in translated-content. Only gather the translations of the incoming slug might be a better idea. --- build/cli.ts | 14 +++---- content/translations.ts | 87 ++++++++++++++++------------------------- server/index.ts | 9 +++-- 3 files changed, 46 insertions(+), 64 deletions(-) diff --git a/build/cli.ts b/build/cli.ts index ca58317ce16c..18ab303cba31 100644 --- a/build/cli.ts +++ b/build/cli.ts @@ -51,8 +51,8 @@ interface GlobalMetadata { } async function buildDocumentInteractive( - documentPath, - interactive, + documentPath: string, + interactive: boolean, invalidate = false ): Promise { try { @@ -65,12 +65,10 @@ async function buildDocumentInteractive( } if (!interactive) { - const translations = await translationsOf(document.metadata); - if (translations && translations.length > 0) { - document.translations = translations; - } else { - document.translations = []; - } + document.translations = translationsOf( + document.metadata.slug, + document.metadata.locale + ); } return { document, doc: await buildDocument(document), skip: false }; diff --git a/content/translations.ts b/content/translations.ts index b9f46569da32..080da38fdbc9 100644 --- a/content/translations.ts +++ b/content/translations.ts @@ -8,70 +8,51 @@ const LANGUAGES = new Map( }) ); -const TRANSLATIONS_OF = new Map(); +type Translation = { + locale: string; + title: string; + native: string; +}; -async function gatherTranslations() { - const iter = (await Document.findAll()).iterDocs(); - for (const { - metadata: { slug, locale, title }, - } of iter) { - if (!slug || !locale || !title) { - continue; - } - const translation = { - title, - locale, - native: LANGUAGES.get(locale.toLowerCase()).native, - }; - const translations = TRANSLATIONS_OF.get(slug.toLowerCase()); - if (translations) { - translations.push(translation); - translations.sort(({ locale: a }, { locale: b }) => { - if (a < b) return -1; - if (a > b) return 1; - return 0; - }); - } else { - TRANSLATIONS_OF.set(slug.toLowerCase(), [translation]); - } - } -} +const TRANSLATIONS_OF = new Map>(); -export async function translationsOf({ slug, locale: currentLocale }) { - if (TRANSLATIONS_OF.size === 0) { - const label = "Time to gather all translations"; - console.time(label); - await gatherTranslations(); - console.timeEnd(label); - } - const translations = TRANSLATIONS_OF.get(slug.toLowerCase()); - if (translations && currentLocale) { - return translations.filter( - ({ locale }) => locale.toLowerCase() !== currentLocale.toLowerCase() - ); - } - return translations; -} - -export function findDocumentTranslations(document) { +// return all translations of a document +export function findTranslations( + slug: string, + currentLocale: string = null +): Array { const translations = []; - for (const locale of VALID_LOCALES.values()) { - if (document.metadata.locale === locale) { + if (currentLocale?.toLowerCase() === locale.toLowerCase()) { continue; } - const translatedDocumentURL = document.url.replace( - `/${document.metadata.locale}/`, - `/${locale}/` - ); - const translatedDocument = Document.findByURL(translatedDocumentURL); - if (translatedDocument) { + const documentURL = `/${locale}/docs/${slug}`; + const document = Document.findByURL(documentURL); + if (document) { translations.push({ locale, - title: translatedDocument.metadata.title, + title: document.metadata.title, native: LANGUAGES.get(locale.toLowerCase()).native, }); } } return translations; } + +// gather and cache all translations of a document, +// then return all translations except the current locale +export function translationsOf( + slug: string, + currentLocale: string +): Array { + let documents = TRANSLATIONS_OF.get(slug.toLowerCase()); + if (!documents) { + documents = findTranslations(slug); + TRANSLATIONS_OF.set(slug.toLowerCase(), documents); + } + return ( + documents.filter( + ({ locale }) => locale.toLowerCase() !== currentLocale.toLowerCase() + ) ?? [] + ); +} diff --git a/server/index.ts b/server/index.ts index 5f6f4df14783..2751bd9f4f1c 100644 --- a/server/index.ts +++ b/server/index.ts @@ -16,7 +16,7 @@ import { buildLiveSamplePageFromURL, renderContributorsTxt, } from "../build/index.js"; -import { findDocumentTranslations } from "../content/translations.js"; +import { findTranslations } from "../content/translations.js"; import { Document, Redirect, Image } from "../content/index.js"; import { CSP_VALUE, DEFAULT_LOCALE } from "../libs/constants/index.js"; import { @@ -47,7 +47,7 @@ import { findPostPathBySlug, } from "../build/blog.js"; -async function buildDocumentFromURL(url) { +async function buildDocumentFromURL(url: string) { const document = Document.findByURL(url); if (!document) { return null; @@ -57,7 +57,10 @@ async function buildDocumentFromURL(url) { // When you're running the dev server and build documents // every time a URL is requested, you won't have had the chance to do // the phase that happens when you do a regular `yarn build`. - document.translations = findDocumentTranslations(document); + document.translations = findTranslations( + document.metadata.slug, + document.metadata.locale + ); } return await buildDocument(document, documentOptions); } From 565e8d2a5a5ed7c24a88bd97a5c605c4534b58eb Mon Sep 17 00:00:00 2001 From: Allo Date: Fri, 19 May 2023 19:08:03 +0800 Subject: [PATCH 2/2] apply suggestions from code review Co-authored-by: Leo McArdle --- content/translations.ts | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/content/translations.ts b/content/translations.ts index 080da38fdbc9..3b06a4c59f23 100644 --- a/content/translations.ts +++ b/content/translations.ts @@ -16,11 +16,27 @@ type Translation = { const TRANSLATIONS_OF = new Map>(); +// gather and cache all translations of a document, +// then return all translations except the current locale +export function translationsOf( + slug: string, + currentLocale: string +): Translation[] { + let translations = TRANSLATIONS_OF.get(slug.toLowerCase()); + if (!translations) { + translations = findTranslations(slug); + TRANSLATIONS_OF.set(slug.toLowerCase(), translations); + } + return translations.filter( + ({ locale }) => locale.toLowerCase() !== currentLocale.toLowerCase() + ); +} + // return all translations of a document export function findTranslations( slug: string, currentLocale: string = null -): Array { +): Translation[] { const translations = []; for (const locale of VALID_LOCALES.values()) { if (currentLocale?.toLowerCase() === locale.toLowerCase()) { @@ -38,21 +54,3 @@ export function findTranslations( } return translations; } - -// gather and cache all translations of a document, -// then return all translations except the current locale -export function translationsOf( - slug: string, - currentLocale: string -): Array { - let documents = TRANSLATIONS_OF.get(slug.toLowerCase()); - if (!documents) { - documents = findTranslations(slug); - TRANSLATIONS_OF.set(slug.toLowerCase(), documents); - } - return ( - documents.filter( - ({ locale }) => locale.toLowerCase() !== currentLocale.toLowerCase() - ) ?? [] - ); -}