Skip to content

Commit

Permalink
perf(TS-13): 강의 목록 렌더링 속도 개선 (#92)
Browse files Browse the repository at this point in the history
* feat: 스크롤 위치 초기화

- 페이지 이동 시 스크롤 위치를 초기화하도록 했습니다.

* perf: 강의 목록 렌더링 속도 개선

- react-window 라이브러리를 설치했습니다.
- 테이블을 가상화 했습니다.
- 렌더링 시간을 약 4.5초->1.5초로 개선했습니다.
- 몇몇 열들의 초기 너비를 수정했습니다.
- 테이블을 가상화하면서 커스텀이 생각보다 어려워서 각 열의 너비를 조정하는 resizer를 제외시켰습니다.
대신 너비를 넉넉하게 바꿔 사용자가 보기에 불편하지 않도록 수정했습니다.
  • Loading branch information
jeewonMoon authored Sep 11, 2024
1 parent bf62dad commit 5032c90
Show file tree
Hide file tree
Showing 12 changed files with 233 additions and 179 deletions.
48 changes: 48 additions & 0 deletions package-lock.json

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

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"react-redux": "^9.1.2",
"react-responsive": "^10.0.0",
"react-router-dom": "^6.24.0",
"react-window": "^1.8.10",
"redux-persist": "^6.0.0",
"styled-components": "^6.1.11",
"styled-reset": "^4.5.2",
Expand All @@ -31,6 +32,7 @@
"@types/node": "^20.14.9",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/react-window": "^1.8.8",
"@types/styled-components": "^5.1.34",
"@typescript-eslint/eslint-plugin": "^7.13.1",
"@typescript-eslint/parser": "^7.13.1",
Expand Down
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ProtectedRoute from '@components/ProtectedRoute.tsx';
import Home from '@pages/index/Home.tsx';
import Login from '@pages/index/Login.tsx';
import DeleteAccount from '@pages/DeleteAccount.tsx';
import ScrollToTop from './utils/scrollToTop';

function initializeAnalytics() {
ReactGA.initialize(import.meta.env.VITE_GTM_ID);
Expand All @@ -21,6 +22,7 @@ function App() {
return (
<ThemeProvider theme={theme}>
<GlobalStyle />
<ScrollToTop />
<Routes>
<Route path='/login' element={<Login />} />
<Route path='/delete' element={<DeleteAccount />} />
Expand Down
14 changes: 7 additions & 7 deletions src/components/CourseRegister/RegisteredList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ import {TableTitle, TableTitleWrap} from '../LectureList';
import Table from '../common/Table';

const colData = [
{name: 'action', value: '삭제', initialWidth: 30, enableFilters: false},
{name: 'action', value: '삭제', initialWidth: 50, enableFilters: false},
{name: 'curiNo', value: '학수번호', initialWidth: 92},
{name: 'classNo', value: '분반', initialWidth: 58},
{name: 'schDeptAlias', value: '개설학과', initialWidth: 167},
{name: 'curiNm', value: '교과목명', initialWidth: 232},
{name: 'schDeptAlias', value: '개설학과', initialWidth: 177},
{name: 'curiNm', value: '교과목명', initialWidth: 242},
{name: 'curiLangNm', value: '강의언어', initialWidth: 73},
{name: 'tmNum', value: '학점/이론/실습', initialWidth: 134},
{name: 'tmNum', value: '학점/이론/실습', initialWidth: 144},
{name: 'curiTypeCdNm', value: '이수구분'},
{name: 'studentYear', value: '학년 (학기)'},
{name: 'lesnTime', value: '요일 및 강의시간', initialWidth: 130},
{name: 'lesnEmp', value: '교수명'},
{name: 'lesnTime', value: '요일 및 강의시간', initialWidth: 183},
{name: 'lesnEmp', value: '교수명', initialWidth: 238},
{name: 'lesnRoom', value: '강의실', initialWidth: 114},
{name: 'remark', value: '수강대상및유의사항', initialWidth: 230},
{name: 'remark', value: '수강대상및유의사항', initialWidth: 610},
];

interface RegisteredListProps {
Expand Down
14 changes: 7 additions & 7 deletions src/components/CourseRegister/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@ import {openModalHandler} from '../common/Modal/handlers/handler';
import {setEndCount} from '@/store/modules/courseRegisteredSlice';

const colData = [
{name: 'action', value: '신청', initialWidth: 30, enableFilters: false},
{name: 'action', value: '신청', initialWidth: 50, enableFilters: false},
{name: 'curiNo', value: '학수번호', initialWidth: 92},
{name: 'classNo', value: '분반', initialWidth: 58},
{name: 'schDeptAlias', value: '개설학과', initialWidth: 167},
{name: 'curiNm', value: '교과목명', initialWidth: 232},
{name: 'schDeptAlias', value: '개설학과', initialWidth: 177},
{name: 'curiNm', value: '교과목명', initialWidth: 242},
{name: 'curiLangNm', value: '강의언어', initialWidth: 73},
{name: 'tmNum', value: '학점/이론/실습', initialWidth: 134},
{name: 'tmNum', value: '학점/이론/실습', initialWidth: 144},
{name: 'curiTypeCdNm', value: '이수구분'},
{name: 'studentYear', value: '학년 (학기)'},
{name: 'lesnTime', value: '요일 및 강의시간', initialWidth: 130},
{name: 'lesnEmp', value: '교수명'},
{name: 'lesnTime', value: '요일 및 강의시간', initialWidth: 183},
{name: 'lesnEmp', value: '교수명', initialWidth: 238},
{name: 'lesnRoom', value: '강의실', initialWidth: 114},
{name: 'remark', value: '수강대상및유의사항', initialWidth: 230},
{name: 'remark', value: '수강대상및유의사항', initialWidth: 610},
];

function CourseRegister() {
Expand Down
20 changes: 10 additions & 10 deletions src/components/LectureList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,24 @@ import {CourseTypes} from '@assets/types/tableType';
import {getCourseList} from '@/apis/api/course';

const colData = [
{name: 'schDeptAlias', value: '개설학과전공', initialWidth: 167},
{name: 'schDeptAlias', value: '개설학과전공', initialWidth: 276},
{name: 'curiNo', value: '학수번호', initialWidth: 92},
{name: 'classNo', value: '분반', initialWidth: 58},
{name: 'curiNm', value: '교과목명', initialWidth: 232},
{name: 'curiNm', value: '교과목명', initialWidth: 242},
{name: 'curiLangNm', value: '강의언어', initialWidth: 73},
{name: 'curiTypeCdNm', value: '이수구분'},
{name: 'sltDomainCdNm', value: '선택영역', initialWidth: 136},
{name: 'tmNum', value: '학점/이론/실습', initialWidth: 134},
{name: 'tmNum', value: '학점/이론/실습', initialWidth: 144},
{name: 'studentYear', value: '학년 (학기)'},
{name: 'corsUnitGrpCdNm', value: '대상과정'},
{name: 'manageDeptNm', value: '주관학과', initialWidth: 135},
{name: 'lesnEmp', value: '교수명'},
{name: 'lesnTime', value: '요일 및 강의시간', initialWidth: 130},
{name: 'manageDeptNm', value: '주관학과', initialWidth: 276},
{name: 'lesnEmp', value: '교수명', initialWidth: 238},
{name: 'lesnTime', value: '요일 및 강의시간', initialWidth: 183},
{name: 'lesnRoom', value: '강의실', initialWidth: 114},
{name: 'cyberTypeCdNm', value: '사이버강좌', initialWidth: 104},
{name: 'internshipTypeCdNm', value: '강좌유형', initialWidth: 126},
{name: 'inoutSubCdtExchangeYn', value: '학점교류수강가능', initialWidth: 130},
{name: 'remark', value: '수강대상및유의사항', initialWidth: 230},
{name: 'cyberTypeCdNm', value: '사이버강좌', initialWidth: 171},
{name: 'internshipTypeCdNm', value: '강좌유형', initialWidth: 136},
{name: 'inoutSubCdtExchangeYn', value: '학점교류수강가능', initialWidth: 140},
{name: 'remark', value: '수강대상및유의사항', initialWidth: 610},
];

function LectureList() {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Menubar/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function MenuItem({id, type, name, isActive, onClick}: DetailProps) {

const DetailWrap = styled.button<{$isactive: boolean}>`
${props => props.theme.texts.tableTitle};
width: 19rem;
width: 90%;
height: 2.8rem;
display: flex;
align-items: center;
Expand Down
20 changes: 10 additions & 10 deletions src/components/Wishlist/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,28 @@ import {useSelector} from 'react-redux';
import {TableTitle, TableTitleWrap} from '../LectureList';

const searchResultColData = [
{name: 'action', value: '신청', initialWidth: 30, enableFilters: false},
{name: 'schDeptAlias', value: '개설학과전공', initialWidth: 167},
{name: 'action', value: '신청', initialWidth: 50, enableFilters: false},
{name: 'schDeptAlias', value: '개설학과전공', initialWidth: 276},
{name: 'curiNo', value: '학수번호', initialWidth: 92},
{name: 'classNo', value: '분반', initialWidth: 58},
{name: 'curiNm', value: '교과목명', initialWidth: 232},
{name: 'curiNm', value: '교과목명', initialWidth: 242},
{name: 'curiTypeCdNm', value: '이수구분'},
{name: 'tmNum', value: '학점/이론/실습', initialWidth: 134},
{name: 'lesnEmp', value: '교수명'},
{name: 'lesnTime', value: '요일 및 강의시간', initialWidth: 130},
{name: 'lesnEmp', value: '교수명', initialWidth: 238},
{name: 'lesnTime', value: '요일 및 강의시간', initialWidth: 183},
{name: 'lesnRoom', value: '강의실', initialWidth: 114},
];

const wishlistColData = [
{name: 'action', value: '삭제', initialWidth: 30, enableFilters: false},
{name: 'schDeptAlias', value: '개설학과전공', initialWidth: 167},
{name: 'action', value: '삭제', initialWidth: 50, enableFilters: false},
{name: 'schDeptAlias', value: '개설학과전공', initialWidth: 276},
{name: 'curiNo', value: '학수번호', initialWidth: 92},
{name: 'classNo', value: '분반', initialWidth: 58},
{name: 'curiNm', value: '교과목명', initialWidth: 232},
{name: 'curiNm', value: '교과목명', initialWidth: 242},
{name: 'curiTypeCdNm', value: '이수구분'},
{name: 'tmNum', value: '학점/이론/실습', initialWidth: 134},
{name: 'lesnEmp', value: '교수명'},
{name: 'lesnTime', value: '요일 및 강의시간', initialWidth: 130},
{name: 'lesnEmp', value: '교수명', initialWidth: 238},
{name: 'lesnTime', value: '요일 및 강의시간', initialWidth: 183},
{name: 'lesnRoom', value: '강의실', initialWidth: 114},
];

Expand Down
26 changes: 6 additions & 20 deletions src/components/common/Table/TableHead.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ interface HeadProps {
width: number;
options: string[];
type?: string;
handleMouseDown: (index: number) => (event: React.MouseEvent) => void;
selectedOptions: string[];
onFilterChange: (index: number, selectedOptions: string[]) => void;
}
Expand All @@ -21,7 +20,6 @@ function TableHead({
type,
selectedOptions,
onFilterChange,
handleMouseDown,
}: HeadProps) {
const [open, setOpen] = useState(false);
const dropdownRef = useRef<HTMLUListElement>(null);
Expand Down Expand Up @@ -101,13 +99,12 @@ function TableHead({
)}
</>
)}
<Resizer onMouseDown={handleMouseDown(index + 1)} />
</div>
</Wrap>
);
}

const Wrap = styled.th<{width: number}>`
const Wrap = styled.div<{width: number}>`
min-width: ${props => props.width}px;
text-align: ${props => (props.width > 100 ? 'center' : 'left')};
Expand All @@ -123,23 +120,11 @@ const Wrap = styled.th<{width: number}>`
}
`;

const Resizer = styled.div`
width: 5px;
height: 100%;
position: absolute;
right: 0;
top: 0;
bottom: 0;
cursor: col-resize;
background-color: transparent;
z-index: 1;
`;

const DropdownBtn = styled.button`
width: 1.8rem;
height: 1.8rem;
background: url(${dropdown}) no-repeat center;
background-size: 1.8rem;
width: 1.8rem;
height: 1.8rem;
background: url(${dropdown}) no-repeat center;
background-size: 1.8rem;
`;

const OptionBox = styled.ul`
Expand All @@ -149,6 +134,7 @@ const OptionBox = styled.ul`
position: absolute;
top: 3rem;
left: 0;
z-index: 1;
`;

const OptionWrap = styled.li`
Expand Down
Loading

0 comments on commit 5032c90

Please sign in to comment.