From 2184240ef146742a61ee12d5536922278b486d29 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Tue, 3 Jan 2023 10:12:37 +0900
Subject: [PATCH] perf(client): use shallowRef for html element ref

---
 packages/frontend/src/components/MkAutocomplete.vue    | 10 +++++-----
 packages/frontend/src/components/MkButton.vue          |  4 ++--
 packages/frontend/src/components/MkCaptcha.vue         |  6 +++---
 packages/frontend/src/components/MkChart.vue           |  4 ++--
 packages/frontend/src/components/MkContextMenu.vue     |  2 +-
 packages/frontend/src/components/MkCropperDialog.vue   |  2 +-
 packages/frontend/src/components/MkDrive.vue           |  4 ++--
 packages/frontend/src/components/MkEmojiPicker.vue     |  6 +++---
 packages/frontend/src/components/MkHeatmap.vue         |  4 ++--
 packages/frontend/src/components/MkImgWithBlurhash.vue |  2 +-
 packages/frontend/src/components/MkInstanceStats.vue   |  4 ++--
 packages/frontend/src/components/MkMediaBanner.vue     |  2 +-
 packages/frontend/src/components/MkMenu.child.vue      |  4 ++--
 packages/frontend/src/components/MkMenu.vue            |  4 ++--
 packages/frontend/src/components/MkModal.vue           |  2 +-
 packages/frontend/src/components/MkModalWindow.vue     |  4 ++--
 packages/frontend/src/components/MkNote.vue            | 10 +++++-----
 packages/frontend/src/components/MkNoteDetailed.vue    | 10 +++++-----
 packages/frontend/src/components/MkNotification.vue    |  4 ++--
 packages/frontend/src/components/MkPagination.vue      |  4 ++--
 packages/frontend/src/components/MkPostForm.vue        |  8 ++++----
 .../src/components/MkReactionsViewer.reaction.vue      |  4 ++--
 packages/frontend/src/components/MkRenoteButton.vue    |  4 ++--
 .../frontend/src/components/MkRetentionHeatmap.vue     |  4 ++--
 packages/frontend/src/components/MkSparkle.vue         |  4 ++--
 packages/frontend/src/components/MkTagCloud.vue        |  6 +++---
 packages/frontend/src/components/MkTooltip.vue         |  4 ++--
 packages/frontend/src/components/MkVisibility.vue      |  2 +-
 packages/frontend/src/components/MkWindow.vue          |  2 +-
 packages/frontend/src/components/form/checkbox.vue     |  2 +-
 packages/frontend/src/components/form/folder.vue       |  2 +-
 packages/frontend/src/components/form/input.vue        |  8 ++++----
 packages/frontend/src/components/form/switch.vue       |  2 +-
 .../frontend/src/components/global/MkPageHeader.vue    |  4 ++--
 packages/frontend/src/components/global/MkSpacer.vue   |  5 ++---
 .../src/components/global/MkStickyContainer.vue        |  6 +++---
 packages/frontend/src/pages/about-misskey.vue          |  2 +-
 packages/frontend/src/pages/admin/_header_.vue         |  6 +++---
 .../frontend/src/pages/admin/overview.active-users.vue |  2 +-
 .../frontend/src/pages/admin/overview.ap-requests.vue  |  4 ++--
 packages/frontend/src/pages/admin/overview.pie.vue     |  4 ++--
 .../frontend/src/pages/admin/overview.queue.chart.vue  |  4 ++--
 packages/frontend/src/pages/admin/overview.vue         |  2 +-
 .../frontend/src/pages/admin/queue.chart.chart.vue     |  4 ++--
 packages/frontend/src/pages/antenna-timeline.vue       |  2 +-
 .../src/pages/messaging/messaging-room.form.vue        |  4 ++--
 .../frontend/src/pages/messaging/messaging-room.vue    |  2 +-
 packages/frontend/src/pages/settings/index.vue         |  4 ++--
 packages/frontend/src/pages/timeline.vue               |  2 +-
 packages/frontend/src/pages/user-list-timeline.vue     |  2 +-
 packages/frontend/src/pages/user/activity.heatmap.vue  |  4 ++--
 packages/frontend/src/pages/user/activity.pv.vue       |  2 +-
 packages/frontend/src/ui/classic.vue                   |  2 +-
 packages/frontend/src/ui/deck.vue                      |  2 +-
 packages/frontend/src/ui/deck/column.vue               |  2 +-
 packages/frontend/src/ui/universal.vue                 |  2 +-
 packages/frontend/src/ui/universal.widgets.vue         |  2 +-
 packages/frontend/src/widgets/aichan.vue               |  4 ++--
 packages/frontend/src/widgets/slideshow.vue            |  6 +++---
 59 files changed, 114 insertions(+), 115 deletions(-)

diff --git a/packages/frontend/src/components/MkAutocomplete.vue b/packages/frontend/src/components/MkAutocomplete.vue
index a2b020b900..08e2c29de2 100644
--- a/packages/frontend/src/components/MkAutocomplete.vue
+++ b/packages/frontend/src/components/MkAutocomplete.vue
@@ -16,9 +16,9 @@
 		</li>
 	</ol>
 	<ol v-else-if="emojis.length > 0" ref="suggests" class="emojis">
-		<li v-for="emoji in emojis" tabindex="-1" :key="emoji.emoji" @click="complete(type, emoji.emoji)" @keydown="onKeydown">
+		<li v-for="emoji in emojis" :key="emoji.emoji" tabindex="-1" @click="complete(type, emoji.emoji)" @keydown="onKeydown">
 			<div class="emoji">
-				<MkEmoji :emoji="emoji.emoji" />
+				<MkEmoji :emoji="emoji.emoji"/>
 			</div>
 			<!-- eslint-disable-next-line vue/no-v-html -->
 			<span v-if="q" class="name" v-html="sanitizeHtml(emoji.name.replace(q, `<b>${q}</b>`))"></span>
@@ -35,7 +35,8 @@
 </template>
 
 <script lang="ts">
-import { markRaw, ref, onUpdated, onMounted, onBeforeUnmount, nextTick, watch } from 'vue';
+import { markRaw, ref, shallowRef, onUpdated, onMounted, onBeforeUnmount, nextTick, watch } from 'vue';
+import sanitizeHtml from 'sanitize-html';
 import contains from '@/scripts/contains';
 import { char2twemojiFilePath, char2fluentEmojiFilePath } from '@/scripts/emoji-base';
 import { acct } from '@/filters/user';
@@ -45,7 +46,6 @@ import { defaultStore } from '@/store';
 import { emojilist } from '@/scripts/emojilist';
 import { instance } from '@/instance';
 import { i18n } from '@/i18n';
