perf: optimize katex config, implement async css loading for katex, improve scrollbar and lightbox loading logic

This commit is contained in:
radishzzz 2025-05-08 18:13:15 +01:00
parent 625879b061
commit 979f36a796
6 changed files with 66 additions and 60 deletions

View file

@ -18,6 +18,7 @@ import { remarkReadingTime } from './src/plugins/remark-reading-time.mjs'
const url = themeConfig.site.url const url = themeConfig.site.url
const locale = themeConfig.global.locale const locale = themeConfig.global.locale
const isKatexEnabled = themeConfig.global.katex
const linkPrefetch = themeConfig.preload.linkPrefetch const linkPrefetch = themeConfig.preload.linkPrefetch
const imageHostURL = themeConfig.preload.imageHostURL const imageHostURL = themeConfig.preload.imageHostURL
const imageConfig = imageHostURL const imageConfig = imageHostURL
@ -31,6 +32,28 @@ const imageConfig = imageHostURL
} }
: {} : {}
const remarkPlugins = [
remarkDirective,
...(isKatexEnabled ? [remarkMath] : []),
remarkAdmonitions,
remarkGithubCard,
remarkReadingTime,
]
const rehypePlugins = [
rehypeSlug,
...(isKatexEnabled ? [rehypeKatex] : []),
rehypeImgToFigure,
[
rehypeExternalLinks,
{
target: '_blank',
rel: ['nofollow', 'noopener', 'noreferrer', 'external'],
protocols: ['http', 'https', 'mailto'],
},
],
] as any[]
export default defineConfig({ export default defineConfig({
site: url, site: url,
base: '/', base: '/',
@ -61,26 +84,8 @@ export default defineConfig({
robotsTxt(), robotsTxt(),
], ],
markdown: { markdown: {
remarkPlugins: [ remarkPlugins,
remarkDirective, rehypePlugins,
remarkMath,
remarkAdmonitions,
remarkGithubCard,
remarkReadingTime,
],
rehypePlugins: [
rehypeSlug,
rehypeKatex,
rehypeImgToFigure,
[
rehypeExternalLinks,
{
target: '_blank',
rel: ['nofollow', 'noopener', 'noreferrer', 'external'],
protocols: ['http', 'https', 'mailto'],
},
],
],
shikiConfig: { shikiConfig: {
// Available themes: https://shiki.style/themes // Available themes: https://shiki.style/themes
themes: { themes: {

View file

@ -60,18 +60,6 @@ function initBackToTop() {
}) })
} }
function cleanup() {
// Cleanup observer
if (observer) {
observer.disconnect()
observer = null
}
// Remove event listeners
backToTopButton = null
}
// Handle page transitions // Handle page transitions
document.addEventListener('astro:page-load', initBackToTop) document.addEventListener('astro:page-load', initBackToTop)
document.addEventListener('astro:before-swap', cleanup)
</script> </script>

View file

@ -11,7 +11,7 @@ function setupGithubCards() {
observer.unobserve(entry.target) observer.unobserve(entry.target)
} }
}) })
}, { rootMargin: '200px' }) }, { rootMargin: '400px' })
githubCards.forEach(card => observer.observe(card)) githubCards.forEach(card => observer.observe(card))
} }

View file

@ -53,11 +53,13 @@ function setupPhotoSwipe() {
} }
function lazySetupPhotoSwipe() { function lazySetupPhotoSwipe() {
if ('requestIdleCallback' in window) { if (typeof window.requestIdleCallback === 'function') {
window.requestIdleCallback(() => setupPhotoSwipe(), { timeout: 1000 }) window.requestIdleCallback(() => setupPhotoSwipe(), { timeout: 1000 })
} }
else { else {
setTimeout(setupPhotoSwipe, 100) requestAnimationFrame(() => {
setupPhotoSwipe()
})
} }
} }

View file

@ -24,43 +24,54 @@ function setupScrollbar() {
bodyElement.setAttribute('data-scrollbar-initialized', 'true') bodyElement.setAttribute('data-scrollbar-initialized', 'true')
} }
// Add scrollbar to code blocks const setupSecondaryScrollbars = () => {
const preElements = document.querySelectorAll('pre') // Add scrollbar to TOC content
preElements.forEach((pre) => { const tocElement = document.getElementById('toc-content')
if (!pre.hasAttribute('data-scrollbar-initialized')) { if (tocElement && !tocElement.hasAttribute('data-scrollbar-initialized')) {
OverlayScrollbars({ OverlayScrollbars({
target: pre, target: tocElement,
}, { }, {
scrollbars: { scrollbars: {
theme: 'scrollbar-widget', theme: 'scrollbar-widget',
autoHide: 'leave', autoHide: 'never',
autoHideDelay: 500,
}, },
overflow: { overflow: {
y: 'hidden', x: 'hidden',
}, },
}) })
pre.setAttribute('data-scrollbar-initialized', 'true') tocElement.setAttribute('data-scrollbar-initialized', 'true')
} }
})
// Add scrollbar to TOC content // Add scrollbar to code blocks
const tocElement = document.getElementById('toc-content') const preElements = document.querySelectorAll('pre')
if (tocElement && !tocElement.hasAttribute('data-scrollbar-initialized')) { preElements.forEach((pre) => {
OverlayScrollbars({ if (!pre.hasAttribute('data-scrollbar-initialized')) {
target: tocElement, OverlayScrollbars({
}, { target: pre,
scrollbars: { }, {
theme: 'scrollbar-widget', scrollbars: {
autoHide: 'never', theme: 'scrollbar-widget',
}, autoHide: 'leave',
overflow: { autoHideDelay: 500,
x: 'hidden', },
}, overflow: {
y: 'hidden',
},
})
pre.setAttribute('data-scrollbar-initialized', 'true')
}
}) })
}
tocElement.setAttribute('data-scrollbar-initialized', 'true') if (typeof window.requestIdleCallback === 'function') {
window.requestIdleCallback(setupSecondaryScrollbars, { timeout: 1000 })
}
else {
requestAnimationFrame(() => {
setupSecondaryScrollbars()
})
} }
} }

View file

@ -54,7 +54,7 @@ const pageImage = postSlug
<link rel="preload" href="/fonts/EarlySummer-Subset.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/EarlySummer-Subset.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/fonts/Snell-Black.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/Snell-Black.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/fonts/Snell-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/Snell-Bold.woff2" as="font" type="font/woff2" crossorigin />
{katex && <link rel="stylesheet" href={katexCSS} />} {katex && <link rel="preload" href={katexCSS} as="style" onload="this.onload=null;this.rel='stylesheet'" />}
{commentURL && <link rel="preconnect" href={commentURL} crossorigin />} {commentURL && <link rel="preconnect" href={commentURL} crossorigin />}
{commentURL && <link rel="dns-prefetch" href={commentURL} />} {commentURL && <link rel="dns-prefetch" href={commentURL} />}
<link rel="alternate" href="/rss.xml" type="application/rss+xml" title="RSS Feed" /> <link rel="alternate" href="/rss.xml" type="application/rss+xml" title="RSS Feed" />