Feat: add compression

Perf: reduce file load to once
Bug: removed lang change race condition
This commit is contained in:
Richard Wong 2024-08-20 13:20:16 +09:00
parent f169e18ea3
commit d7fdf2df50
Signed by: richard
GPG Key ID: 72948FBB6D359A6D
6 changed files with 97 additions and 35 deletions

View File

@ -29,7 +29,8 @@
"eslint-plugin-react": "^7.32.2", "eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.3.4", "eslint-plugin-react-refresh": "^0.3.4",
"vite": "^4.3.2" "vite": "^4.3.2",
"vite-plugin-compression2": "^1.2.0"
}, },
"packageManager": "pnpm@8.15.4+sha512.0bd3a9be9eb0e9a692676deec00a303ba218ba279d99241475616b398dbaeedd11146f92c2843458f557b1d127e09d4c171e105bdcd6b61002b39685a8016b9e" "packageManager": "pnpm@8.15.4+sha512.0bd3a9be9eb0e9a692676deec00a303ba218ba279d99241475616b398dbaeedd11146f92c2843458f557b1d127e09d4c171e105bdcd6b61002b39685a8016b9e"
} }

View File

@ -61,6 +61,9 @@ devDependencies:
vite: vite:
specifier: ^4.3.2 specifier: ^4.3.2
version: 4.3.2 version: 4.3.2
vite-plugin-compression2:
specifier: ^1.2.0
version: 1.2.0
packages: packages:
@ -613,6 +616,24 @@ packages:
fastq: 1.15.0 fastq: 1.15.0
dev: true dev: true
/@rollup/pluginutils@5.1.0:
resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
engines: {node: '>=14.0.0'}
peerDependencies:
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true
dependencies:
'@types/estree': 1.0.5
estree-walker: 2.0.2
picomatch: 2.3.1
dev: true
/@types/estree@1.0.5:
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
dev: true
/@types/prop-types@15.7.5: /@types/prop-types@15.7.5:
resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
dev: true dev: true
@ -1135,6 +1156,10 @@ packages:
engines: {node: '>=4.0'} engines: {node: '>=4.0'}
dev: true dev: true
/estree-walker@2.0.2:
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
dev: true
/esutils@2.0.3: /esutils@2.0.3:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -1746,6 +1771,11 @@ packages:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
dev: true dev: true
/picomatch@2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
dev: true
/postcss@8.4.23: /postcss@8.4.23:
resolution: {integrity: sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==} resolution: {integrity: sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==}
engines: {node: ^10 || ^12 || >=14} engines: {node: ^10 || ^12 || >=14}
@ -2009,6 +2039,10 @@ packages:
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
dev: true dev: true
/tar-mini@0.1.0:
resolution: {integrity: sha512-klU/ZiWwgAKugpvd4SsmmuZO/FRpvMBzPV+7s46Jn1LWC7GiIZ2BwCnRYl8CtudSD8S1EaHJ/LRdNPF50n+V5w==}
dev: true
/text-table@0.2.0: /text-table@0.2.0:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
dev: true dev: true
@ -2072,6 +2106,15 @@ packages:
punycode: 2.3.0 punycode: 2.3.0
dev: true dev: true
/vite-plugin-compression2@1.2.0:
resolution: {integrity: sha512-3RYEAwQW9JKHt6lmCudoTVO1YaiAGEDkg86MDNvl74btmwtWuCXt8r5WUByZEQLjCZz8nYf5BEh7NELUXr+4LA==}
dependencies:
'@rollup/pluginutils': 5.1.0
tar-mini: 0.1.0
transitivePeerDependencies:
- rollup
dev: true
/vite@4.3.2: /vite@4.3.2:
resolution: {integrity: sha512-9R53Mf+TBoXCYejcL+qFbZde+eZveQLDYd9XgULILLC1a5ZwPaqgmdVpL8/uvw2BM/1TzetWjglwm+3RO+xTyw==} resolution: {integrity: sha512-9R53Mf+TBoXCYejcL+qFbZde+eZveQLDYd9XgULILLC1a5ZwPaqgmdVpL8/uvw2BM/1TzetWjglwm+3RO+xTyw==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}

View File

@ -4,7 +4,7 @@ Implemented features:
- create checklist from keys - create checklist from keys
*/ */
import fullVerseData from "./assets/verse.json" // the actual verse json data file import fullVerseData from "./assets/verse.json" // the actual verse json data file
import { useState } from "react"; import { useState, useEffect } from "react";
import CheckboxTree from 'react-checkbox-tree'; import CheckboxTree from 'react-checkbox-tree';
import 'react-checkbox-tree/lib/react-checkbox-tree.css'; import 'react-checkbox-tree/lib/react-checkbox-tree.css';
import _ from 'underscore'; import _ from 'underscore';
@ -68,7 +68,7 @@ const loadCustomData = (language) => {
case 'en': case 'en':
default: default:
data = fullVerseData.en; data = fullVerseData.en;
break; break;//
} }
return data; return data;
}; };
@ -77,39 +77,61 @@ const loadCustomData = (language) => {
function Page() { function Page() {
// refresh button for refresh
const RefreshButton = ({ onClick }) => {
return <button onClick={onClick}>Shuffle</button>;
};
// refresh variables where incrementing state forces refresh
const [refreshKey, setRefreshKey] = useState(0);
const handleRefresh = () => {
// Increment the key to force a re-render
setRefreshKey(refreshKey => refreshKey + 1);
};
// setup i18 for function // setup i18 for function
const { t, i18n } = useTranslation(); const { t, i18n } = useTranslation();
// load VerseData json data file // we should not load the file every time
const [VerseData, setVerseData] = useState(loadCustomData(i18n.language)); const [VerseData, setVerseData] = useState(null);
// effect to only run on first render
// empty dependency means only mount once
useEffect(() => {
setVerseData(loadCustomData(i18n.language));
}, []);
// function hook to change language // function hook to change language
// updates both i18n language and also the VerseData state variable // updates both i18n language and also the VerseData state variable
const changeLanguage = (lng) => { const changeLanguage = (lng) => {
i18n.changeLanguage(lng); // i18n.changeLanguage is async, so we should wait until its done to avoid
// race conditions
// console.log("change language");
i18n.changeLanguage(lng).then(() => {
setVerseData(loadCustomData(i18n.language)); setVerseData(loadCustomData(i18n.language));
});
}; };
// create checklist array for pack selection // // create checklist array for pack selection
const packList = Object.keys(VerseData); // const packList = Object.keys(VerseData);
// return a list of packObj's // // return a list of packObj's
// 1. packObj.pack for the pack name // // 1. packObj.pack for the pack name
// 2. packObj.include for whether to include the pack // // 2. packObj.include for whether to include the pack
const packObjList = packList.map((element) => { // const packObjList = packList.map((element) => {
// create object for each element in VerseData key list // // create object for each element in VerseData key list
const packObj = new Object(); // const packObj = new Object();
packObj.pack = element; // packObj.pack = element;
packObj.include = false; // packObj.include = false;
return packObj // return packObj
} // }
) // )
const [packs, setPacks] = useState(packObjList) // const [packs, setPacks] = useState(packObjList)
// initialize state variable testCount // initialize state variable testCount
// purpose: to set number of verses to test // purpose: to set number of verses to test
const [testCount, setTestCount] = useState(15) const [testCount, setTestCount] = useState(20)
const testCountChange = (e) => { const testCountChange = (e) => {
const value = e.target.value const value = e.target.value
setTestCount(value) setTestCount(value)
@ -143,16 +165,6 @@ function Page() {
// refresh button for refresh
const RefreshButton = ({ onClick }) => {
return <button onClick={onClick}>Shuffle</button>;
};
// refresh variables where incrementing state forces refresh
const [refreshKey, setRefreshKey] = useState(0);
const handleRefresh = () => {
// Increment the key to force a re-render
setRefreshKey(refreshKey => refreshKey + 1);
};
return ( return (
<div className="App"> <div className="App">

View File

@ -240,7 +240,7 @@ const VerseValidator = ({ element: { pack, title, chapterTitle, reference, verse
<p></p> <p></p>
<div> <div>
Verse: Verse:
<DiffViewer <DiffViewerStrict
oldValue={verse} oldValue={verse}
newValue={inputVerse} newValue={inputVerse}
/> />

View File

@ -1710,7 +1710,7 @@
"title": "승리의 확신", "title": "승리의 확신",
"chapterTitle": "", "chapterTitle": "",
"reference": "고린도전서 10:13", "reference": "고린도전서 10:13",
"verse": "사람이 감할 시험밖에는 너희에게 당한 것이 없나니, 오직 하나님은 미쁘사 너희가 감당치 못할 시험 당함을 허락지 아니하시고, 시험당할 즈음에 또한 피할 길을 내사 너희로 능히 감당하게 시느니라" "verse": "사람이 감할 시험밖에는 너희에게 당한 것이 없나니 오직 하나님은 미쁘사 너희가 감당치 못할 시험당함을 허락지 아니하시고 시험당할 즈음에 또한 피할 길을 내사 너희로 능히 감당하게 시느니라"
}, },
{ {
"pack": "5확신", "pack": "5확신",

View File

@ -1,9 +1,15 @@
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react' import react from '@vitejs/plugin-react'
import { compression } from 'vite-plugin-compression2'
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [react()], plugins: [
react(),
compression({
algorithm: "brotliCompress"
})
],
define: { define: {
VITE_BUILD_DATE: JSON.stringify(new Date().toLocaleString()), VITE_BUILD_DATE: JSON.stringify(new Date().toLocaleString()),
}, },