Skip to content

Commit

Permalink
Improve performance with lazy loading, useCallback, useMemo, and mini…
Browse files Browse the repository at this point in the history
…fied JavaScript
  • Loading branch information
rendi12345678 committed Jul 1, 2024
1 parent 25b5253 commit 503254a
Show file tree
Hide file tree
Showing 15 changed files with 52 additions and 45 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"random-words": "^1.1.2",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-scripts": "5.0.1",
"react-scripts": "^5.0.1",
"react-select": "^5.3.0",
"react-toastify": "^10.0.4",
"styled-components": "^5.3.5",
Expand Down
27 changes: 15 additions & 12 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
import React, { useState, useRef, useEffect } from "react";
import React, { useState, Suspense, useRef, useEffect } from "react";
import { ThemeProvider } from "styled-components";
import { defaultTheme, themesOptions } from "./style/theme";
import { GlobalStyles } from "./style/global";
import TypeBox from "./components/features/TypeBox/TypeBox";
import SentenceBox from "./components/features/SentenceBox/SentenceBox";
import Logo from "./components/common/Logo";
import MusicPlayerSnackbar from "./components/features/MusicPlayer/MusicPlayerSnackbar";
import FooterMenu from "./components/common/FooterMenu";
import FreeTypingBox from "./components/features/FreeTypingBox";

import {
GAME_MODE,
GAME_MODE_DEFAULT,
GAME_MODE_SENTENCE,
} from "./constants/Constants";
import useLocalPersistState from "./hooks/useLocalPersistState";
import DefaultKeyboard from "./components/features/Keyboard/DefaultKeyboard";
import WordsCard from "./components/features/WordsCard/WordsCard";
import {
SOUND_MODE,
soundOptions,
DEFAULT_SOUND_TYPE,
DEFAULT_SOUND_TYPE_KEY,
} from "./components/features/sound/sound";
import DynamicBackground from "./components/common/DynamicBackground";

// Lazy load components to boost performance
const TypeBox = React.lazy(() => import('./components/features/TypeBox/TypeBox'));
const SentenceBox = React.lazy(() => import('./components/features/SentenceBox/SentenceBox'));
const Logo = React.lazy(() => import('./components/common/Logo'));
const MusicPlayerSnackbar = React.lazy(() => import('./components/features/MusicPlayer/MusicPlayerSnackbar'));
const FooterMenu = React.lazy(() => import('./components/common/FooterMenu'));
const FreeTypingBox = React.lazy(() => import('./components/features/FreeTypingBox'));
const WordsCard = React.lazy(() => import('./components/features/WordsCard/WordsCard'));
const DefaultKeyboard = React.lazy(() => import('./components/features/Keyboard/DefaultKeyboard'));
const DynamicBackground = React.lazy(() => import('./components/common/DynamicBackground'));

