perf: optimizing page transition (#178)

* perf: optimizing page transition

* fix: minor fixes
This commit is contained in:
saica.go
2024-09-13 20:14:03 +08:00
committed by GitHub
parent f5ad1c643d
commit f0754cae3f
9 changed files with 149 additions and 78 deletions

View File

@@ -58,6 +58,14 @@ if (!lang) {
lang = `${siteConfig.lang}`
}
const siteLang = lang.replace('_', '-')
const bannerOffsetByPosition = {
'top': '30vh',
'center': '15vh',
'bottom': '0'
}
const bannerOffset = bannerOffsetByPosition[siteConfig.banner.position || 'center']
---
<!DOCTYPE html>
@@ -117,17 +125,20 @@ const siteLang = lang.replace('_', '-')
<style define:vars={{ configHue }}></style> <!-- defines global css variables. This will be applied to <html> <body> and some other elements idk why -->
</head>
<body class=" min-h-screen transition " class:list={[{"is-home": isHomePage, "enable-banner": enableBanner}]}>
<body class=" min-h-screen transition " class:list={[{"lg:is-home": isHomePage, "enable-banner": enableBanner}]}>
<ConfigCarrier></ConfigCarrier>
<GlobalStyles>
<div id="banner-wrapper" class="absolute w-full transition-all duration-700">
<ImageWrapper id="boxtest" alt="Banner image of the blog" class:list={["object-cover h-full", {"hidden": !siteConfig.banner.enable}]}
{siteConfig.banner.enable && <div id="banner-wrapper" class="absolute -top-[30vh] w-full transition duration-700 overflow-hidden">
<ImageWrapper id="banner" alt="Banner image of the blog" class:list={["object-cover h-full transition duration-700"]}
src={siteConfig.banner.src} position={siteConfig.banner.position}
>
</ImageWrapper>
</div>
</div>}
<slot />
</GlobalStyles>
<!-- increase the page height during page transition to prevent the scrolling animation from jumping -->
<div id="page-height-extend" class="hidden h-[300vh]"></div>
</body>
</html>
<style is:global>
@@ -136,23 +147,35 @@ const siteLang = lang.replace('_', '-')
--page-width: 75rem;
}
</style>
<style is:global>
<style is:global define:vars={{ bannerOffset }}>
@tailwind components;
@tailwind utilities;
@layer components {
.enable-banner.is-home #banner-wrapper {
@apply h-[var(--banner-height)] md:h-[var(--banner-height-home)]
@apply h-[var(--banner-height-home)] translate-y-[30vh]
}
.enable-banner #banner-wrapper {
@apply h-[var(--banner-height)]
@apply h-[var(--banner-height-home)]
}
.enable-banner.is-home #top-row {
@apply h-[calc(var(--banner-height)_-_4.5rem)] md:h-[calc(var(--banner-height-home)_-_4.5rem)]
.enable-banner.is-home #banner {
@apply h-[var(--banner-height-home)] translate-y-0
}
.enable-banner #banner {
@apply h-[var(--banner-height-home)] translate-y-[var(--bannerOffset)]
}
.enable-banner.is-home #main-grid {
@apply translate-y-[30vh];
}
.enable-banner #top-row {
@apply h-[calc(var(--banner-height)_-_4.5rem)]
@apply h-[calc(var(--banner-height-home)_-_4.5rem)] transition-all duration-300
}
.enable-banner.is-home #sidebar-sticky {
@apply -top-[30vh]
}
.navbar-hidden {
@apply opacity-0 -translate-y-16
}
}
</style>
@@ -300,18 +323,47 @@ const setup = () => {
// Remove the delay for the first time page load
window.swup.hooks.on('link:click', () => {
document.documentElement.style.setProperty('--content-delay', '0ms')
// prevent elements from overlapping the navbar
let threshold = window.innerHeight * 0.30 - 72 - 16
let navbar = document.getElementById('navbar-wrapper')
if (!navbar || !document.body.classList.contains('lg:is-home')) {
return
}
if (document.body.scrollTop >= threshold || document.documentElement.scrollTop >= threshold) {
navbar.classList.add('navbar-hidden')
}
})
window.swup.hooks.on('content:replace', initCustomScrollbar)
window.swup.hooks.on('visit:start', (visit: {to: {url: string}}) => {
// change banner height immediately when a link is clicked
const bodyElement = document.querySelector('body')
if (pathsEqual(visit.to.url, url('/'))) {
bodyElement!.classList.add('is-home');
bodyElement!.classList.add('lg:is-home');
} else {
bodyElement!.classList.remove('is-home');
bodyElement!.classList.remove('lg:is-home');
}
// increase the page height during page transition to prevent the scrolling animation from jumping
const heightExtend = document.getElementById('page-height-extend')
if (heightExtend) {
heightExtend.classList.remove('hidden')
}
});
window.swup.hooks.on('page:view', () => {
// hide the temp high element when the transition is done
const heightExtend = document.getElementById('page-height-extend')
if (heightExtend) {
heightExtend.classList.remove('hidden')
}
});
window.swup.hooks.on('visit:end', (visit: {to: {url: string}}) => {
// execute 1s later
const heightExtend = document.getElementById('page-height-extend')
if (heightExtend) {
heightExtend.classList.add('hidden')
}
});
}
if (window?.swup?.hooks) {
setup()
@@ -319,6 +371,33 @@ if (window?.swup?.hooks) {
document.addEventListener('swup:enable', setup)
}
let backToTopBtn = document.getElementById('back-to-top-btn');
const bannerEnable = !!document.getElementById('banner-wrapper')
let navbar = document.getElementById('navbar-wrapper')
function scrollFunction() {
if (backToTopBtn) {
if (document.body.scrollTop > 600 || document.documentElement.scrollTop > 600) {
backToTopBtn.classList.remove('hide')
} else {
backToTopBtn.classList.add('hide')
}
}
if (!bannerEnable) return
if (navbar) {
let threshold = window.innerHeight * 0.30 - 72 - 16
if (document.body.classList.contains('lg:is-home') && window.innerWidth >= 1024) {
threshold = window.innerHeight * 0.60 - 72 - 16
}
if (document.body.scrollTop >= threshold || document.documentElement.scrollTop >= threshold) {
navbar.classList.add('navbar-hidden')
} else {
navbar.classList.remove('navbar-hidden')
}
}
}
window.onscroll = scrollFunction
</script>
<script>
@@ -382,14 +461,3 @@ if (window.swup) {
document.addEventListener("swup:enable", setup)
}
</script>
<style is:global lang="stylus">
#banner-wrapper
top: 0
opacity: 1
.banner-closed
#banner-wrapper
top: -120px
opacity: 0
</style>