perf(frontend): introduce MkLazy for lazy loading
This commit is contained in:
		
							parent
							
								
									bd4d8694dd
								
							
						
					
					
						commit
						eacc2040a1
					
				
					 3 changed files with 65 additions and 3 deletions
				
			
		
							
								
								
									
										53
									
								
								packages/frontend/src/components/global/MkLazy.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								packages/frontend/src/components/global/MkLazy.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,53 @@
 | 
			
		|||
<!--
 | 
			
		||||
SPDX-FileCopyrightText: syuilo and other misskey contributors
 | 
			
		||||
SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
-->
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
<div ref="rootEl" :class="$style.root">
 | 
			
		||||
	<div v-if="!showing" :class="$style.placeholder"></div>
 | 
			
		||||
	<slot v-else></slot>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import { nextTick, onMounted, onActivated, onBeforeUnmount, ref, shallowRef } from 'vue';
 | 
			
		||||
 | 
			
		||||
const rootEl = shallowRef<HTMLDivElement>();
 | 
			
		||||
const showing = ref(false);
 | 
			
		||||
 | 
			
		||||
const observer = new IntersectionObserver(
 | 
			
		||||
	(entries) => {
 | 
			
		||||
		if (entries.some((entry) => entry.isIntersecting)) {
 | 
			
		||||
			showing.value = true;
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
	nextTick(() => {
 | 
			
		||||
		observer.observe(rootEl.value!);
 | 
			
		||||
	});
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
onActivated(() => {
 | 
			
		||||
	nextTick(() => {
 | 
			
		||||
		observer.observe(rootEl.value!);
 | 
			
		||||
	});
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
onBeforeUnmount(() => {
 | 
			
		||||
	observer.disconnect();
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" module>
 | 
			
		||||
.root {
 | 
			
		||||
	display: block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.placeholder {
 | 
			
		||||
	display: block;
 | 
			
		||||
	min-height: 150px;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -25,6 +25,7 @@ import MkPageHeader from './global/MkPageHeader.vue';
 | 
			
		|||
import MkSpacer from './global/MkSpacer.vue';
 | 
			
		||||
import MkFooterSpacer from './global/MkFooterSpacer.vue';
 | 
			
		||||
import MkStickyContainer from './global/MkStickyContainer.vue';
 | 
			
		||||
import MkLazy from './global/MkLazy.vue';
 | 
			
		||||
 | 
			
		||||
export default function(app: App) {
 | 
			
		||||
	for (const [key, value] of Object.entries(components)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -53,6 +54,7 @@ export const components = {
 | 
			
		|||
	MkSpacer: MkSpacer,
 | 
			
		||||
	MkFooterSpacer: MkFooterSpacer,
 | 
			
		||||
	MkStickyContainer: MkStickyContainer,
 | 
			
		||||
	MkLazy: MkLazy,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
declare module '@vue/runtime-core' {
 | 
			
		||||
| 
						 | 
				
			
			@ -77,5 +79,6 @@ declare module '@vue/runtime-core' {
 | 
			
		|||
		MkSpacer: typeof MkSpacer;
 | 
			
		||||
		MkFooterSpacer: typeof MkFooterSpacer;
 | 
			
		||||
		MkStickyContainer: typeof MkStickyContainer;
 | 
			
		||||
		MkLazy: typeof MkLazy;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -128,12 +128,18 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		|||
				</div>
 | 
			
		||||
				<MkInfo v-else-if="$i && $i.id === user.id">{{ i18n.ts.userPagePinTip }}</MkInfo>
 | 
			
		||||
				<template v-if="narrow">
 | 
			
		||||
					<XFiles :key="user.id" :user="user"/>
 | 
			
		||||
					<XActivity :key="user.id" :user="user"/>
 | 
			
		||||
					<MkLazy>
 | 
			
		||||
						<XFiles :key="user.id" :user="user"/>
 | 
			
		||||
					</MkLazy>
 | 
			
		||||
					<MkLazy>
 | 
			
		||||
						<XActivity :key="user.id" :user="user"/>
 | 
			
		||||
					</MkLazy>
 | 
			
		||||
				</template>
 | 
			
		||||
				<div v-if="!disableNotes">
 | 
			
		||||
					<div style="margin-bottom: 8px;">{{ i18n.ts.featured }}</div>
 | 
			
		||||
					<MkNotes :class="$style.tl" :noGap="true" :pagination="pagination"/>
 | 
			
		||||
					<MkLazy>
 | 
			
		||||
						<MkNotes :class="$style.tl" :noGap="true" :pagination="pagination"/>
 | 
			
		||||
					</MkLazy>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue