diff --git a/packages/compiler-sfc/src/parse.ts b/packages/compiler-sfc/src/parse.ts
index 32c26d3acac..c8be865508f 100644
--- a/packages/compiler-sfc/src/parse.ts
+++ b/packages/compiler-sfc/src/parse.ts
@@ -18,6 +18,7 @@ import { createCache } from './cache'
 import type { ImportBinding } from './compileScript'
 import { isImportUsed } from './script/importUsageCheck'
 import type { LRUCache } from 'lru-cache'
+import { genCacheKey } from '@vue/shared'
 
 export const DEFAULT_FILENAME = 'anonymous.vue'
 
@@ -103,24 +104,14 @@ export const parseCache:
   | Map<string, SFCParseResult>
   | LRUCache<string, SFCParseResult> = createCache<SFCParseResult>()
 
-function genCacheKey(source: string, options: SFCParseOptions): string {
-  return (
-    source +
-    JSON.stringify(
-      {
-        ...options,
-        compiler: { parse: options.compiler?.parse },
-      },
-      (_, val) => (typeof val === 'function' ? val.toString() : val),
-    )
-  )
-}
-
 export function parse(
   source: string,
   options: SFCParseOptions = {},
 ): SFCParseResult {
-  const sourceKey = genCacheKey(source, options)
+  const sourceKey = genCacheKey(source, {
+    ...options,
+    compiler: { parse: options.compiler?.parse },
+  })
   const cache = parseCache.get(sourceKey)
   if (cache) {
     return cache
diff --git a/packages/shared/src/general.ts b/packages/shared/src/general.ts
index 552b447064c..9c6a2313240 100644
--- a/packages/shared/src/general.ts
+++ b/packages/shared/src/general.ts
@@ -208,3 +208,12 @@ export function genPropsAccessExp(name: string): string {
     ? `__props.${name}`
     : `__props[${JSON.stringify(name)}]`
 }
+
+export function genCacheKey(source: string, options: any): string {
+  return (
+    source +
+    JSON.stringify(options, (_, val) =>
+      typeof val === 'function' ? val.toString() : val,
+    )
+  )
+}
diff --git a/packages/vue-compat/src/index.ts b/packages/vue-compat/src/index.ts
index 639ccfd94c6..d7e9695d824 100644
--- a/packages/vue-compat/src/index.ts
+++ b/packages/vue-compat/src/index.ts
@@ -12,7 +12,13 @@ import {
   registerRuntimeCompiler,
   warn,
 } from '@vue/runtime-dom'
-import { NOOP, extend, generateCodeFrame, isString } from '@vue/shared'
+import {
+  NOOP,
+  extend,
+  genCacheKey,
+  generateCodeFrame,
+  isString,
+} from '@vue/shared'
 import type { InternalRenderFunction } from 'packages/runtime-core/src/component'
 import * as runtimeDom from '@vue/runtime-dom'
 import {
@@ -35,7 +41,7 @@ function compileToFunction(
     }
   }
 
-  const key = template
+  const key = genCacheKey(template, options)
   const cached = compileCache[key]
   if (cached) {
     return cached
diff --git a/packages/vue/src/index.ts b/packages/vue/src/index.ts
index 35077b3cf63..785f3fd4bb4 100644
--- a/packages/vue/src/index.ts
+++ b/packages/vue/src/index.ts
@@ -13,9 +13,9 @@ import {
 } from '@vue/runtime-dom'
 import * as runtimeDom from '@vue/runtime-dom'
 import {
-  EMPTY_OBJ,
   NOOP,
   extend,
+  genCacheKey,
   generateCodeFrame,
   isString,
 } from '@vue/shared'
@@ -25,19 +25,7 @@ if (__DEV__) {
   initDev()
 }
 
-const compileCache = new WeakMap<
-  CompilerOptions,
-  Record<string, RenderFunction>
->()
-
-function getCache(options?: CompilerOptions) {
-  let c = compileCache.get(options ?? EMPTY_OBJ)
-  if (!c) {
-    c = Object.create(null) as Record<string, RenderFunction>
-    compileCache.set(options ?? EMPTY_OBJ, c)
-  }
-  return c
-}
+const compileCache: Record<string, RenderFunction> = Object.create(null)
 
 function compileToFunction(
   template: string | HTMLElement,
@@ -52,9 +40,8 @@ function compileToFunction(
     }
   }
 
-  const key = template
-  const cache = getCache(options)
-  const cached = cache[key]
+  const key = genCacheKey(template, options)
+  const cached = compileCache[key]
   if (cached) {
     return cached
   }
@@ -111,7 +98,7 @@ function compileToFunction(
   // mark the function as runtime compiled
   ;(render as InternalRenderFunction)._rc = true
 
-  return (cache[key] = render)
+  return (compileCache[key] = render)
 }
 
 registerRuntimeCompiler(compileToFunction)