performance

This commit is contained in:
tangly1024
2023-07-20 22:49:23 +08:00
parent 0c7a42cfbc
commit 40d10041e6
6 changed files with 51 additions and 126 deletions

View File

@@ -2,7 +2,7 @@ import BLOG from '@/blog.config'
import BlogPostCard from './BlogPostCard'
import BlogPostListEmpty from './BlogPostListEmpty'
import { useGlobal } from '@/lib/global'
import React from 'react'
import React, { useEffect, useRef, useState } from 'react'
import CONFIG from '../config'
import { getListByPage } from '@/lib/utils'
@@ -15,7 +15,7 @@ import { getListByPage } from '@/lib/utils'
*/
const BlogPostListScroll = ({ posts = [], currentSearch, showSummary = CONFIG.POST_LIST_SUMMARY, siteInfo }) => {
const postsPerPage = BLOG.POSTS_PER_PAGE
const [page, updatePage] = React.useState(1)
const [page, updatePage] = useState(1)
const postsToShow = getListByPage(posts, page, postsPerPage)
let hasMore = false
@@ -41,14 +41,14 @@ const BlogPostListScroll = ({ posts = [], currentSearch, showSummary = CONFIG.PO
}
// 监听滚动
React.useEffect(() => {
useEffect(() => {
window.addEventListener('scroll', scrollTrigger)
return () => {
window.removeEventListener('scroll', scrollTrigger)
}
})
const targetRef = React.useRef(null)
const targetRef = useRef(null)
const { locale } = useGlobal()
if (!postsToShow || postsToShow.length === 0) {

View File

@@ -27,8 +27,8 @@ const Catalog = ({ toc }) => {
// 同步选中目录事件
const [activeSection, setActiveSection] = useState(null)
const throttleMs = 200
const actionSectionScrollSpy = useCallback(throttle(() => {
console.log('目录')
const sections = document.getElementsByClassName('notion-h')
let prevBBox = null
let currentSectionId = activeSection
@@ -53,7 +53,7 @@ const Catalog = ({ toc }) => {
setActiveSection(currentSectionId)
const index = tocIds.indexOf(currentSectionId) || 0
tRef?.current?.scrollTo({ top: 28 * index, behavior: 'smooth' })
}, throttleMs))
}, 200))
// 无目录就直接返回空
if (!toc || toc.length < 1) {

View File

@@ -26,23 +26,11 @@ const NavBar = props => {
slideOverRef?.current?.toggleSlideOvers()
}
// 监听滚动
useEffect(() => {
scrollTrigger()
window.addEventListener('scroll', scrollTrigger)
return () => {
window.removeEventListener('scroll', scrollTrigger)
}
}, [])
const throttleMs = 200
/**
* 根据滚动条,切换导航栏样式
*/
const scrollTrigger = useCallback(throttle(() => {
const scrollS = window.scrollY
// 导航栏设置 白色背景
if (scrollS <= 0) {
setFixedNav(false)
@@ -60,7 +48,16 @@ const NavBar = props => {
setTextWhite(false)
setBgWhite(true)
}
}, throttleMs))
}, 200))
// 监听滚动
useEffect(() => {
scrollTrigger()
window.addEventListener('scroll', scrollTrigger)
return () => {
window.removeEventListener('scroll', scrollTrigger)
}
}, [])
// 监听导航栏显示文字
useEffect(() => {

View File

@@ -1,44 +0,0 @@
import React, { useEffect, useState } from 'react'
import { isBrowser } from '@/lib/utils'
/**
* 顶部页面阅读进度条
* @returns {JSX.Element}
* @constructor
*/
const Progress = ({ targetRef, showPercent = true }) => {
const currentRef = targetRef?.current || targetRef
const [percent, changePercent] = useState(0)
const scrollListener = () => {
const target = currentRef || (isBrowser() && document.getElementById('article-wrapper'))
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(() => {
document.addEventListener('scroll', scrollListener)
return () => document.removeEventListener('scroll', scrollListener)
}, [])
return (
<div className="h-4 w-full shadow-2xl bg-gray-700 rounded-sm">
<div
className="h-4 bg-indigo-600 duration-200 rounded-sm"
style={{ width: `${percent}%` }}
>
{showPercent && (
<div className="text-right text-white text-xs">{percent}%</div>
)}
</div>
</div>
)
}
export default Progress

View File

@@ -7,36 +7,50 @@ import { useEffect, useState } from 'react'
*/
export default function ReadingProgress() {
const [scrollPercentage, setScrollPercentage] = useState(0)
function handleScroll() {
const scrollHeight = document.documentElement.scrollHeight
const clientHeight = document.documentElement.clientHeight
const scrollY = window.scrollY || window.pageYOffset
const percent = Math.floor((scrollY / (scrollHeight - clientHeight)) * 100)
setScrollPercentage(percent)
}
// 监听滚动事件
useEffect(() => {
let requestId
function handleScroll() {
const scrollHeight = document.documentElement.scrollHeight
const clientHeight = document.documentElement.clientHeight
const scrollY = window.scrollY || window.pageYOffset
const percent = Math.floor((scrollY / (scrollHeight - clientHeight)) * 100)
setScrollPercentage(percent)
requestId = requestAnimationFrame(handleScroll)
function updateScrollPercentage() {
handleScroll()
requestId = null
}
handleScroll() // 初始化滚动位置
function handleAnimationFrame() {
if (requestId) {
return
}
requestId = requestAnimationFrame(updateScrollPercentage)
}
window.addEventListener('scroll', handleAnimationFrame)
return () => {
cancelAnimationFrame(requestId)
window.removeEventListener('scroll', handleAnimationFrame)
if (requestId) {
cancelAnimationFrame(requestId)
}
}
}, [])
return (<>
<div title={'阅读进度'}
onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
className={`${scrollPercentage > 0 ? 'w-10 h-10 ' : 'w-0 h-0 opacity-0'} group cursor-pointer hover:bg-black hover:bg-opacity-10 rounded-full flex justify-center items-center duration-200 transition-all`} >
<ArrowSmallUp className={'w-5 h-5 hidden group-hover:block'} />
<div className='group-hover:hidden text-xs flex justify-center items-center rounded-full w-6 h-6 bg-black text-white'>
{scrollPercentage < 100 ? scrollPercentage : <ArrowSmallUp className={'w-5 h-5 fill-white'} />}
</div>
return (<div
title={'阅读进度'}
onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
className={`${scrollPercentage > 0 ? 'w-10 h-10 ' : 'w-0 h-0 opacity-0'} group cursor-pointer hover:bg-black hover:bg-opacity-10 rounded-full flex justify-center items-center duration-200 transition-all`}
>
<ArrowSmallUp className={'w-5 h-5 hidden group-hover:block'} />
<div className='group-hover:hidden text-xs flex justify-center items-center rounded-full w-6 h-6 bg-black text-white'>
{scrollPercentage < 100 ? scrollPercentage : <ArrowSmallUp className={'w-5 h-5 fill-white'} />}
</div>
</>)
</div>
)
}

View File

@@ -1,42 +0,0 @@
import throttle from 'lodash.throttle'
import { useCallback, useEffect, useState } from 'react'
import FloatDarkModeButton from './FloatDarkModeButton'
import JumpToTopButton from './JumpToTopButton'
/**
* 悬浮在右下角的按钮当页面向下滚动100px时会出现
* @param {*} param0
* @returns
*/
export default function RightFloatArea({ floatSlot }) {
const [showFloatButton, switchShow] = useState(false)
const scrollListener = useCallback(throttle(() => {
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 > 100 && per > 0
// 右下角显示悬浮按钮
if (shouldShow !== showFloatButton) {
switchShow(shouldShow)
}
}, 200))
useEffect(() => {
document.addEventListener('scroll', scrollListener)
return () => document.removeEventListener('scroll', scrollListener)
}, [])
return (
<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}
<JumpToTopButton />
</div>
</div>
)
}