performance

This commit is contained in:
tangly1024
2023-03-11 12:33:21 +08:00
parent f75103699f
commit f94bcde757
24 changed files with 150 additions and 168 deletions

View File

@@ -69,7 +69,7 @@ export function DebugPanel() {
{/* 调试侧拉抽屉 */}
<div
className={` ${show ? 'shadow-card w-96 right-0 ' : '-right-96 w-0'} overflow-y-scroll h-full p-5 bg-white fixed bottom-0 z-50 duration-200`}
className={` ${show ? 'shadow-card w-96 right-0 ' : '-right-96 invisible w-0'} overflow-y-scroll h-full p-5 bg-white fixed bottom-0 z-50 duration-200`}
>
<div className="flex justify-between space-x-1 my-5">
<div className='flex'>

View File

@@ -52,7 +52,6 @@ const Tabs = ({ className, children }) => {
return <section key={index}
data-aos="fade-up"
data-aos-duration="300"
data-aos-easing="ease-in-out"
data-aos-once="true"
data-aos-anchor-placement="top-bottom">
{currentTab === index && item}

View File

@@ -1,5 +1,5 @@
import BLOG from 'blog.config'
import React from 'react'
import React, { useEffect } from 'react'
import dynamic from 'next/dynamic'
import 'animate.css'
@@ -20,7 +20,6 @@ import { Sakura } from '@/components/Sakura'
import { StarrySky } from '@/components/StarrySky'
import MusicPlayer from '@/components/MusicPlayer'
import ExternalScript from '@/components/ExternalScript'
import { isBrowser } from '@/lib/utils'
import smoothscroll from 'smoothscroll-polyfill'
import AOS from 'aos'
@@ -56,10 +55,10 @@ const MyApp = ({ Component, pageProps }) => {
<ExternalScript/>
</>
if (isBrowser()) {
useEffect(() => {
AOS.init()
smoothscroll.polyfill()
}
})
return (
<GlobalContextProvider>

View File

@@ -2,7 +2,6 @@ const Card = ({ children, headerSlot, className }) => {
return <div className={className}
data-aos="fade-up"
data-aos-duration="300"
data-aos-easing="ease-in-out"
data-aos-once="false"
data-aos-anchor-placement="top-bottom"
>

View File

@@ -27,7 +27,7 @@ const FacebookPage = dynamic(
*/
const LayoutBase = props => {
const { children, headerSlot, floatSlot, meta, siteInfo } = props
const [show, switchShow] = useState(false)
const [showFloatButton, switchShow] = useState(false)
// const [percent, changePercent] = useState(0) // 页面阅读百分比
const rightAreaSlot = (
<>
@@ -47,7 +47,7 @@ const LayoutBase = props => {
if (per > 100) per = 100
const shouldShow = scrollY > 100 && per > 0
if (shouldShow !== show) {
if (shouldShow !== showFloatButton) {
switchShow(shouldShow)
}
// changePercent(per)
@@ -56,7 +56,7 @@ const LayoutBase = props => {
useEffect(() => {
document.addEventListener('scroll', scrollListener)
return () => document.removeEventListener('scroll', scrollListener)
}, [show])
}, [])
return (
<div id='theme-hexo' className="bg-hexo-background-gray dark:bg-black">
@@ -79,7 +79,7 @@ const LayoutBase = props => {
</main>
{/* 右下角悬浮 */}
<div className={(show ? 'opacity-100 ' : 'invisible opacity-0') + ' duration-300 transition-all bottom-12 right-1 fixed justify-end z-20 text-white bg-indigo-500 dark:bg-hexo-black-gray rounded-sm'}>
<div className={(showFloatButton ? 'opacity-100 ' : 'invisible opacity-0') + ' duration-300 transition-all bottom-12 right-1 fixed justify-end z-20 text-white bg-indigo-500 dark:bg-hexo-black-gray rounded-sm'}>
<div className={'justify-center flex flex-col items-center cursor-pointer'}>
<FloatDarkModeButton />
{floatSlot}

View File

@@ -9,7 +9,6 @@ const Announcement = ({ post, className }) => {
return <div
data-aos="fade-up"
data-aos-duration="300"
data-aos-easing="ease-in-out"
data-aos-once="false"
data-aos-anchor-placement="top-bottom"
className={className}>

View File

@@ -15,11 +15,11 @@ const BlogPostCard = ({ post, showSummary, siteInfo }) => {
<div
key={post.id}
data-aos="fade-up"
data-aos-duration="150"
data-aos-once="false"
data-aos-duration="200"
data-aos-once="true"
data-aos-anchor-placement="top-bottom"
className={`flex md:flex-row flex-col-reverse ${CONFIG_HEXO.POST_LIST_IMG_CROSSOVER ? 'even:md:flex-row-reverse' : ''}
w-full md:h-72 h-96 justify-between overflow-hidden drop-shadow-md
w-full md:h-72 h-96 justify-between overflow-hidden shadow-md
border dark:border-black rounded-xl bg-white dark:bg-hexo-black-gray`}>
<div className={`lg:p-8 p-4 flex flex-col ${showPageCover ? 'md:w-7/12 w-full' : 'w-full'}`}>

View File

@@ -1,7 +1,7 @@
const Card = ({ children, headerSlot, className }) => {
return <div className={className}>
<>{headerSlot}</>
<section className=" drop-shadow-md hover:shadow-md dark:text-gray-300 border dark:border-black rounded-xl px-2 py-4 bg-white dark:bg-hexo-black-gray lg:duration-100">
<section className="shadow-md hover:shadow-md dark:text-gray-300 border dark:border-black rounded-xl px-2 py-4 bg-white dark:bg-hexo-black-gray lg:duration-100">
{children}
</section>
</div>

View File

@@ -18,18 +18,32 @@ let windowTop = 0
* @returns
*/
const TopNav = props => {
const searchDrawer = useRef()
const { tags, currentTag, categories, currentCategory } = props
const { locale } = useGlobal()
const searchDrawer = useRef()
const { isDarkMode } = useGlobal()
const router = useRouter()
const [isOpen, changeShow] = useState(false)
const toggleMenuOpen = () => {
changeShow(!isOpen)
}
// 监听滚动
useEffect(() => {
scrollTrigger()
window.addEventListener('scroll', scrollTrigger)
return () => {
window.removeEventListener('scroll', scrollTrigger)
}
}, [])
const scrollTrigger = () => {
requestAnimationFrame(() => {
const scrollS = window.scrollY
const nav = document.querySelector('#sticky-nav')
const header = document.querySelector('#header')
const showNav = scrollS <= windowTop || scrollS < 5 || (header && scrollS <= header.clientHeight)// 非首页无大图时影藏顶部 滚动条置顶时隐藏
// 是否将导航栏透明
const navTransparent = (scrollS < document.documentElement.clientHeight - 12 && router.route === '/') || scrollS < 300 // 透明导航条的条件
@@ -47,6 +61,7 @@ const TopNav = props => {
nav && nav.classList.replace('transparent', 'dark:bg-hexo-black-gray')
}
const showNav = scrollS <= windowTop || scrollS < 5 || (header && scrollS <= header.clientHeight)// 非首页无大图时影藏顶部 滚动条置顶时隐藏
if (!showNav) {
nav && nav.classList.replace('top-0', '-top-20')
windowTop = scrollS
@@ -70,21 +85,6 @@ const TopNav = props => {
}
}
const [isOpen, changeShow] = useState(false)
const toggleMenuOpen = () => {
changeShow(!isOpen)
}
// 监听滚动
useEffect(() => {
scrollTrigger()
window.addEventListener('scroll', scrollTrigger)
return () => {
window.removeEventListener('scroll', scrollTrigger)
}
}, [])
const searchDrawerSlot = <>
{categories && (
<section className='mt-8'>
@@ -127,7 +127,7 @@ const TopNav = props => {
<SearchDrawer cRef={searchDrawer} slot={searchDrawerSlot} />
{/* 导航栏 */}
<div id='sticky-nav' className={'top-0 shadow-none fixed bg-none dark:bg-hexo-black-gray dark:text-gray-200 text-black w-full z-20 transform transition-all duration-200 border-transparent dark:border-transparent'}>
<div id='sticky-nav' className={'top-0 duration-200 transition-all shadow-none fixed bg-none dark:bg-hexo-black-gray dark:text-gray-200 text-black w-full z-20 transform border-transparent dark:border-transparent'}>
<div className='w-full flex justify-between items-center px-4 py-2'>
<div className='flex'>
<Logo {...props} />

View File

@@ -23,14 +23,14 @@ const LayoutBase = props => {
const scrollListener = () => {
requestAnimationFrame(() => {
const targetRef = document.getElementById('wrapper')
const clientHeight = targetRef?.clientHeight
// const targetRef = document.getElementById('wrapper')
// const clientHeight = targetRef?.clientHeight
const scrollY = window.pageYOffset
const fullHeight = clientHeight - window.outerHeight
let per = parseFloat(((scrollY / fullHeight) * 100).toFixed(0))
if (per > 100) per = 100
const shouldShow = scrollY > 300 && per > 0
// const fullHeight = clientHeight - window.outerHeight
// let per = parseFloat(((scrollY / fullHeight) * 100).toFixed(0))
// if (per > 100) per = 100
const shouldShow = scrollY > 300
console.log(scrollY)
if (shouldShow !== show) {
switchShow(shouldShow)
}
@@ -40,7 +40,7 @@ const LayoutBase = props => {
useEffect(() => {
document.addEventListener('scroll', scrollListener)
return () => document.removeEventListener('scroll', scrollListener)
}, [show])
}, [])
return (
<div id='theme-matery' className="min-h-screen flex flex-col justify-between bg-hexo-background-gray dark:bg-black w-full">
@@ -67,12 +67,8 @@ const LayoutBase = props => {
</div>
{/* 右下角悬浮 */}
<div className="bottom-12 right-2 fixed justify-end z-20">
<div className={
(show ? 'animate__animated ' : 'hidden') +
' animate__fadeInUp justify-center duration-300 animate__faster flex flex-col items-center cursor-pointer '
}
>
<div className={ (show ? ' opacity-100 fixed ' : ' hidden opacity-0 ') + ' transition-all duration-200 bottom-12 right-2 justify-end z-20' }>
<div className= ' justify-center flex flex-col items-center cursor-pointer '>
<JumpToTopButton />
</div>
</div>

View File

@@ -1,4 +1,4 @@
import React from 'react'
import React, { useEffect } from 'react'
import { ArticleLock } from './components/ArticleLock'
import HeaderArticle from './components/HeaderArticle'
import LayoutBase from './LayoutBase'
@@ -16,16 +16,18 @@ export const LayoutSlug = props => {
const [show, switchShow] = React.useState(false)
const scrollListener = () => {
const scrollY = window.pageYOffset
const shouldShow = scrollY > 220 && post?.toc?.length > 0
if (shouldShow !== show) {
switchShow(shouldShow)
}
requestAnimationFrame(() => {
const scrollY = window.pageYOffset
const shouldShow = scrollY > 220 && post?.toc?.length > 0
if (shouldShow !== show) {
switchShow(shouldShow)
}
})
}
React.useEffect(() => {
useEffect(() => {
document.addEventListener('scroll', scrollListener)
return () => document.removeEventListener('scroll', scrollListener)
}, [show])
}, [])
if (!post) {
return <LayoutBase
@@ -36,98 +38,92 @@ export const LayoutSlug = props => {
></LayoutBase>
}
return (
<LayoutBase
headerSlot={<HeaderArticle {...props} />}
{...props}
showCategory={false}
showTag={false}
>
return (<LayoutBase
headerSlot={<HeaderArticle {...props} />}
{...props}
showCategory={false}
showTag={false}
>
<div id='inner-wrapper'>
<div className={'drop-shadow-xl w-full lg:max-w-3xl 2xl:max-w-4xl'}>
<div className="-mt-32 rounded-md mx-3 lg:border lg:rounded-xl lg:py-4 bg-white dark:bg-hexo-black-gray dark:border-black">
{lock && <ArticleLock validPassword={validPassword} />}
<div id='inner-wrapper'>
<div className={'w-full lg:max-w-3xl 2xl:max-w-4xl'}>
<div className="-mt-32 shadow-md rounded-md mx-3 lg:border lg:rounded-xl lg:py-4 bg-white dark:bg-hexo-black-gray dark:border-black">
{lock && <ArticleLock validPassword={validPassword} />}
{!lock && <div id="container" className="overflow-x-auto md:w-full px-3 ">
{ post?.type && post?.type === 'Post' && <>
<div
data-aos="fade-down"
data-aos-duration="500"
data-aos-easing="ease-in-out"
data-aos-once="false"
data-aos-anchor-placement="top-center"
className='px-10'>
<ArticleInfo post={post} />
</div>
<hr />
</>}
<div className='lg:px-10 '>
<article itemScope itemType="https://schema.org/Movie" className="subpixel-antialiased overflow-y-hidden" >
{/* Notion文章主体 */}
<section id='notion-article'
data-aos-delay="200"
data-aos="fade-down"
data-aos-duration="500"
data-aos-easing="ease-in-out"
data-aos-once="false"
data-aos-anchor-placement="top-bottom"
className='justify-center mx-auto max-w-2xl lg:max-w-full'>
{post && <NotionPage post={post} />}
</section>
<section className="px-1 py-2 my-1 text-sm font-light overflow-auto text-gray-600 dark:text-gray-400">
{/* 文章内嵌广告 */}
<ins className="adsbygoogle"
style={{ display: 'block', textAlign: 'center' }}
data-adtest="on"
data-ad-layout="in-article"
data-ad-format="fluid"
data-ad-client="ca-pub-2708419466378217"
data-ad-slot="3806269138" />
</section>
{post.type === 'Post' && <ArticleCopyright {...props} />}
</article>
<hr className='border-dashed' />
{/* 评论互动 */}
<div className="duration-200 overflow-x-auto dark:bg-hexo-black-gray px-3">
<Comment frontMatter={post} />
</div>
{!lock && <div id="container" className="overflow-x-auto md:w-full px-3 ">
{post?.type && post?.type === 'Post' && <>
<div
data-aos="fade-down"
data-aos-duration="100"
data-aos-once="false"
data-aos-anchor-placement="top-center"
className='px-10'>
<ArticleInfo post={post} />
</div>
<hr />
</>}
</div>}
</div>
{post.type === 'Post' && <ArticleAdjacent {...props} />}
<div className='lg:px-10 subpixel-antialiased'>
<article itemScope >
{/* Notion文章主体 */}
<section id='notion-article' className='justify-center mx-auto max-w-2xl lg:max-w-full'>
{post && <NotionPage post={post} />}
</section>
{post?.toc?.length > 0 && <div id='toc-wrapper' style={{ zIndex: '-1' }} className='absolute top-0 w-full h-full xl:block hidden' >
<div data-aos-delay="200"
data-aos="fade-down"
data-aos-duration="500"
data-aos-easing="ease-in-out"
data-aos-once="false"
data-aos-anchor-placement="top-center"
className='relative h-full'>
<div className='float-right xl:-mr-72 xl:w-72 w-56 -mr-56 h-full mt-40'>
<div className='sticky top-24'>
<Catalog toc={post.toc} />
</div>
<section className="px-1 py-2 my-1 text-sm font-light overflow-auto text-gray-600 dark:text-gray-400">
{/* 文章内嵌广告 */}
<ins className="adsbygoogle"
style={{ display: 'block', textAlign: 'center' }}
data-adtest="on"
data-ad-layout="in-article"
data-ad-format="fluid"
data-ad-client="ca-pub-2708419466378217"
data-ad-slot="3806269138" />
</section>
{/* 文章版权说明 */}
{post.type === 'Post' && <ArticleCopyright {...props} />}
</article>
<hr className='border-dashed' />
{/* 评论互动 */}
<div className="overflow-x-auto dark:bg-hexo-black-gray px-3">
<Comment frontMatter={post} />
</div>
</div>
</div>}
</div>
<div className='fixed bottom-28 right-4'>
<JumpToCommentButton />
</div>
{/* 文章推荐 */}
{post.type === 'Post' && <ArticleAdjacent {...props} />}
{/* 文章目录 */}
{post?.toc?.length > 0 && <div id='toc-wrapper' style={{ zIndex: '-1' }} className='absolute top-0 w-full h-full xl:block hidden lg:max-w-3xl 2xl:max-w-4xl' >
<div data-aos-delay="200"
data-aos="fade-down"
data-aos-duration="200"
data-aos-once="true"
data-aos-anchor-placement="top-center"
className='relative h-full'>
<div className='float-right xl:-mr-72 xl:w-72 w-56 -mr-56 h-full mt-40'>
<div className='sticky top-24'>
<Catalog toc={post.toc} />
</div>
</div>
</div>
</div>}
</div>
</LayoutBase>
<div className='fixed bottom-28 right-4'>
<JumpToCommentButton />
</div>
</div>
</LayoutBase>
)
}

View File

@@ -15,10 +15,9 @@ const BlogPostCard = ({ post, showSummary, siteInfo }) => {
<div
data-aos="zoom-in"
data-aos-duration="300"
data-aos-easing="ease-in-out"
data-aos-once="true"
data-aos-once="false"
data-aos-anchor-placement="top-bottom"
className="w-full mb-4 h-full overflow-auto drop-shadow-md border dark:border-black rounded-xl bg-white dark:bg-hexo-black-gray">
className="w-full mb-4 h-full overflow-auto shadow-md border dark:border-black rounded-xl bg-white dark:bg-hexo-black-gray">
{/* 固定高度 ,空白用图片拉升填充 */}
<div key={post.id} className="flex flex-col h-96 justify-between">

View File

@@ -42,10 +42,10 @@ const BlogPostListScroll = ({ posts = [], currentSearch, showSummary = CONFIG_MA
// 监听滚动
React.useEffect(() => {
window.addEventListener('scroll', scrollTrigger)
return () => {
window.removeEventListener('scroll', scrollTrigger)
}
// window.addEventListener('scroll', scrollTrigger)
// return () => {
// window.removeEventListener('scroll', scrollTrigger)
// }
})
const targetRef = React.useRef(null)

View File

@@ -13,8 +13,8 @@ const Catalog = ({ toc }) => {
const { locale } = useGlobal()
// 监听滚动事件
React.useEffect(() => {
window.addEventListener('scroll', actionSectionScrollSpy)
actionSectionScrollSpy()
window.addEventListener('scroll', actionSectionScrollSpy)
return () => {
window.removeEventListener('scroll', actionSectionScrollSpy)
}

View File

@@ -32,13 +32,14 @@ const Header = props => {
if (enableAutoScroll) {
scrollTrigger()
window.addEventListener('scroll', scrollTrigger)
} window.addEventListener('resize', updateHeaderHeight)
}
window.addEventListener('resize', updateHeaderHeight)
return () => {
if (enableAutoScroll) {
window.removeEventListener('scroll', scrollTrigger)
} window.removeEventListener('resize', updateHeaderHeight)
}
})
}, [])
const autoScrollEnd = () => {
if (autoScroll) {

View File

@@ -4,8 +4,7 @@ export default function HeaderArticle({ post, siteInfo }) {
return (
<div
data-aos="fade-down"
data-aos-duration="500"
data-aos-easing="ease-in-out"
data-aos-duration="300"
data-aos-once="false"
data-aos-anchor-placement="top-center"
id='header' className="flex h-96 justify-center align-middle items-center w-full relative duration-200 bg-black">

View File

@@ -10,16 +10,18 @@ const Progress = ({ targetRef, showPercent = true }) => {
const currentRef = targetRef?.current || targetRef
const [percent, changePercent] = useState(0)
const scrollListener = () => {
const target = currentRef || (isBrowser() && document.getElementById('container'))
if (target) {
const clientHeight = target.clientHeight
const scrollY = window.pageYOffset
const fullHeight = clientHeight - window.outerHeight
let per = parseFloat(((scrollY / fullHeight) * 100).toFixed(0))
if (per > 100) per = 100
if (per < 0) per = 0
changePercent(per)
}
requestAnimationFrame(() => {
const target = currentRef || (isBrowser() && document.getElementById('container'))
if (target) {
const clientHeight = target.clientHeight
const scrollY = window.pageYOffset
const fullHeight = clientHeight - window.outerHeight
let per = parseFloat(((scrollY / fullHeight) * 100).toFixed(0))
if (per > 100) per = 100
if (per < 0) per = 0
changePercent(per)
}
})
}
useEffect(() => {

View File

@@ -46,7 +46,6 @@ const LayoutBase = props => {
<div
data-aos="fade-up"
data-aos-duration="300"
data-aos-easing="ease-in-out"
data-aos-once="false"
data-aos-anchor-placement="top-center"
className='fixed xl:right-80 right-2 mr-10 bottom-24 hidden lg:block z-20'>

View File

@@ -15,7 +15,6 @@ const BlogPostCard = ({ post, showSummary }) => {
key={post.id}
data-aos="fade-up"
data-aos-duration="300"
data-aos-easing="ease-in-out"
data-aos-once="false"
data-aos-anchor-placement="top-bottom"
className="mb-6 max-w-7xl border-b dark:border-gray-800 "

View File

@@ -29,7 +29,6 @@ export default function ArticleDetail(props) {
<div id="container"
data-aos="fade-down"
data-aos-duration="300"
data-aos-easing="ease-in-out"
data-aos-once="true"
data-aos-anchor-placement="top-bottom"

View File

@@ -2,7 +2,6 @@ const Card = ({ children, headerSlot, className }) => {
return <div
data-aos="fade-down"
data-aos-duration="300"
data-aos-easing="ease-in-out"
data-aos-once="true"
data-aos-anchor-placement="top-bottom"
className={className}>

View File

@@ -19,7 +19,6 @@ const PaginationNumber = ({ page, totalPage }) => {
<div
data-aos="fade-down"
data-aos-duration="300"
data-aos-easing="ease-in-out"
data-aos-once="false"
data-aos-anchor-placement="top-bottom"
className="my-5 flex justify-center items-end font-medium text-black hover:shadow-xl duration-500 bg-white dark:bg-hexo-black-gray dark:text-gray-300 py-3 shadow space-x-2">
@@ -62,7 +61,7 @@ const PaginationNumber = ({ page, totalPage }) => {
</div>
</Link>
</div>
);
)
}
function getPageElement(pagePrefix, page, currentPage) {
@@ -81,7 +80,7 @@ function getPageElement(pagePrefix, page, currentPage) {
{page}
</Link>)
);
)
}
function generatePages(pagePrefix, page, currentPage, totalPage) {
const pages = []

View File

@@ -18,7 +18,6 @@ const PaginationSimple = ({ page, showNext }) => {
<div
data-aos="fade-down"
data-aos-duration="300"
data-aos-easing="ease-in-out"
data-aos-once="false"
data-aos-anchor-placement="top-bottom"
className="my-10 flex justify-between font-medium text-black dark:text-gray-100 space-x-2">
@@ -58,7 +57,7 @@ const PaginationSimple = ({ page, showNext }) => {
</button>
</Link>
</div>
);
)
}
export default PaginationSimple

View File

@@ -28,7 +28,6 @@ const SideAreaLeft = props => {
<section
data-aos="fade-down"
data-aos-duration="300"
data-aos-easing="ease-in-out"
data-aos-once="false"
data-aos-anchor-placement="top-bottom"
className='w-60'>