Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .commitlintrc.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
extends:
- '@commitlint/config-conventional'
- "@commitlint/config-conventional"
rules:
type-enum:
- 2
Expand Down
23 changes: 20 additions & 3 deletions components/elements/BackToTop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,29 @@ export default function BackToTop({ target }: Readonly<{ target: string }>) {
const [hasScrolled, setHasScrolled] = useState(false);

useEffect(() => {
/*
* ⚑ Bolt Optimization:
* - Throttles scroll events using requestAnimationFrame to prevent main-thread blocking and excessive re-renders.
* - Uses passive event listener to allow the browser to perform smooth scrolling without waiting for JS execution.
* Expected impact: Significant reduction in CPU usage and jank during fast scrolling.
*/
const state = { isTicking: false, tickingId: 0 };

const onScroll = () => {
setHasScrolled(window.scrollY > 100);
if (!state.isTicking) {
state.tickingId = window.requestAnimationFrame(() => {
setHasScrolled(window.scrollY > 100);
state.isTicking = false;
});
state.isTicking = true;
}
};

window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
window.addEventListener("scroll", onScroll, { passive: true });
return () => {
window.removeEventListener("scroll", onScroll);
window.cancelAnimationFrame(state.tickingId);
};
Comment on lines +14 to +30
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For improved readability and maintainability, I suggest a few refinements:

  • Extract Magic Number: The scroll threshold 100 is a magic number. Extracting it into a named constant like SCROLL_THRESHOLD_PX makes its purpose clear and simplifies future modifications.
  • Descriptive Naming: Renaming state to throttleState and tickingId to animationFrameId more accurately describes their roles within the throttling logic.

These changes make the implementation easier to understand at a glance.

    const SCROLL_THRESHOLD_PX = 100;
    const throttleState = { isTicking: false, animationFrameId: 0 };

    const onScroll = () => {
      if (!throttleState.isTicking) {
        throttleState.animationFrameId = window.requestAnimationFrame(() => {
          setHasScrolled(window.scrollY > SCROLL_THRESHOLD_PX);
          throttleState.isTicking = false;
        });
        throttleState.isTicking = true;
      }
    };

    window.addEventListener("scroll", onScroll, { passive: true });
    return () => {
      window.removeEventListener("scroll", onScroll);
      window.cancelAnimationFrame(throttleState.animationFrameId);
    };

}, []);

const handleClick = () => {
Expand Down
Loading