-import sanitizeHtml from 'sanitize-html';
 
 type EmojiDef = {
 	emoji: string;
@@ -136,7 +136,7 @@ const emit = defineEmits<{
 }>();
 
 const suggests = ref<Element>();
-const rootEl = ref<HTMLDivElement>();
+const rootEl = shallowRef<HTMLDivElement>();
 
 const fetching = ref(true);
 const users = ref<any[]>([]);
diff --git a/packages/frontend/src/components/MkButton.vue b/packages/frontend/src/components/MkButton.vue
index 2b1b66da29..daf47e12d4 100644
--- a/packages/frontend/src/components/MkButton.vue
+++ b/packages/frontend/src/components/MkButton.vue
@@ -47,8 +47,8 @@ const emit = defineEmits<{
 	(ev: 'click', payload: MouseEvent): void;
 }>();
 
-let el = $ref<HTMLElement | null>(null);
-let ripples = $ref<HTMLElement | null>(null);
+let el = $shallowRef<HTMLElement | null>(null);
+let ripples = $shallowRef<HTMLElement | null>(null);
 
 onMounted(() => {
 	if (props.autofocus) {
diff --git a/packages/frontend/src/components/MkCaptcha.vue b/packages/frontend/src/components/MkCaptcha.vue
index 6d218389fc..8db2e54e88 100644
--- a/packages/frontend/src/components/MkCaptcha.vue
+++ b/packages/frontend/src/components/MkCaptcha.vue
@@ -6,7 +6,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed, onMounted, onBeforeUnmount, watch } from 'vue';
+import { ref, shallowRef, computed, onMounted, onBeforeUnmount, watch } from 'vue';
 import { defaultStore } from '@/store';
 import { i18n } from '@/i18n';
 
@@ -42,7 +42,7 @@ const emit = defineEmits<{
 
 const available = ref(false);
 
-const captchaEl = ref<HTMLDivElement | undefined>();
+const captchaEl = shallowRef<HTMLDivElement | undefined>();
 
 const variable = computed(() => {
 	switch (props.provider) {
@@ -62,7 +62,7 @@ const src = computed(() => {
 	}
 });
 
-const scriptId = computed(() => `script-${props.provider}`)
+const scriptId = computed(() => `script-${props.provider}`);
 
 const captcha = computed<Captcha>(() => window[variable.value] || {} as unknown as Captcha);
 
diff --git a/packages/frontend/src/components/MkChart.vue b/packages/frontend/src/components/MkChart.vue
index d602849651..7d3a3d289b 100644
--- a/packages/frontend/src/components/MkChart.vue
+++ b/packages/frontend/src/components/MkChart.vue
@@ -13,7 +13,7 @@
   id-denylist violation when setting it. This is causing about 60+ lint issues.
   As this is part of Chart.js's API it makes sense to disable the check here.
 */
-import { onMounted, ref, watch, PropType, onUnmounted } from 'vue';
+import { onMounted, ref, shallowRef, watch, PropType, onUnmounted } from 'vue';
 import { Chart } from 'chart.js';
 import 'chartjs-adapter-date-fns';
 import { enUS } from 'date-fns/locale';
@@ -102,7 +102,7 @@ let chartData: {
 	}[];
 } = null;
 
-const chartEl = ref<HTMLCanvasElement>(null);
+const chartEl = shallowRef<HTMLCanvasElement>(null);
 const fetching = ref(true);
 
 const getDate = (ago: number) => {
diff --git a/packages/frontend/src/components/MkContextMenu.vue b/packages/frontend/src/components/MkContextMenu.vue
index 6470f8b972..9d9abc5d09 100644
--- a/packages/frontend/src/components/MkContextMenu.vue
+++ b/packages/frontend/src/components/MkContextMenu.vue
@@ -22,7 +22,7 @@ const emit = defineEmits<{
 	(ev: 'closed'): void;
 }>();
 
-let rootEl = $ref<HTMLDivElement>();
+let rootEl = $shallowRef<HTMLDivElement>();
 
 let zIndex = $ref<number>(os.claimZIndex('high'));
 
diff --git a/packages/frontend/src/components/MkCropperDialog.vue b/packages/frontend/src/components/MkCropperDialog.vue
index ae18160dea..3ff73d6669 100644
--- a/packages/frontend/src/components/MkCropperDialog.vue
+++ b/packages/frontend/src/components/MkCropperDialog.vue
@@ -51,7 +51,7 @@ const props = defineProps<{
 
 const imgUrl = getProxiedImageUrl(props.file.url);
 let dialogEl = $ref<InstanceType<typeof XModalWindow>>();
-let imgEl = $ref<HTMLImageElement>();
+let imgEl = $shallowRef<HTMLImageElement>();
 let cropper: Cropper | null = null;
 let loading = $ref(true);
 
diff --git a/packages/frontend/src/components/MkDrive.vue b/packages/frontend/src/components/MkDrive.vue
index 4053870950..843c5f1c54 100644
--- a/packages/frontend/src/components/MkDrive.vue
+++ b/packages/frontend/src/components/MkDrive.vue
@@ -88,7 +88,7 @@
 </template>
 
 <script lang="ts" setup>
-import { markRaw, nextTick, onActivated, onBeforeUnmount, onMounted, ref, watch } from 'vue';
+import { markRaw, nextTick, onActivated, onBeforeUnmount, onMounted, ref, shallowRef, watch } from 'vue';
 import * as Misskey from 'misskey-js';
 import MkButton from './MkButton.vue';
 import XNavFolder from '@/components/MkDrive.navFolder.vue';
@@ -119,7 +119,7 @@ const emit = defineEmits<{
 }>();
 
 const loadMoreFiles = ref<InstanceType<typeof MkButton>>();
-const fileInput = ref<HTMLInputElement>();
+const fileInput = shallowRef<HTMLInputElement>();
 
 const folder = ref<Misskey.entities.DriveFolder | null>(null);
 const files = ref<Misskey.entities.DriveFile[]>([]);
diff --git a/packages/frontend/src/components/MkEmojiPicker.vue b/packages/frontend/src/components/MkEmojiPicker.vue
index fe098c9de6..4ce451c85c 100644
--- a/packages/frontend/src/components/MkEmojiPicker.vue
+++ b/packages/frontend/src/components/MkEmojiPicker.vue
@@ -77,7 +77,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed, watch, onMounted } from 'vue';
+import { ref, shallowRef, computed, watch, onMounted } from 'vue';
 import * as Misskey from 'misskey-js';
 import XSection from '@/components/MkEmojiPicker.section.vue';
 import { emojilist, UnicodeEmojiDef, unicodeEmojiCategories as categories } from '@/scripts/emojilist';
@@ -102,8 +102,8 @@ const emit = defineEmits<{
 	(ev: 'chosen', v: string): void;
 }>();
 
-const search = ref<HTMLInputElement>();
-const emojis = ref<HTMLDivElement>();
+const search = shallowRef<HTMLInputElement>();
+const emojis = shallowRef<HTMLDivElement>();
 
 const {
 	reactions: pinned,
diff --git a/packages/frontend/src/components/MkHeatmap.vue b/packages/frontend/src/components/MkHeatmap.vue
index f7a2db8509..fff93ef965 100644
--- a/packages/frontend/src/components/MkHeatmap.vue
+++ b/packages/frontend/src/components/MkHeatmap.vue
@@ -27,8 +27,8 @@ const props = defineProps<{
 	src: string;
 }>();
 
-const rootEl = $ref<HTMLDivElement>(null);
-const chartEl = $ref<HTMLCanvasElement>(null);
+const rootEl = $shallowRef<HTMLDivElement>(null);
+const chartEl = $shallowRef<HTMLCanvasElement>(null);
 const now = new Date();
 let chartInstance: Chart = null;
 let fetching = $ref(true);
diff --git a/packages/frontend/src/components/MkImgWithBlurhash.vue b/packages/frontend/src/components/MkImgWithBlurhash.vue
index 80d7c201a4..6e651a06ab 100644
--- a/packages/frontend/src/components/MkImgWithBlurhash.vue
+++ b/packages/frontend/src/components/MkImgWithBlurhash.vue
@@ -24,7 +24,7 @@ const props = withDefaults(defineProps<{
 	cover: true,
 });
 
-const canvas = $ref<HTMLCanvasElement>();
+const canvas = $shallowRef<HTMLCanvasElement>();
 let loaded = $ref(false);
 
 function draw() {
diff --git a/packages/frontend/src/components/MkInstanceStats.vue b/packages/frontend/src/components/MkInstanceStats.vue
index e576caf78a..531175b764 100644
--- a/packages/frontend/src/components/MkInstanceStats.vue
+++ b/packages/frontend/src/components/MkInstanceStats.vue
@@ -94,8 +94,8 @@ const chartLimit = 500;
 let chartSpan = $ref<'hour' | 'day'>('hour');
 let chartSrc = $ref('active-users');
 let heatmapSrc = $ref('active-users');
-let subDoughnutEl = $ref<HTMLCanvasElement>();
-let pubDoughnutEl = $ref<HTMLCanvasElement>();
+let subDoughnutEl = $shallowRef<HTMLCanvasElement>();
+let pubDoughnutEl = $shallowRef<HTMLCanvasElement>();
 
 const { handler: externalTooltipHandler1 } = useChartTooltip({
 	position: 'middle',
diff --git a/packages/frontend/src/components/MkMediaBanner.vue b/packages/frontend/src/components/MkMediaBanner.vue
index aa06c00fc6..718ce80e0d 100644
--- a/packages/frontend/src/components/MkMediaBanner.vue
+++ b/packages/frontend/src/components/MkMediaBanner.vue
@@ -38,7 +38,7 @@ const props = withDefaults(defineProps<{
 }>(), {
 });
 
-const audioEl = $ref<HTMLAudioElement | null>();
+const audioEl = $shallowRef<HTMLAudioElement | null>();
 let hide = $ref(true);
 
 function volumechange() {
diff --git a/packages/frontend/src/components/MkMenu.child.vue b/packages/frontend/src/components/MkMenu.child.vue
index c2705d394a..0ff8794c5d 100644
--- a/packages/frontend/src/components/MkMenu.child.vue
+++ b/packages/frontend/src/components/MkMenu.child.vue
@@ -6,7 +6,7 @@
 
 <script lang="ts" setup>
 import { on } from 'events';
-import { nextTick, onBeforeUnmount, onMounted, onUnmounted, ref, watch } from 'vue';
+import { nextTick, onBeforeUnmount, onMounted, onUnmounted, ref, shallowRef, watch } from 'vue';
 import MkMenu from './MkMenu.vue';
 import { MenuItem } from '@/types/menu';
 import * as os from '@/os';
@@ -24,7 +24,7 @@ const emit = defineEmits<{
 	(ev: 'actioned'): void;
 }>();
 
-const el = ref<HTMLElement>();
+const el = shallowRef<HTMLElement>();
 const align = 'left';
 
 function setPosition() {
diff --git a/packages/frontend/src/components/MkMenu.vue b/packages/frontend/src/components/MkMenu.vue
index 64d18b6b7c..b893e80345 100644
--- a/packages/frontend/src/components/MkMenu.vue
+++ b/packages/frontend/src/components/MkMenu.vue
@@ -78,7 +78,7 @@ const emit = defineEmits<{
 	(ev: 'close', actioned?: boolean): void;
 }>();
 
-let itemsEl = $ref<HTMLDivElement>();
+let itemsEl = $shallowRef<HTMLDivElement>();
 
 let items2: InnerMenuItem[] = $ref([]);
 
@@ -112,7 +112,7 @@ watch(() => props.items, () => {
 });
 
 let childMenu = $ref<MenuItem[] | null>();
-let childTarget = $ref<HTMLElement | null>();
+let childTarget = $shallowRef<HTMLElement | null>();
 
 function closeChild() {
 	childMenu = null;
diff --git a/packages/frontend/src/components/MkModal.vue b/packages/frontend/src/components/MkModal.vue
index bd6ac02cc8..505b5e64bc 100644
--- a/packages/frontend/src/components/MkModal.vue
+++ b/packages/frontend/src/components/MkModal.vue
@@ -61,7 +61,7 @@ let maxHeight = $ref<number>();
 let fixed = $ref(false);
 let transformOrigin = $ref('center');
 let showing = $ref(true);
-let content = $ref<HTMLElement>();
+let content = $shallowRef<HTMLElement>();
 const zIndex = os.claimZIndex(props.zPriority);
 const type = $computed<ModalTypes>(() => {
 	if (props.preferType === 'auto') {
diff --git a/packages/frontend/src/components/MkModalWindow.vue b/packages/frontend/src/components/MkModalWindow.vue
index d977ca6e9c..bd7146ab88 100644
--- a/packages/frontend/src/components/MkModalWindow.vue
+++ b/packages/frontend/src/components/MkModalWindow.vue
@@ -42,8 +42,8 @@ const emit = defineEmits<{
 }>();
 
 let modal = $ref<InstanceType<typeof MkModal>>();
-let rootEl = $ref<HTMLElement>();
-let headerEl = $ref<HTMLElement>();
+let rootEl = $shallowRef<HTMLElement>();
+let headerEl = $shallowRef<HTMLElement>();
 let bodyWidth = $ref(0);
 let bodyHeight = $ref(0);
 
diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue
index b379a8a7e4..4bbd44122d 100644
--- a/packages/frontend/src/components/MkNote.vue
+++ b/packages/frontend/src/components/MkNote.vue
@@ -101,7 +101,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, inject, onMounted, onUnmounted, reactive, ref, Ref } from 'vue';
+import { computed, inject, onMounted, onUnmounted, reactive, ref, shallowRef, Ref } from 'vue';
 import * as mfm from 'mfm-js';
 import * as misskey from 'misskey-js';
 import MkNoteSub from '@/components/MkNoteSub.vue';
@@ -156,11 +156,11 @@ const isRenote = (
 	note.poll == null
 );
 
-const el = ref<HTMLElement>();
-const menuButton = ref<HTMLElement>();
+const el = shallowRef<HTMLElement>();
+const menuButton = shallowRef<HTMLElement>();
 const renoteButton = ref<InstanceType<typeof MkRenoteButton>>();
-const renoteTime = ref<HTMLElement>();
-const reactButton = ref<HTMLElement>();
+const renoteTime = shallowRef<HTMLElement>();
+const reactButton = shallowRef<HTMLElement>();
 let appearNote = $computed(() => isRenote ? note.renote as misskey.entities.Note : note);
 const isMyRenote = $i && ($i.id === note.userId);
 const showContent = ref(false);
diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue
index 79dff69be5..31188704ab 100644
--- a/packages/frontend/src/components/MkNoteDetailed.vue
+++ b/packages/frontend/src/components/MkNoteDetailed.vue
@@ -112,7 +112,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, inject, onMounted, onUnmounted, reactive, ref } from 'vue';
+import { computed, inject, onMounted, onUnmounted, reactive, ref, shallowRef } from 'vue';
 import * as mfm from 'mfm-js';
 import * as misskey from 'misskey-js';
 import MkNoteSub from '@/components/MkNoteSub.vue';
@@ -166,11 +166,11 @@ const isRenote = (
 	note.poll == null
 );
 
-const el = ref<HTMLElement>();
-const menuButton = ref<HTMLElement>();
+const el = shallowRef<HTMLElement>();
+const menuButton = shallowRef<HTMLElement>();
 const renoteButton = ref<InstanceType<typeof MkRenoteButton>>();
-const renoteTime = ref<HTMLElement>();
-const reactButton = ref<HTMLElement>();
+const renoteTime = shallowRef<HTMLElement>();
+const reactButton = shallowRef<HTMLElement>();
 let appearNote = $computed(() => isRenote ? note.renote as misskey.entities.Note : note);
 const isMyRenote = $i && ($i.id === note.userId);
 const showContent = ref(false);
diff --git a/packages/frontend/src/components/MkNotification.vue b/packages/frontend/src/components/MkNotification.vue
index c8b197a850..a21a9e12a1 100644
--- a/packages/frontend/src/components/MkNotification.vue
+++ b/packages/frontend/src/components/MkNotification.vue
@@ -73,7 +73,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, onMounted, onUnmounted, watch } from 'vue';
+import { ref, shallowRef, onMounted, onUnmounted, watch } from 'vue';
 import * as misskey from 'misskey-js';
 import XReactionIcon from '@/components/MkReactionIcon.vue';
 import MkFollowButton from '@/components/MkFollowButton.vue';
@@ -95,7 +95,7 @@ const props = withDefaults(defineProps<{
 	full: false,
 });
 
-const elRef = ref<HTMLElement>(null);
+const elRef = shallowRef<HTMLElement>(null);
 const reactionRef = ref(null);
 
 let readObserver: IntersectionObserver | undefined;
diff --git a/packages/frontend/src/components/MkPagination.vue b/packages/frontend/src/components/MkPagination.vue
index b5a6bd271a..2c0a30a888 100644
--- a/packages/frontend/src/components/MkPagination.vue
+++ b/packages/frontend/src/components/MkPagination.vue
@@ -32,7 +32,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, ComputedRef, isRef, markRaw, onActivated, onDeactivated, Ref, ref, watch } from 'vue';
+import { computed, ComputedRef, isRef, markRaw, onActivated, onDeactivated, Ref, ref, shallowRef, watch } from 'vue';
 import * as misskey from 'misskey-js';
 import * as os from '@/os';
 import { onScrollTop, isTopVisible, getScrollPosition, getScrollContainer } from '@/scripts/scroll';
@@ -74,7 +74,7 @@ const emit = defineEmits<{
 
 type Item = { id: string; [another: string]: unknown; };
 
-const rootEl = ref<HTMLElement>();
+const rootEl = shallowRef<HTMLElement>();
 const items = ref<Item[]>([]);
 const queue = ref<Item[]>([]);
 const offset = ref(0);
diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue
index fb2cb5671d..883ad9f14f 100644
--- a/packages/frontend/src/components/MkPostForm.vue
+++ b/packages/frontend/src/components/MkPostForm.vue
@@ -128,10 +128,10 @@ const emit = defineEmits<{
 	(ev: 'esc'): void;
 }>();
 
-const textareaEl = $ref<HTMLTextAreaElement | null>(null);
-const cwInputEl = $ref<HTMLInputElement | null>(null);
-const hashtagsInputEl = $ref<HTMLInputElement | null>(null);
-const visibilityButton = $ref<HTMLElement | null>(null);
+const textareaEl = $shallowRef<HTMLTextAreaElement | null>(null);
+const cwInputEl = $shallowRef<HTMLInputElement | null>(null);
+const hashtagsInputEl = $shallowRef<HTMLInputElement | null>(null);
+const visibilityButton = $shallowRef<HTMLElement | null>(null);
 
 let posting = $ref(false);
 let posted = $ref(false);
diff --git a/packages/frontend/src/components/MkReactionsViewer.reaction.vue b/packages/frontend/src/components/MkReactionsViewer.reaction.vue
index b10c7009f5..e0e1262550 100644
--- a/packages/frontend/src/components/MkReactionsViewer.reaction.vue
+++ b/packages/frontend/src/components/MkReactionsViewer.reaction.vue
@@ -12,7 +12,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, onMounted, ref, watch } from 'vue';
+import { computed, onMounted, ref, shallowRef, watch } from 'vue';
 import * as misskey from 'misskey-js';
 import XDetails from '@/components/MkReactionsViewer.details.vue';
 import XReactionIcon from '@/components/MkReactionIcon.vue';
@@ -28,7 +28,7 @@ const props = defineProps<{
 	note: misskey.entities.Note;
 }>();
 
-const buttonRef = ref<HTMLElement>();
+const buttonRef = shallowRef<HTMLElement>();
 
 const canToggle = computed(() => !props.reaction.match(/@\w/) && $i);
 
diff --git a/packages/frontend/src/components/MkRenoteButton.vue b/packages/frontend/src/components/MkRenoteButton.vue
index e0b1eaafc9..e84d4a3faa 100644
--- a/packages/frontend/src/components/MkRenoteButton.vue
+++ b/packages/frontend/src/components/MkRenoteButton.vue
@@ -14,7 +14,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, ref } from 'vue';
+import { computed, ref, shallowRef } from 'vue';
 import * as misskey from 'misskey-js';
 import XDetails from '@/components/MkUsersTooltip.vue';
 import { pleaseLogin } from '@/scripts/please-login';
@@ -28,7 +28,7 @@ const props = defineProps<{
 	count: number;
 }>();
 
-const buttonRef = ref<HTMLElement>();
+const buttonRef = shallowRef<HTMLElement>();
 
 const canRenote = computed(() => ['public', 'home'].includes(props.note.visibility) || props.note.userId === $i.id);
 
diff --git a/packages/frontend/src/components/MkRetentionHeatmap.vue b/packages/frontend/src/components/MkRetentionHeatmap.vue
index 4dcf0cef9c..95690bde47 100644
--- a/packages/frontend/src/components/MkRetentionHeatmap.vue
+++ b/packages/frontend/src/components/MkRetentionHeatmap.vue
@@ -23,8 +23,8 @@ import { initChart } from '@/scripts/init-chart';
 
 initChart();
 
-const rootEl = $ref<HTMLDivElement>(null);
-const chartEl = $ref<HTMLCanvasElement>(null);
+const rootEl = $shallowRef<HTMLDivElement>(null);
+const chartEl = $shallowRef<HTMLCanvasElement>(null);
 const now = new Date();
 let chartInstance: Chart = null;
 let fetching = $ref(true);
diff --git a/packages/frontend/src/components/MkSparkle.vue b/packages/frontend/src/components/MkSparkle.vue
index cdeaf9c417..0f268a9d1a 100644
--- a/packages/frontend/src/components/MkSparkle.vue
+++ b/packages/frontend/src/components/MkSparkle.vue
@@ -64,10 +64,10 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref } from 'vue';
+import { onMounted, onUnmounted, ref, shallowRef } from 'vue';
 
 const particles = ref([]);
-const el = ref<HTMLElement>();
+const el = shallowRef<HTMLElement>();
 const width = ref(0);
 const height = ref(0);
 const colors = ['#FF1493', '#00FFFF', '#FFE202', '#FFE202', '#FFE202'];
diff --git a/packages/frontend/src/components/MkTagCloud.vue b/packages/frontend/src/components/MkTagCloud.vue
index 2dfd26edb0..9f7e76f18e 100644
--- a/packages/frontend/src/components/MkTagCloud.vue
+++ b/packages/frontend/src/components/MkTagCloud.vue
@@ -19,9 +19,9 @@ const computedStyle = getComputedStyle(document.documentElement);
 const idForCanvas = Array.from(Array(16)).map(() => SAFE_FOR_HTML_ID[Math.floor(Math.random() * SAFE_FOR_HTML_ID.length)]).join('');
 const idForTags = Array.from(Array(16)).map(() => SAFE_FOR_HTML_ID[Math.floor(Math.random() * SAFE_FOR_HTML_ID.length)]).join('');
 let available = $ref(false);
-let rootEl = $ref<HTMLElement | null>(null);
-let canvasEl = $ref<HTMLCanvasElement | null>(null);
-let tagsEl = $ref<HTMLElement | null>(null);
+let rootEl = $shallowRef<HTMLElement | null>(null);
+let canvasEl = $shallowRef<HTMLCanvasElement | null>(null);
+let tagsEl = $shallowRef<HTMLElement | null>(null);
 let width = $ref(300);
 
 watch($$(available), () => {
diff --git a/packages/frontend/src/components/MkTooltip.vue b/packages/frontend/src/components/MkTooltip.vue
index 9dba0c7350..399cec36c7 100644
--- a/packages/frontend/src/components/MkTooltip.vue
+++ b/packages/frontend/src/components/MkTooltip.vue
@@ -10,7 +10,7 @@
 </template>
 
 <script lang="ts" setup>
-import { nextTick, onMounted, onUnmounted, ref } from 'vue';
+import { nextTick, onMounted, onUnmounted, ref, shallowRef } from 'vue';
 import * as os from '@/os';
 import { calcPopupPosition } from '@/scripts/popup-position';
 
@@ -34,7 +34,7 @@ const emit = defineEmits<{
 	(ev: 'closed'): void;
 }>();
 
-const el = ref<HTMLElement>();
+const el = shallowRef<HTMLElement>();
 const zIndex = os.claimZIndex('high');
 
 function setPosition() {
diff --git a/packages/frontend/src/components/MkVisibility.vue b/packages/frontend/src/components/MkVisibility.vue
index 229907fbb8..2becb69d5a 100644
--- a/packages/frontend/src/components/MkVisibility.vue
+++ b/packages/frontend/src/components/MkVisibility.vue
@@ -22,7 +22,7 @@ const props = defineProps<{
 	},
 }>();
 
-const specified = $ref<HTMLElement>();
+const specified = $shallowRef<HTMLElement>();
 
 if (props.note.visibility === 'specified') {
 	useTooltip($$(specified), async (showing) => {
diff --git a/packages/frontend/src/components/MkWindow.vue b/packages/frontend/src/components/MkWindow.vue
index dca258421b..0f7e0e4f2e 100644
--- a/packages/frontend/src/components/MkWindow.vue
+++ b/packages/frontend/src/components/MkWindow.vue
@@ -88,7 +88,7 @@ const emit = defineEmits<{
 
 provide('inWindow', true);
 
-let rootEl = $ref<HTMLElement | null>();
+let rootEl = $shallowRef<HTMLElement | null>();
 let showing = $ref(true);
 let beforeClickedAt = 0;
 let maximized = $ref(false);
diff --git a/packages/frontend/src/components/form/checkbox.vue b/packages/frontend/src/components/form/checkbox.vue
index d869b600c9..a8e24dd839 100644
--- a/packages/frontend/src/components/form/checkbox.vue
+++ b/packages/frontend/src/components/form/checkbox.vue
@@ -35,7 +35,7 @@ const emit = defineEmits<{
 	(ev: 'update:modelValue', v: boolean): void;
 }>();
 
-let button = $ref<HTMLElement>();
+let button = $shallowRef<HTMLElement>();
 const checked = toRefs(props).modelValue;
 const toggle = () => {
 	if (props.disabled) return;
diff --git a/packages/frontend/src/components/form/folder.vue b/packages/frontend/src/components/form/folder.vue
index d7603e58d1..49d3bf93e1 100644
--- a/packages/frontend/src/components/form/folder.vue
+++ b/packages/frontend/src/components/form/folder.vue
@@ -40,7 +40,7 @@ const props = withDefaults(defineProps<{
 
 let opened = $ref(props.defaultOpen);
 let openedAtLeastOnce = $ref(props.defaultOpen);
-let root = $ref<HTMLElement>();
+let root = $shallowRef<HTMLElement>();
 
 function enter(el) {
 	const elementHeight = el.getBoundingClientRect().height;
diff --git a/packages/frontend/src/components/form/input.vue b/packages/frontend/src/components/form/input.vue
index b7e216bfe2..4f3e50c31a 100644
--- a/packages/frontend/src/components/form/input.vue
+++ b/packages/frontend/src/components/form/input.vue
@@ -34,7 +34,7 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
+import { onMounted, onUnmounted, nextTick, ref, shallowRef, watch, computed, toRefs } from 'vue';
 import { debounce } from 'throttle-debounce';
 import MkButton from '@/components/MkButton.vue';
 import { useInterval } from '@/scripts/use-interval';
@@ -74,9 +74,9 @@ const focused = ref(false);
 const changed = ref(false);
 const invalid = ref(false);
 const filled = computed(() => v.value !== '' && v.value != null);
-const inputEl = ref<HTMLElement>();
-const prefixEl = ref<HTMLElement>();
-const suffixEl = ref<HTMLElement>();
+const inputEl = shallowRef<HTMLElement>();
+const prefixEl = shallowRef<HTMLElement>();
+const suffixEl = shallowRef<HTMLElement>();
 const height =
 	props.small ? 35 :
 	props.large ? 39 :
diff --git a/packages/frontend/src/components/form/switch.vue b/packages/frontend/src/components/form/switch.vue
index 1ed00ae655..5c9e3a5223 100644
--- a/packages/frontend/src/components/form/switch.vue
+++ b/packages/frontend/src/components/form/switch.vue
@@ -34,7 +34,7 @@ const emit = defineEmits<{
 	(ev: 'update:modelValue', v: boolean): void;
 }>();
 
-let button = $ref<HTMLElement>();
+let button = $shallowRef<HTMLElement>();
 const checked = toRefs(props).modelValue;
 const toggle = () => {
 	if (props.disabled) return;
diff --git a/packages/frontend/src/components/global/MkPageHeader.vue b/packages/frontend/src/components/global/MkPageHeader.vue
index 9c7c49ac58..e39cc70185 100644
--- a/packages/frontend/src/components/global/MkPageHeader.vue
+++ b/packages/frontend/src/components/global/MkPageHeader.vue
@@ -77,9 +77,9 @@ const metadata = injectPageMetadata();
 const hideTitle = inject('shouldOmitHeaderTitle', false);
 const thin_ = props.thin || inject('shouldHeaderThin', false);
 
-const el = $ref<HTMLElement | undefined>(undefined);
+const el = $shallowRef<HTMLElement | undefined>(undefined);
 const tabRefs: Record<string, HTMLElement | null> = {};
-const tabHighlightEl = $ref<HTMLElement | null>(null);
+const tabHighlightEl = $shallowRef<HTMLElement | null>(null);
 const bg = ref<string | undefined>(undefined);
 let narrow = $ref(false);
 const hasTabs = $computed(() => props.tabs.length > 0);
diff --git a/packages/frontend/src/components/global/MkSpacer.vue b/packages/frontend/src/components/global/MkSpacer.vue
index 01e7409801..88c1daaf23 100644
--- a/packages/frontend/src/components/global/MkSpacer.vue
+++ b/packages/frontend/src/components/global/MkSpacer.vue
@@ -24,8 +24,8 @@ const props = withDefaults(defineProps<{
 });
 
 let ro: ResizeObserver;
-let root = $ref<HTMLElement>();
-let content = $ref<HTMLElement>();
+let root = $shallowRef<HTMLElement>();
+let content = $shallowRef<HTMLElement>();
 let margin = $ref(props.marginMin);
 const widthHistory = [null, null] as [number | null, number | null];
 const heightHistory = [null, null] as [number | null, number | null];
@@ -72,7 +72,6 @@ onMounted(() => {
 		const pastHeight = heightHistory.pop();
 		heightHistory.unshift(height);
 
-
 		if (pastWidth === width && pastHeight === height) {
 			return;
 		}
diff --git a/packages/frontend/src/components/global/MkStickyContainer.vue b/packages/frontend/src/components/global/MkStickyContainer.vue
index 44f4f065a6..a3fee91a36 100644
--- a/packages/frontend/src/components/global/MkStickyContainer.vue
+++ b/packages/frontend/src/components/global/MkStickyContainer.vue
@@ -18,9 +18,9 @@ const CURRENT_STICKY_TOP = 'CURRENT_STICKY_TOP';
 <script lang="ts" setup>
 import { onMounted, onUnmounted, provide, inject, Ref, ref, watch } from 'vue';
 
-const rootEl = $ref<HTMLElement>();
-const headerEl = $ref<HTMLElement>();
-const bodyEl = $ref<HTMLElement>();
+const rootEl = $shallowRef<HTMLElement>();
+const headerEl = $shallowRef<HTMLElement>();
+const bodyEl = $shallowRef<HTMLElement>();
 
 let headerHeight = $ref<string | undefined>();
 let childStickyTop = $ref(0);
diff --git a/packages/frontend/src/pages/about-misskey.vue b/packages/frontend/src/pages/about-misskey.vue
index 67f141d458..5085b12527 100644
--- a/packages/frontend/src/pages/about-misskey.vue
+++ b/packages/frontend/src/pages/about-misskey.vue
@@ -156,7 +156,7 @@ const patrons = [
 let easterEggReady = false;
 let easterEggEmojis = $ref([]);
 let easterEggEngine = $ref(null);
-const containerEl = $ref<HTMLElement>();
+const containerEl = $shallowRef<HTMLElement>();
 
 function iconLoaded() {
 	const emojis = defaultStore.state.reactions;
diff --git a/packages/frontend/src/pages/admin/_header_.vue b/packages/frontend/src/pages/admin/_header_.vue
index bdb41b2d2c..a342644516 100644
--- a/packages/frontend/src/pages/admin/_header_.vue
+++ b/packages/frontend/src/pages/admin/_header_.vue
@@ -28,7 +28,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, onMounted, onUnmounted, ref, inject, watch, nextTick } from 'vue';
+import { computed, onMounted, onUnmounted, ref, shallowRef, inject, watch, nextTick } from 'vue';
 import tinycolor from 'tinycolor2';
 import { popupMenu } from '@/os';
 import { url } from '@/config';
@@ -64,9 +64,9 @@ const emit = defineEmits<{
 
 const metadata = injectPageMetadata();
 
-const el = ref<HTMLElement>(null);
+const el = shallowRef<HTMLElement>(null);
 const tabRefs = {};
-const tabHighlightEl = $ref<HTMLElement | null>(null);
+const tabHighlightEl = $shallowRef<HTMLElement | null>(null);
 const bg = ref(null);
 const height = ref(0);
 const hasTabs = computed(() => {
diff --git a/packages/frontend/src/pages/admin/overview.active-users.vue b/packages/frontend/src/pages/admin/overview.active-users.vue
index d760d90ef1..e01009b7aa 100644
--- a/packages/frontend/src/pages/admin/overview.active-users.vue
+++ b/packages/frontend/src/pages/admin/overview.active-users.vue
@@ -23,7 +23,7 @@ import { initChart } from '@/scripts/init-chart';
 
 initChart();
 
-const chartEl = $ref<HTMLCanvasElement>(null);
+const chartEl = $shallowRef<HTMLCanvasElement>(null);
 const now = new Date();
 let chartInstance: Chart = null;
 const chartLimit = 7;
diff --git a/packages/frontend/src/pages/admin/overview.ap-requests.vue b/packages/frontend/src/pages/admin/overview.ap-requests.vue
index 5dcb67474f..61a0667080 100644
--- a/packages/frontend/src/pages/admin/overview.ap-requests.vue
+++ b/packages/frontend/src/pages/admin/overview.ap-requests.vue
@@ -34,8 +34,8 @@ import { initChart } from '@/scripts/init-chart';
 initChart();
 
 const chartLimit = 50;
-const chartEl = $ref<HTMLCanvasElement>();
-const chartEl2 = $ref<HTMLCanvasElement>();
+const chartEl = $shallowRef<HTMLCanvasElement>();
+const chartEl2 = $shallowRef<HTMLCanvasElement>();
 let fetching = $ref(true);
 
 const { handler: externalTooltipHandler } = useChartTooltip();
diff --git a/packages/frontend/src/pages/admin/overview.pie.vue b/packages/frontend/src/pages/admin/overview.pie.vue
index b6f0d1b705..416e963356 100644
--- a/packages/frontend/src/pages/admin/overview.pie.vue
+++ b/packages/frontend/src/pages/admin/overview.pie.vue
@@ -3,7 +3,7 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref } from 'vue';
+import { onMounted, onUnmounted, ref, shallowRef } from 'vue';
 import { Chart } from 'chart.js';
 import number from '@/filters/number';
 import { defaultStore } from '@/store';
@@ -16,7 +16,7 @@ const props = defineProps<{
 	data: { name: string; value: number; color: string; onClick?: () => void }[];
 }>();
 
-const chartEl = ref<HTMLCanvasElement>(null);
+const chartEl = shallowRef<HTMLCanvasElement>(null);
 
 const { handler: externalTooltipHandler } = useChartTooltip({
 	position: 'middle',
diff --git a/packages/frontend/src/pages/admin/overview.queue.chart.vue b/packages/frontend/src/pages/admin/overview.queue.chart.vue
index 1765577d45..0162d53665 100644
--- a/packages/frontend/src/pages/admin/overview.queue.chart.vue
+++ b/packages/frontend/src/pages/admin/overview.queue.chart.vue
@@ -3,7 +3,7 @@
 </template>
 
 <script lang="ts" setup>
-import { watch, onMounted, onUnmounted, ref } from 'vue';
+import { watch, onMounted, onUnmounted, ref, shallowRef } from 'vue';
 import { Chart } from 'chart.js';
 import number from '@/filters/number';
 import * as os from '@/os';
@@ -19,7 +19,7 @@ const props = defineProps<{
 	type: string;
 }>();
 
-const chartEl = ref<HTMLCanvasElement>(null);
+const chartEl = shallowRef<HTMLCanvasElement>(null);
 
 const { handler: externalTooltipHandler } = useChartTooltip();
 
diff --git a/packages/frontend/src/pages/admin/overview.vue b/packages/frontend/src/pages/admin/overview.vue
index 5fdfa5f263..c16a928a80 100644
--- a/packages/frontend/src/pages/admin/overview.vue
+++ b/packages/frontend/src/pages/admin/overview.vue
@@ -82,7 +82,7 @@ import { defaultStore } from '@/store';
 import MkFileListForAdmin from '@/components/MkFileListForAdmin.vue';
 import MkFolder from '@/components/MkFolder.vue';
 
-const rootEl = $ref<HTMLElement>();
+const rootEl = $shallowRef<HTMLElement>();
 let serverInfo: any = $ref(null);
 let topSubInstancesForPie: any = $ref(null);
 let topPubInstancesForPie: any = $ref(null);
diff --git a/packages/frontend/src/pages/admin/queue.chart.chart.vue b/packages/frontend/src/pages/admin/queue.chart.chart.vue
index ae8d9ae4de..a0c05df983 100644
--- a/packages/frontend/src/pages/admin/queue.chart.chart.vue
+++ b/packages/frontend/src/pages/admin/queue.chart.chart.vue
@@ -3,7 +3,7 @@
 </template>
 
 <script lang="ts" setup>
-import { watch, onMounted, onUnmounted, ref } from 'vue';
+import { watch, onMounted, onUnmounted, ref, shallowRef } from 'vue';
 import { Chart } from 'chart.js';
 import number from '@/filters/number';
 import * as os from '@/os';
@@ -19,7 +19,7 @@ const props = defineProps<{
 	type: string;
 }>();
 
-const chartEl = ref<HTMLCanvasElement>(null);
+const chartEl = shallowRef<HTMLCanvasElement>(null);
 
 const { handler: externalTooltipHandler } = useChartTooltip();
 
diff --git a/packages/frontend/src/pages/antenna-timeline.vue b/packages/frontend/src/pages/antenna-timeline.vue
index 1d5c3aa1d3..fd98ef5604 100644
--- a/packages/frontend/src/pages/antenna-timeline.vue
+++ b/packages/frontend/src/pages/antenna-timeline.vue
@@ -34,7 +34,7 @@ const props = defineProps<{
 
 let antenna = $ref(null);
 let queue = $ref(0);
-let rootEl = $ref<HTMLElement>();
+let rootEl = $shallowRef<HTMLElement>();
 let tlEl = $ref<InstanceType<typeof XTimeline>>();
 const keymap = $computed(() => ({
 	't': focus,
diff --git a/packages/frontend/src/pages/messaging/messaging-room.form.vue b/packages/frontend/src/pages/messaging/messaging-room.form.vue
index 84572815c0..2c54c6f71f 100644
--- a/packages/frontend/src/pages/messaging/messaging-room.form.vue
+++ b/packages/frontend/src/pages/messaging/messaging-room.form.vue
@@ -46,8 +46,8 @@ const props = defineProps<{
 	group?: Misskey.entities.UserGroup | null;
 }>();
 
-let textEl = $ref<HTMLTextAreaElement>();
-let fileEl = $ref<HTMLInputElement>();
+let textEl = $shallowRef<HTMLTextAreaElement>();
+let fileEl = $shallowRef<HTMLInputElement>();
 
 let text = $ref<string>('');
 let file = $ref<Misskey.entities.DriveFile | null>(null);
diff --git a/packages/frontend/src/pages/messaging/messaging-room.vue b/packages/frontend/src/pages/messaging/messaging-room.vue
index 280e6a903b..0db431b083 100644
--- a/packages/frontend/src/pages/messaging/messaging-room.vue
+++ b/packages/frontend/src/pages/messaging/messaging-room.vue
@@ -71,7 +71,7 @@ const props = defineProps<{
 	groupId?: string;
 }>();
 
-let rootEl = $ref<HTMLDivElement>();
+let rootEl = $shallowRef<HTMLDivElement>();
 let formEl = $ref<InstanceType<typeof XForm>>();
 let pagingComponent = $ref<InstanceType<typeof MkPagination>>();
 
diff --git a/packages/frontend/src/pages/settings/index.vue b/packages/frontend/src/pages/settings/index.vue
index 9517e3a5c8..119a75b650 100644
--- a/packages/frontend/src/pages/settings/index.vue
+++ b/packages/frontend/src/pages/settings/index.vue
@@ -22,7 +22,7 @@
 </template>
 
 <script setup lang="ts">
-import { computed, defineAsyncComponent, inject, nextTick, onActivated, onMounted, onUnmounted, provide, ref, watch } from 'vue';
+import { computed, defineAsyncComponent, inject, nextTick, onActivated, onMounted, onUnmounted, provide, ref, shallowRef, watch } from 'vue';
 import { i18n } from '@/i18n';
 import MkInfo from '@/components/MkInfo.vue';
 import MkSuperMenu from '@/components/MkSuperMenu.vue';
@@ -40,7 +40,7 @@ const indexInfo = {
 	hideHeader: true,
 };
 const INFO = ref(indexInfo);
-const el = ref<HTMLElement | null>(null);
+const el = shallowRef<HTMLElement | null>(null);
 const childInfo = ref(null);
 
 const router = useRouter();
diff --git a/packages/frontend/src/pages/timeline.vue b/packages/frontend/src/pages/timeline.vue
index fbbe43f2c0..640d940d91 100644
--- a/packages/frontend/src/pages/timeline.vue
+++ b/packages/frontend/src/pages/timeline.vue
@@ -42,7 +42,7 @@ const keymap = {
 };
 
 const tlComponent = $ref<InstanceType<typeof XTimeline>>();
-const rootEl = $ref<HTMLElement>();
+const rootEl = $shallowRef<HTMLElement>();
 
 let queue = $ref(0);
 const src = $computed({ get: () => defaultStore.reactiveState.tl.value.src, set: (x) => saveSrc(x) });
diff --git a/packages/frontend/src/pages/user-list-timeline.vue b/packages/frontend/src/pages/user-list-timeline.vue
index a223dee319..b69bbd575f 100644
--- a/packages/frontend/src/pages/user-list-timeline.vue
+++ b/packages/frontend/src/pages/user-list-timeline.vue
@@ -35,7 +35,7 @@ const props = defineProps<{
 let list = $ref(null);
 let queue = $ref(0);
 let tlEl = $ref<InstanceType<typeof XTimeline>>();
-let rootEl = $ref<HTMLElement>();
+let rootEl = $shallowRef<HTMLElement>();
 
 watch(() => props.listId, async () => {
 	list = await os.api('users/lists/show', {
diff --git a/packages/frontend/src/pages/user/activity.heatmap.vue b/packages/frontend/src/pages/user/activity.heatmap.vue
index 000653ea5c..8472f79948 100644
--- a/packages/frontend/src/pages/user/activity.heatmap.vue
+++ b/packages/frontend/src/pages/user/activity.heatmap.vue
@@ -28,8 +28,8 @@ const props = defineProps<{
 	user: misskey.entities.User;
 }>();
 
-const rootEl = $ref<HTMLDivElement>(null);
-const chartEl = $ref<HTMLCanvasElement>(null);
+const rootEl = $shallowRef<HTMLDivElement>(null);
+const chartEl = $shallowRef<HTMLCanvasElement>(null);
 const now = new Date();
 let chartInstance: Chart = null;
 let fetching = $ref(true);
diff --git a/packages/frontend/src/pages/user/activity.pv.vue b/packages/frontend/src/pages/user/activity.pv.vue
index 25d708e71a..eaaeba976c 100644
--- a/packages/frontend/src/pages/user/activity.pv.vue
+++ b/packages/frontend/src/pages/user/activity.pv.vue
@@ -28,7 +28,7 @@ const props = defineProps<{
 	user: misskey.entities.User;
 }>();
 
-const chartEl = $ref<HTMLCanvasElement>(null);
+const chartEl = $shallowRef<HTMLCanvasElement>(null);
 const now = new Date();
 let chartInstance: Chart = null;
 const chartLimit = 30;
diff --git a/packages/frontend/src/ui/classic.vue b/packages/frontend/src/ui/classic.vue
index 6369bb8976..ba9120a77d 100644
--- a/packages/frontend/src/ui/classic.vue
+++ b/packages/frontend/src/ui/classic.vue
@@ -64,7 +64,7 @@ let fullView = $ref(false);
 let globalHeaderHeight = $ref(0);
 const wallpaper = localStorage.getItem('wallpaper') != null;
 const showMenuOnTop = $computed(() => defaultStore.state.menuDisplay === 'top');
-let live2d = $ref<HTMLIFrameElement>();
+let live2d = $shallowRef<HTMLIFrameElement>();
 let widgetsLeft = $ref();
 let widgetsRight = $ref();
 
diff --git a/packages/frontend/src/ui/deck.vue b/packages/frontend/src/ui/deck.vue
index 6efb2ce290..b0306ab832 100644
--- a/packages/frontend/src/ui/deck.vue
+++ b/packages/frontend/src/ui/deck.vue
@@ -125,7 +125,7 @@ function showSettings() {
 	os.pageWindow('/settings/deck');
 }
 
-let columnsEl = $ref<HTMLElement>();
+let columnsEl = $shallowRef<HTMLElement>();
 
 const addColumn = async (ev) => {
 	const columns = [
diff --git a/packages/frontend/src/ui/deck/column.vue b/packages/frontend/src/ui/deck/column.vue
index 5de5528b1d..0b8d6afe55 100644
--- a/packages/frontend/src/ui/deck/column.vue
+++ b/packages/frontend/src/ui/deck/column.vue
@@ -59,7 +59,7 @@ const emit = defineEmits<{
 	(ev: 'change-active-state', v: boolean): void;
 }>();
 
-let body = $ref<HTMLDivElement>();
+let body = $shallowRef<HTMLDivElement>();
 
 let dragging = $ref(false);
 watch($$(dragging), v => os.deckGlobalEvents.emit(v ? 'column.dragStart' : 'column.dragEnd'));
diff --git a/packages/frontend/src/ui/universal.vue b/packages/frontend/src/ui/universal.vue
index 9f1324313e..9e1fee5b6b 100644
--- a/packages/frontend/src/ui/universal.vue
+++ b/packages/frontend/src/ui/universal.vue
@@ -86,7 +86,7 @@ window.addEventListener('resize', () => {
 });
 
 let pageMetadata = $ref<null | ComputedRef<PageMetadata>>();
-const widgetsEl = $ref<HTMLElement>();
+const widgetsEl = $shallowRef<HTMLElement>();
 const widgetsShowing = $ref(false);
 
 provide('router', mainRouter);
diff --git a/packages/frontend/src/ui/universal.widgets.vue b/packages/frontend/src/ui/universal.widgets.vue
index 35de23ebfa..d4210f6988 100644
--- a/packages/frontend/src/ui/universal.widgets.vue
+++ b/packages/frontend/src/ui/universal.widgets.vue
@@ -31,7 +31,7 @@ const emit = defineEmits<{
 	(ev: 'mounted', el?: Element): void;
 }>();
 
-let rootEl = $ref<HTMLDivElement>();
+let rootEl = $shallowRef<HTMLDivElement>();
 
 const widgets = $computed(() => {
 	if (props.place === null) return defaultStore.reactiveState.widgets.value;
diff --git a/packages/frontend/src/widgets/aichan.vue b/packages/frontend/src/widgets/aichan.vue
index 828490fd9c..ab5b375ae4 100644
--- a/packages/frontend/src/widgets/aichan.vue
+++ b/packages/frontend/src/widgets/aichan.vue
@@ -5,7 +5,7 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, reactive, ref } from 'vue';
+import { onMounted, onUnmounted, reactive, ref, shallowRef } from 'vue';
 import { useWidgetPropsManager, Widget, WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget';
 import { GetFormResultType } from '@/scripts/form';
 
@@ -32,7 +32,7 @@ const { widgetProps, configure } = useWidgetPropsManager(name,
 	emit,
 );
 
-const live2d = ref<HTMLIFrameElement>();
+const live2d = shallowRef<HTMLIFrameElement>();
 
 const touched = () => {
 	//if (this.live2d) this.live2d.changeExpression('gurugurume');
diff --git a/packages/frontend/src/widgets/slideshow.vue b/packages/frontend/src/widgets/slideshow.vue
index e317b8ab94..2c937d85c5 100644
--- a/packages/frontend/src/widgets/slideshow.vue
+++ b/packages/frontend/src/widgets/slideshow.vue
@@ -12,7 +12,7 @@
 </template>
 
 <script lang="ts" setup>
-import { nextTick, onMounted, onUnmounted, reactive, ref } from 'vue';
+import { nextTick, onMounted, onUnmounted, reactive, ref, shallowRef } from 'vue';
 import { useWidgetPropsManager, Widget, WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget';
 import { GetFormResultType } from '@/scripts/form';
 import * as os from '@/os';
@@ -49,8 +49,8 @@ const { widgetProps, configure, save } = useWidgetPropsManager(name,
 
 const images = ref([]);
 const fetching = ref(true);
-const slideA = ref<HTMLElement>();
-const slideB = ref<HTMLElement>();
+const slideA = shallowRef<HTMLElement>();
+const slideB = shallowRef<HTMLElement>();
 
 const change = () => {
 	if (images.value.length === 0) return;