function App() {
// localStorage persist theme setting
Expand Down Expand Up @@ -174,7 +177,7 @@ function App() {

return (
<ThemeProvider theme={theme}>
<>
<Suspense fallback={null}>
<DynamicBackground theme={theme}></DynamicBackground>
<div className="canvas">
<GlobalStyles />
Expand Down Expand Up @@ -245,7 +248,7 @@ function App() {
onMouseLeave={() => focusTextInput()}
></MusicPlayerSnackbar>
</div>
</>
</Suspense>
</ThemeProvider>
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/DynamicBackground.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ const DynamicBackground = ({ theme }) => {
return null;
};

export default DynamicBackground;
export default React.memo(DynamicBackground);
2 changes: 1 addition & 1 deletion src/components/common/FooterMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,4 @@ const FooterMenu = ({
);
};

export default FooterMenu;
export default React.memo(FooterMenu);
2 changes: 1 addition & 1 deletion src/components/common/Logo.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ const Logo = ({ isFocusedMode }) => {
);
};

export default Logo;
export default React.memo(Logo);
2 changes: 1 addition & 1 deletion src/components/features/FreeTypingBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@ const FreeTypingBox = ({ spaces = 4, textAreaRef, soundMode, soundType }) => {
);
};

export default FreeTypingBox;
export default React.memo(FreeTypingBox);
2 changes: 1 addition & 1 deletion src/components/features/Keyboard/DefaultKeyboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,4 +222,4 @@ const DefaultKeyboard = ({soundType, soundMode}) => {
);
};

export default DefaultKeyboard;
export default React.memo(DefaultKeyboard);
37 changes: 21 additions & 16 deletions src/components/features/SentenceBox/SentenceBox.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from "react";
import { useState, useMemo, useEffect } from "react";
import React, {useCallback, useMemo, useEffect, useState} from "react";
import { sentencesGenerator } from "../../../scripts/sentencesGenerator";
import { Stack } from "@mui/material";
import { Grid } from "@mui/material";
Expand Down Expand Up @@ -168,25 +167,31 @@ const SentenceBox = ({
extra: 0,
});

const checkAndUpdateStats = (currSentence, currInput) => {
const newStats = stats;
const checkAndUpdateStats = useCallback((currSentence, currInput) => {
setStats((prevStats) => {
let correct = prevStats.correct;
let incorrect = prevStats.incorrect;
let extra = prevStats.extra;

for (let i = 0; i < currSentence.length; i++) {
if (currSentence[i] === currInput[i]) {
newStats.correct++;
correct++;
} else {
newStats.incorrect++;
incorrect++;
}
}

const deltaCharDifference = currInput.length - currSentence.length;

if (deltaCharDifference > 0) {
newStats.extra = deltaCharDifference;
extra = deltaCharDifference;
}

setStats(newStats);
};
return { correct, incorrect, extra };
});
}, []);

const handleKeyDown = (e) => {
const handleKeyDown = useCallback(() => (e) => {
if (status !== "finished" && soundMode) {
play();
}
Expand All @@ -208,7 +213,7 @@ const SentenceBox = ({
return;
}

setRawKeyStroke(rawKeyStroke + 1);
setRawKeyStroke(prevRawKeyStroke => prevRawKeyStroke + 1);

// if enter key pressed.
// advance to next sentence only if the input val length is equal to the current sentence char count);
Expand All @@ -221,14 +226,14 @@ const SentenceBox = ({
setTimeRunning(false);
return;
}
setCurrSentenceIndex(currSentenceIndex + 1);
setCurrSentenceIndex(prevCurrSentenceIndex => prevCurrSentenceIndex + 1);
setCurrInput("");
sentenceInputRef.current.value = "";
return;
}
return;
}
};
});

const getCharClassName = (idx, char) => {
if (idx < currInput.length) {
Expand Down Expand Up @@ -268,14 +273,14 @@ const SentenceBox = ({
}
};

const handleChange = (e) => {
const handleChange = useCallback(() => (e) => {
const {
currentTarget: { value },
} = e;
if (e.currentTarget instanceof HTMLInputElement && !isOnComposition) {
setCurrInput(value);
}
};
});

return (
<div onClick={handleInputFocus}>
Expand Down Expand Up @@ -452,4 +457,4 @@ const SentenceBox = ({
);
};

export default SentenceBox;
export default React.memo(SentenceBox);
2 changes: 1 addition & 1 deletion src/components/features/SentenceBox/SentenceBoxStats.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ const SentenceBoxStats = ({ status, wpm, countDown, stats, rawKeyStrokes }) => {
);
};

export default SentenceBoxStats;
export default React.memo(SentenceBoxStats);
2 changes: 1 addition & 1 deletion src/components/features/TypeBox/Stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,4 @@ const Stats = ({
);
};

export default Stats;
export default React.memo(Stats);
2 changes: 1 addition & 1 deletion src/components/features/TypeBox/TypeBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -991,4 +991,4 @@ const TypeBox = ({
);
};

export default TypeBox;
export default React.memo(TypeBox);
9 changes: 4 additions & 5 deletions src/components/features/WordsCard/WordsCard.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from "react";
import { useState, useEffect, useRef } from "react";
import React, { useState, useCallback, useEffect, useRef } from "react";
import { DICTIONARY_SOURCE_CATALOG } from "../../../constants/DictionaryConstants";
import {
RECITE_MODE_TITLE,
Expand Down Expand Up @@ -100,11 +99,11 @@ const WordsCard = ({ soundType, soundMode }) => {
}
};

const handleInputChange = (e) => {
const handleInputChange = useCallback(() => (e) => {
setCurrInput(e.target.value);
hiddenInputRef.current.value = e.target.value;
e.preventDefault();
};
});

const updateAlphabetSet = (char) => {
const newAlphabetSet = new Set(alphabetSet);
Expand Down Expand Up @@ -516,4 +515,4 @@ const WordsCard = ({ soundType, soundMode }) => {
);
};

export default WordsCard;
export default React.memo(WordsCard);
2 changes: 1 addition & 1 deletion src/components/utils/Select.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@ export default styled(Select)`
background: ${({ theme }) => theme.background};
}
`;
`;
2 changes: 1 addition & 1 deletion src/scripts/wordsGenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,6 @@ const wordsCardVocabGenerator = (vocabSource, chapter) => {
wordsList.push(VOCAB_DICTIONARIES[vocabSource][i]);
}
return wordsList;
};
}

export { wordsGenerator, chineseWordsGenerator, wordsCardVocabGenerator };

0 comments on commit 503254a

Please sign in to comment.