diff --git a/src/client/pages/note.vue b/src/client/pages/note.vue
index 77f15b8a49..b203a1322a 100644
--- a/src/client/pages/note.vue
+++ b/src/client/pages/note.vue
@@ -1,37 +1,37 @@
 <template>
 <div class="fcuexfpr _root">
-	<div v-if="note" class="note" v-anim>
-		<div class="_gap" v-if="showNext">
-			<XNotes class="_content" :pagination="next" :no-gap="true"/>
-		</div>
-
-		<div class="main _gap">
-			<MkButton v-if="!showNext && hasNext" class="load next" @click="showNext = true"><Fa :icon="faChevronUp"/></MkButton>
-			<div class="_content _gap">
-				<MkRemoteCaution v-if="note.user.host != null" :href="note.url || note.uri" class="_gap"/>
-				<XNoteDetailed v-model:note="note" :key="note.id" class="_gap"/>
+	<transition name="fade" mode="out-in">
+		<div v-if="note" class="note">
+			<div class="_gap" v-if="showNext">
+				<XNotes class="_content" :pagination="next" :no-gap="true"/>
 			</div>
-			<div class="_content clips _gap" v-if="clips && clips.length > 0">
-				<div class="title">{{ $ts.clip }}</div>
-				<MkA v-for="item in clips" :key="item.id" :to="`/clips/${item.id}`" class="item _panel _gap">
-					<b>{{ item.name }}</b>
-					<div v-if="item.description" class="description">{{ item.description }}</div>
-					<div class="user">
-						<MkAvatar :user="item.user" class="avatar"/> <MkUserName :user="item.user" :nowrap="false"/>
-					</div>
-				</MkA>
+
+			<div class="main _gap">
+				<MkButton v-if="!showNext && hasNext" class="load next" @click="showNext = true"><Fa :icon="faChevronUp"/></MkButton>
+				<div class="_content _gap">
+					<MkRemoteCaution v-if="note.user.host != null" :href="note.url || note.uri" class="_gap"/>
+					<XNoteDetailed v-model:note="note" :key="note.id" class="_gap"/>
+				</div>
+				<div class="_content clips _gap" v-if="clips && clips.length > 0">
+					<div class="title">{{ $ts.clip }}</div>
+					<MkA v-for="item in clips" :key="item.id" :to="`/clips/${item.id}`" class="item _panel _gap">
+						<b>{{ item.name }}</b>
+						<div v-if="item.description" class="description">{{ item.description }}</div>
+						<div class="user">
+							<MkAvatar :user="item.user" class="avatar"/> <MkUserName :user="item.user" :nowrap="false"/>
+						</div>
+					</MkA>
+				</div>
+				<MkButton v-if="!showPrev && hasPrev" class="load prev" @click="showPrev = true"><Fa :icon="faChevronDown"/></MkButton>
 			</div>
-			<MkButton v-if="!showPrev && hasPrev" class="load prev" @click="showPrev = true"><Fa :icon="faChevronDown"/></MkButton>
-		</div>
 
-		<div class="_gap" v-if="showPrev">
-			<XNotes class="_content" :pagination="prev" :no-gap="true"/>
+			<div class="_gap" v-if="showPrev">
+				<XNotes class="_content" :pagination="prev" :no-gap="true"/>
+			</div>
 		</div>
-	</div>
-
-	<div v-if="error">
-		<MkError @retry="fetch()"/>
-	</div>
+		<MkError v-else-if="error" @retry="fetch()"/>
+		<MkLoading v-else/>
+	</transition>
 </div>
 </template>
 
@@ -106,6 +106,7 @@ export default defineComponent({
 	},
 	methods: {
 		fetch() {
+			this.note = null;
 			os.api('notes/show', {
 				noteId: this.noteId
 			}).then(note => {
@@ -138,6 +139,15 @@ export default defineComponent({
 </script>
 
 <style lang="scss" scoped>
+.fade-enter-active,
+.fade-leave-active {
+	transition: opacity 0.125s ease;
+}
+.fade-enter-from,
+.fade-leave-to {
+	opacity: 0;
+}
+
 .fcuexfpr {
 	> .note {
 		> .main {
diff --git a/src/client/pages/user/index.vue b/src/client/pages/user/index.vue
index 2322b09ea9..630ac382b5 100644
--- a/src/client/pages/user/index.vue
+++ b/src/client/pages/user/index.vue
@@ -1,6 +1,6 @@
 <template>
-<div>
-	<div class="ftskorzw wide _section" v-if="user && narrow === false">
+<transition name="fade" mode="out-in">
+	<div class="ftskorzw wide" v-if="user && narrow === false">
 		<MkRemoteCaution v-if="user.host != null" :href="user.url" class="_gap"/>
 
 		<div class="banner-container _gap" :style="style">
@@ -212,10 +212,9 @@
 			<XPages v-else-if="page === 'pages'" :user="user" class="_gap"/>
 		</div>
 	</div>
-	<div v-else-if="error">
-		<MkError @retry="fetch()"/>
-	</div>
-</div>
+	<MkError v-else-if="error" @retry="fetch()"/>
+	<MkLoading v-else/>
+</transition>
 </template>
 
 <script lang="ts">
@@ -324,6 +323,7 @@ export default defineComponent({
 
 		fetch() {
 			if (this.acct == null) return;
+			this.user = null;
 			Progress.start();
 			os.api('users/show', parseAcct(this.acct)).then(user => {
 				this.user = user;
@@ -369,6 +369,15 @@ export default defineComponent({
 </script>
 
 <style lang="scss" scoped>
+.fade-enter-active,
+.fade-leave-active {
+	transition: opacity 0.125s ease;
+}
+.fade-enter-from,
+.fade-leave-to {
+	opacity: 0;
+}
+
 .ftskorzw.wide {
 	max-width: 1150px;
 	margin: 0 auto;