From d36d0d49d1c646d564b4aacdcb9b340cd8467d37 Mon Sep 17 00:00:00 2001 From: Etienne <45695613+etiennejouan@users.noreply.github.com> Date: Fri, 12 Dec 2025 18:39:01 +0100 Subject: [PATCH] Investigate - Slow transformRichTextV2 function (#16535) Investigate CPU overloading ... related to https://github.com/twentyhq/twenty/issues/15916 --- .../utils/transform-rich-text-v2.util.ts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/packages/twenty-server/src/engine/core-modules/record-transformer/utils/transform-rich-text-v2.util.ts b/packages/twenty-server/src/engine/core-modules/record-transformer/utils/transform-rich-text-v2.util.ts index 44825e0bcc..7d8bc4665d 100644 --- a/packages/twenty-server/src/engine/core-modules/record-transformer/utils/transform-rich-text-v2.util.ts +++ b/packages/twenty-server/src/engine/core-modules/record-transformer/utils/transform-rich-text-v2.util.ts @@ -1,3 +1,5 @@ +import { Logger } from '@nestjs/common'; + import { isNonEmptyString } from '@sniptt/guards'; import { type RichTextV2Metadata, @@ -5,14 +7,32 @@ import { } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; +const logger = new Logger('TransformRichTextV2'); + +const calculateInputSize = (input: unknown): number => { + if (typeof input === 'string') { + return Buffer.byteLength(input, 'utf8'); + } + if (typeof input === 'object' && input !== null) { + return Buffer.byteLength(JSON.stringify(input), 'utf8'); + } + + return 0; +}; + export const transformRichTextV2Value = async ( // eslint-disable-next-line @typescript-eslint/no-explicit-any richTextValue: any, ): Promise => { + const startTime = performance.now(); + const inputSize = calculateInputSize(richTextValue); + const parsedValue = isNonEmptyString(richTextValue) ? richTextV2ValueSchema.parse(richTextValue) : richTextValue; + const afterParsingTime = performance.now(); + const { ServerBlockNoteEditor } = await import('@blocknote/server-util'); const serverBlockNoteEditor = ServerBlockNoteEditor.create(); @@ -31,6 +51,8 @@ export const transformRichTextV2Value = async ( convertedMarkdown = parsedValue.blocknote || null; } + const afterMarkdownConversionTime = performance.now(); + const convertedBlocknote = parsedValue.markdown ? JSON.stringify( await serverBlockNoteEditor.tryParseMarkdownToBlocks( @@ -39,6 +61,12 @@ export const transformRichTextV2Value = async ( ) : null; + const endTime = performance.now(); + + logger.debug( + `transformRichTextV2Value completed - total: ${endTime - startTime}ms, parsing: ${afterParsingTime - startTime}ms, markdown_conversion: ${afterMarkdownConversionTime - afterParsingTime}ms, blocknote_conversion: ${endTime - afterMarkdownConversionTime}ms, size: ${inputSize} bytes`, + ); + return { markdown: parsedValue.markdown || convertedMarkdown, blocknote: parsedValue.blocknote || convertedBlocknote,