diff --git a/packages/frontend/src/components/MkAutocomplete.vue b/packages/frontend/src/components/MkAutocomplete.vue
index a2b020b900c2ad9ff32489ce4f545e5add9dcf61..08e2c29de29419e68b889cf86f8fa79fb4acc3c9 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 2b1b66da29c4d40ac6391fdce8ca71d05c8173f4..daf47e12d4fd30b3d6306f3f9f0a38b786301654 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 6d218389fc00752be265822e67e2e2f19d09de46..8db2e54e880d35148d5dfab77232b9a36dc1381b 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 d602849651e49b391ae49c77cd16869c741e4da0..7d3a3d289b3dab4f2848d2067b0146541c0d4c01 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 6470f8b9728861b0f4fa5bdcc1593b0eca95ff99..9d9abc5d092a3eee3c495e692d98b7d782fb8a78 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 ae18160dea6cf3087b747246b44aab800a134dca..3ff73d6669eb9f4705106341d62b803ab0d40e49 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 4053870950b61f0e9cd5d56fdc8e21f7b394ab7d..843c5f1c544ae8a1f73ebf9f210b67fcc1207c95 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 fe098c9de61e180072bb472fd2ede08a43a0ff0a..4ce451c85c41da50a322137e347a5586ec2828c0 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 f7a2db85095029f7ea81f72514e5d0c93a32300b..fff93ef9655705aa463037c48d4f5c560965942e 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 80d7c201a403a2a4f7307eb645a55b6166e63026..6e651a06ab685bf32f15b2124e0f42d45f7b5f70 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 e576caf78a59edbde544def5c063b14e7641dcfe..531175b764ce5bb37e3fe91ee6d4e8a5b67049dc 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 aa06c00fc640ba7dd3eb2c92da8a691ef19d6926..718ce80e0d68cee7c584137bc1e5e70a1603b2bf 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 c2705d394a210ecf6358c8b8ae23d92f54667fda..0ff8794c5da58ce689fac634de6b31126850204e 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 64d18b6b7c90299926e8df4d73198ec2aeb6b6d9..b893e80345baf528233f248aa3ec6d39265edf51 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 bd6ac02cc85a39e89f5c48fe5dc47fcb7fda18a4..505b5e64bc0c7a982354a1a8a5c10a31d0836bb0 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 d977ca6e9cbb8b24e508bbd71c887fcaa2eff866..bd7146ab88c0df1956f7d2974b5dac3ae353e7b2 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 b379a8a7e43e099e2b6d4920e820e8b43d7661cd..4bbd44122d1bcda71fad2935f42fb0508530a821 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 79dff69be5920d4b84377932fc8859507b0d0056..31188704ab30cbed83565bf2d99802db16af869f 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 c8b197a8501d8da7cecc7623aeeca0eb93c5b666..a21a9e12a142233891486b3ecbd31683168bd5c6 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 b5a6bd271a3d3d8d2f50bee761b482100ca7c450..2c0a30a8884a21b12591cc49f8f692e70f203881 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 fb2cb5671dca78a9f167722422038de77d4bbccb..883ad9f14f2d2211b598a856658cbace74d40b13 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 b10c7009f5652ee5cc79aea8db89056429721e4c..e0e1262550830c2c22fe3ca473efa823ba01b603 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 e0b1eaafc916d40a00f5b74023843bccebd0b2f7..e84d4a3faa27139b11d98691910615b2c9cb3d1d 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 4dcf0cef9ce39e0561877ffcb30a8c28ad35bbfc..95690bde478b3e6df01806d56d4e5c389bbdd7c3 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 cdeaf9c41738c9c84f51feea3831347fbe4e3f3c..0f268a9d1aa515cdd11712b6b734b52af57c639a 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 2dfd26edb0d9a5d5d03e0976a6dbf06e2cf6dd67..9f7e76f18e6035e9b9e555111e5bba62e197b67a 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 9dba0c735097d3e08ad6edbc4fe609266e2dc649..399cec36c76740e01eb5e0ea67cccdf27a15c69b 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 229907fbb89d3f3d0026e2f36b200cedee97712c..2becb69d5a209b22f84a08f67b04d92e3d518992 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 dca258421b9ff685a462d06d83c386813559e9d5..0f7e0e4f2eab6d5c45de75ad0fc524bb245740cd 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 d869b600c9093ec2c98af15edf18e9a908d576d4..a8e24dd83941c149eda112d94e20dd7297e4bf85 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 d7603e58d1a746771ad4e3cf5df209d135d5777f..49d3bf93e19d38c6fde6effbd814cf215fc9f1d0 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 b7e216bfe2bfb23b30836b1ea9064565619e1176..4f3e50c31a08b8357793359c6fbd257c804de0bf 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 1ed00ae655780124a1ada2b45854237a2d818c63..5c9e3a5223ff821d6126a525a9088f9b04224555 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 9c7c49ac58711654ec173ebe22184a957cbe6d47..e39cc70185e2c28092c237dfa6356792ac5449f8 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 01e7409801aa769cedaa2e1e102f47ac58dd80d0..88c1daaf234dcc00869a2ccf5ac034f84a1ee044 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 44f4f065a60009e831b14d62ef2dde3d71e4384d..a3fee91a36504e387f11ba9608aae3678a05ec0b 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 67f141d458f69477ed7c99194650c201dda89395..5085b12527b7192eb25cbf5e330c2a291ed0cfc8 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 bdb41b2d2c2d5f0c43221bf37a37b426203074d7..a342644516cbb8194158364c5366ef40e73da3b1 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 d760d90ef1ba5a42a0dc572d653a96af21760a93..e01009b7aa2111ac52cdeb56cb8da8f1c79d9162 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 5dcb67474fe755651008b37b7d08e4558afc8526..61a0667080cb070ce787fc95be816de169c2e131 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 b6f0d1b7059b4a03fcdaceef8e6957972bb1c4d0..416e963356b363cc5c1d1408aa826a4e0b0de8f0 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 1765577d4514729d44deea9fdd6b9f4d16562610..0162d536656ad89bd56ebdeb28b95e4b5ecf2397 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 5fdfa5f2630362bd42a5e9bfc46d6ac695518be4..c16a928a80cc3931f75bc507ccc9cbc8fac44c31 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 ae8d9ae4de69fb20f6c31daf8f39c96466af4da9..a0c05df9834b90035f8bf7023ee6d3af3d12be11 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 1d5c3aa1d384cdc3d7912c5f989fdf163906762f..fd98ef5604e748a7227a38f9b9302fab4dc3ee6c 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 84572815c01841a33b30e6257471517b7a4aae6d..2c54c6f71f86d7f5c8fa8ca720a50ca989818670 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 280e6a903b0a7e6b059b11e8b583f871bb2850f4..0db431b083111de8880864e1f34d974882e31a60 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 9517e3a5c8a2f01b75b45dd67e15a96d13d8760f..119a75b6507bae2d28dec4f39ecd21fe527792ac 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 fbbe43f2c0c4cda8cb64ef109da79952d19b8336..640d940d91af1d557059b534dafc37a42658e01f 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 a223dee319462eaf5a5f12bde7ad3f0af1706dc0..b69bbd575f13633711484ac675fb3a4c36fe14f1 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 000653ea5c092b6747bcc0fd6a7f0b5fa5810aae..8472f79948de00dd9e9da24b7ce5a96e777c5643 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 25d708e71ac611ea2d68846ae7d2d4a47f7b5e7d..eaaeba976cf36244f4e8d6516ba58c4433a0e77c 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 6369bb897605aa7b82f3221ec91b7f64bb90c8ac..ba9120a77d7c4f61b39ecd794d4f0cfbf878599b 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 6efb2ce2907198a1568eea16528dbdd18b85a3ee..b0306ab832d69506c93cc16f5d2e3f175931a2cd 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 5de5528b1ddf5edfd3b0022c92974c79191b3935..0b8d6afe5569dc1f9f7910d387ae79f6b0afcece 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 9f1324313eea8e899c09f6a5cba271337c9135ad..9e1fee5b6bb9f6843ea96dd7f35da1f5852906ea 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 35de23ebfa1a69c5ea8dd1ef981352e16ffe0a7e..d4210f698831f4964209588ad71815851fc48fb7 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 828490fd9c53108a1f125827b4b66d0bcfee029d..ab5b375ae41474346f7ec643e01b7daa0490eb0c 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 e317b8ab9431c53fba985a15e3daf254f0d4cc38..2c937d85c59fcd2516b5391c65537e3f087f2c4d 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;