현 회사에 이직하기로 마음먹은 건 새로운 도전을 할 수 있을 것 같다는 강한 끌림과 프런트엔드만 접하다가
간단한 웹 백엔드 서버까지 구축하여 도전을 할 수 있다는 점이 가장 크게 와닿았고 회사의 비전이 정말 괜찮다고 느껴져서 이직 후 6개월가량 밤샘 작업을 하면서 회사의 이바지하였다..
기존 전임자가 짜놓고 간 일렉트론으로 만든 코드는.. 정말 형편이 없었고 딜레이부터 잔 버그들 그리고 사용하지 못할 정도로 속도가 느렸고.. 부분 부분 도메인지식도 전체적으로 다 틀렸다.. 전임자가 사용 한 부분은 일렉트론 + mysql + 백그라운드 js를 사용하였다. 정말이지.. 리뉴얼하는데 엄청 진을 뺐다..
문제가 되었던 부분을 정리하자면
1. cdn 방식이 아닌 폴더 자체 접근 기존 데이터를 알지 못해서 계속 추가적인.. 중복코드 작성
2. 무분별한 store 사용
3. 이벤트 버스를 사용 함으로 자기가 만들어 놓은 로직이 어디에 있는지 몰라서 추가적으로 중복코드 작성
4. 아키텍처가 없고 규칙이 없는 폴더구조
5. 유지보수가 힘든 명령형 프로그래밍 구조
6. 웹 백엔드가 없어서 백엔드 에러로그 확인이 힘듦
7. 비동기처리에 부재로 시점차이 오류가 남발
8. 라이프사이클을 제대로 활용하지 않아서 시점 차이 발생..
전임자가.. SI 출신 12년차 백엔드 개발자라고 전달 받아서 들었다.. 그의 코드를 뜯어보고 나는 경악을 했다.. 신입이 짜놓은 듯한 ...
기존 코드들은 대부분 명령형 + 이벤트버스 남발.. if문에 indexOf.. 등등 es7 등 문법은 찾아보기도 힘들었다..
기존 전임자 코드의 아키텍처
사실상 컴포넌트에 tabPages 만 사용 하고 안쓰는 컴포넌트가 태반이였다.
그리고 알 수 없는 main 이라는 폴더는 사용도 안하고 있다..
리팩토링한 아키텍처 구조는
Api 계층을 담당하는 부분을 common으로 재사용이 가능하게 담아두고 서비스 별로 분리해둔 후 재사용성에 비중을 뒀다..
현 회사의 특이점으로는 폐쇄망으로 내부망쪽에 통신을 해서 값을 올리는 부분이 있는데 그부분에 인수인계가 하나도 없었다.. 순서도를 그려서 대략적인 커스텀마이징을 걸치긴 해야하지만 아래와같이 작업을 진행 하였다.
순서도로 미리 로직을 그려본 후 코드를 만들어가기 시작했다. 모든 로직을 새로 순서도를 그려서 체계적으로 만들기 시작하였고 새로운 로직으로 버그투성이에다가 돌아가지 않는 전임자 코드를 안쓰고 새로 만들었다.
전임자 코드.... 무분별한 이벤트 버스.. 남발 어디서 뭘하는지 전혀 모르겠다..
되도록 props 를 사용하며 전역 스토어는 지향하였다 스토어에 무분별한 사용도 성능 이슈에 영향을 끼치기 때문에 주의 하면서 쓰도록 하였다.
기존 코드 리팩토링 작업을 들어간다.
위에 기존 코드
리팩토링한 코드
if (buff.indexOf('\n') === -1) {
bufStr += buff.toString()
} else {
bufStr += buff.toString()
self.postMessage({params: JSON.parse(bufStr.toString())})
bufStr = ''
}
기존 전임자 코드
ES7에서는 .includes() 메서드가 도입되어 배열에 특정 값이 존재하는지
확인할 때 더 간결하고 직관적인 방법을 사용할 수 있습니다.
indexOf() 메서드와 비교할 때 가독성 면에서 우수하며
indexOf()는 -1을 반환하는 대신 true 또는 false로 존재 여부를 바로 알 수 있다.
if (!buff.includes('\n')) { // indexOf 대신 includes 사용
bufStr += buff.toString();
} else {
bufStr += buff.toString();
self.postMessage({ params: JSON.parse(bufStr.toString()) });
bufStr = '';
}
기존의 콜백 함수나 Promise 체인보다 훨씬 가독성이 좋고, 비동기 코드 작성을 간소화하여 네트워크 요청, 파일 읽기/쓰기 등의 작업을 최적화할 수 있다.
대략 위에 같이 함수형 프로그래밍으로 변경을 했고
성능쪽 이슈를 해결해보겠다.
기존 테이블 리스트 5개 기준 속도 측정 결과
레디스 캐시 서버와 프론트 측 불필요한 스크립트를 걷어내서 속도 향상을 하였고 불필요한 비동기 함수들을 걷어냈다.
서버측에서는 TCP WEBSOCKET 을 사용하여 통신 측 서비스를 하나 만들었고 거기에 로거 서비스를 만들어서 로그를 생성해서 폴더에 생성했다. 아래는 서비스 로거 코드
private lastMessages = {
log: null,
error: null,
warn: null,
debug: null,
cbcLis: null,
ping: null,
login: null,
}; // 각 로그 레벨별 마지막 메시지 저장
constructor() {
super();
this.ensureBaseLogDirectoryExists();
}
log(message: string) {
if (this.isDuplicateMessage('log', message)) return;
super.log(message);
this.writeLog('log', message);
}
error(message: string, trace?: string) {
const fullMessage = trace ? `${message}\n${trace}` : message;
if (this.isDuplicateMessage('error', fullMessage)) return;
super.error(message, trace);
this.writeLog('error', fullMessage);
}
warn(message: string) {
if (this.isDuplicateMessage('warn', message)) return;
super.warn(message);
this.writeLog('warn', message);
}
debug(message: string) {
if (this.isDuplicateMessage('debug', message)) return;
super.debug(message);
this.writeLog('debug', message);
}
cbcLis(message: string) {
if (this.isDuplicateMessage('cbcLis', message)) return;
super.log(message);
this.writeLog('cbcLis', message);
}
ping(message: string) {
if (this.isDuplicateMessage('ping', message)) return;
super.log(message);
this.writeLog('ping', message);
}
logic(message: string) {
if (this.isDuplicateMessage('logic', message)) return;
super.log(message);
this.writeLog('logic', message);
}
private isDuplicateMessage(level: string, message: string): boolean {
if (this.lastMessages[level] === message) {
return true; // 중복 메시지일 경우 true 반환
}
this.lastMessages[level] = message; // 마지막 메시지를 갱신
return false; // 중복이 아니면 false 반환
}
private formattedTime(date: Date) {
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
const milliseconds = String(date.getMilliseconds()).padStart(3, '0');
return `[${hours}:${minutes}:${seconds}.${milliseconds}]`;
}
private writeLog(level: string, message: string) {
const now = new Date();
const dateString = moment(now).format('YYYY-MM-DD'); // 현재 로컬 시간 기준으로 날짜 생성
const logDir = path.join(this.baseLogDir, level);
this.ensureDirectoryExists(logDir);
const logFilePath = path.join(logDir, `${dateString}_${level}.txt`);
this.ensureFileExists(logFilePath);
const formattedMessage = `${this.formattedTime(now)} - ${message}`;
fs.appendFileSync(logFilePath, `${formattedMessage}\n`);
}
private ensureBaseLogDirectoryExists() {
this.ensureDirectoryExists(this.baseLogDir);
}
private ensureDirectoryExists(dir: string) {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
console.log(`로그 디렉토리가 존재하지 않아서 생성: ${dir}`);
}
}
private ensureFileExists(file: string) {
if (!fs.existsSync(file)) {
fs.writeFileSync(file, '');
}
}
아래는 생성된 로그 폴더
로컬 PC에 맞게 로그도 남기면서 성능 이슈도 해결 했다.
서버 측 작업과 프론트 쪽에서도 많은 작업을 했지만 나중에 추후에 더 깊게 작성 해볼 예정이다! 끝
'vue > csr,vue' 카테고리의 다른 글
오픈시드래곤 사용 - 타일화 & 캔버스 위에 좌표 값에 따른 사각형 표시 (0) | 2024.08.27 |
---|---|
Vue 3 Composition API: 간결하고 효율적인 상태 관리 (0) | 2023.12.08 |
Vue 주요 기능 개념 정리 (0) | 2023.12.06 |
Vue 뒤로가기했을때 재렌더링 하기 에러일지 (0) | 2023.01.13 |
vue를 이용한 파이어베이스를 fcm을 이용한 전화 수신 시 알림 창, 모달 창 띄우기 (2) | 2022.12.27 |