perf: WebView2 HostObject 프록시 캐싱으로 성능 개선

- 각 HTML 파일에서 machine 프록시를 전역 변수로 한 번만 초기화
- 매 함수 호출마다 hostObjects.machine 접근하던 오버헤드 제거
- 네비게이션 클릭 시 콘솔 로그 추가 (디버깅용)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
backuppc
2025-11-25 15:58:39 +09:00
parent 3bd7a37b72
commit f0d46b7cb1
6 changed files with 464 additions and 1274 deletions

View File

@@ -262,6 +262,9 @@
</div>
<script>
// 비동기 프록시 캐싱 (한 번만 초기화)
const machine = window.chrome.webview.hostObjects.machine;
// 폼 제출 처리
document.getElementById('loginForm').addEventListener('submit', function(e) {
e.preventDefault();
@@ -278,49 +281,43 @@
// 로딩 표시
showLoading();
// HomeController의 로그인 API 호출
fetch('/Home/Login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
Gcode: gcode,
UserId: userId,
Password: password,
RememberMe: rememberMe
})
})
.then(response => response.json())
.then(data => {
hideLoading();
if (data.Success) {
// 로그인 성공
showSuccess(data.Message);
// WebView2에 로그인 성공 메시지 전송
if (window.chrome && window.chrome.webview) {
window.chrome.webview.postMessage('LOGIN_SUCCESS');
}
// 리다이렉트 URL이 있으면 이동
if (data.RedirectUrl) {
// WebView2 HostObject를 통해 C# Login 함수 호출
(async () => {
try {
const jsonResult = await machine.Login(gcode, userId, password, rememberMe);
const data = JSON.parse(jsonResult);
hideLoading();
if (data.Success) {
// 로그인 성공
showSuccess(data.Message);
// 버전 경고가 있으면 표시
if (data.VersionWarning) {
alert(data.VersionWarning);
}
// WebView2에 로그인 성공 메시지 전송
if (window.chrome && window.chrome.webview) {
window.chrome.webview.postMessage('LOGIN_SUCCESS');
}
// 리다이렉트 URL이 있으면 이동, 없으면 대시보드로 이동
setTimeout(() => {
window.location.href = data.RedirectUrl;
window.location.href = data.RedirectUrl || '/DashBoard/index.html';
}, 1000);
} else {
// 로그인 실패
showError(data.Message || '로그인에 실패했습니다.');
}
} else {
// 로그인 실패
showError(data.Message || '로그인에 실패했습니다.');
} catch (error) {
hideLoading();
console.error('로그인 요청 중 오류 발생:', error);
showError('서버 연결에 실패했습니다. 다시 시도해주세요.');
}
})
.catch(error => {
hideLoading();
console.error('로그인 요청 중 오류 발생:', error);
showError('서버 연결에 실패했습니다. 다시 시도해주세요.');
});
})();
});
// 입력 필드 포커스 효과
@@ -372,74 +369,76 @@
}
// 그룹 목록 로드
function loadUserGroups() {
fetch('/DashBoard/GetUserGroups')
.then(response => response.json())
.then(data => {
const gcodeSelect = document.getElementById('gcode');
// 기존 옵션 제거 (첫 번째 옵션 제외)
while (gcodeSelect.children.length > 1) {
gcodeSelect.removeChild(gcodeSelect.lastChild);
async function loadUserGroups() {
try {
// WebView2 HostObject를 통해 C# 함수 호출
const machine = window.chrome.webview.hostObjects.machine;
const jsonData = await machine.GetUserGroups();
const data = JSON.parse(jsonData);
const gcodeSelect = document.getElementById('gcode');
// 기존 옵션 제거 (첫 번째 옵션 제외)
while (gcodeSelect.children.length > 1) {
gcodeSelect.removeChild(gcodeSelect.lastChild);
}
// 데이터 추가
data.forEach(group => {
if (group.gcode && group.name) {
const option = document.createElement('option');
option.value = group.gcode;
option.textContent = group.name;
option.className = 'text-gray-800';
gcodeSelect.appendChild(option);
}
// 데이터 추가
data.forEach(group => {
if (group.gcode && group.name) {
const option = document.createElement('option');
option.value = group.gcode;
option.textContent = group.name;
option.className = 'text-gray-800';
gcodeSelect.appendChild(option);
}
});
// 이전 로그인 정보 설정
setPreviousLoginInfo();
})
.catch(error => {
console.error('그룹 목록 로드 중 오류 발생:', error);
showError('부서 목록을 불러오는 중 오류가 발생했습니다.');
});
// 이전 로그인 정보 설정
setPreviousLoginInfo();
} catch (error) {
console.error('그룹 목록 로드 중 오류 발생:', error);
showError('부서 목록을 불러오는 중 오류가 발생했습니다.');
}
}
// 이전 로그인 정보 설정
function setPreviousLoginInfo() {
// HomeController의 GetPreviousLoginInfo API 호출
fetch('/Home/GetPreviousLoginInfo')
.then(response => response.json())
.then(data => {
if (data.Success && data.Data) {
handlePreviousLoginInfo(data.Data);
}
})
.catch(error => {
console.error('이전 로그인 정보 로드 중 오류 발생:', error);
// 오류 발생해도 기본 포커스 설정
setTimeout(() => {
document.getElementById('gcode').focus();
}, 100);
});
async function setPreviousLoginInfo() {
try {
// WebView2 HostObject를 통해 C# GetPreviousLoginInfo 함수 호출
const machine = window.chrome.webview.hostObjects.machine;
const jsonResult = await machine.GetPreviousLoginInfo();
const data = JSON.parse(jsonResult);
if (data.Success && data.Data) {
handlePreviousLoginInfo(data.Data);
}
} catch (error) {
console.error('이전 로그인 정보 로드 중 오류 발생:', error);
// 오류가 발생해도 기본 포커스 설정
setTimeout(() => {
document.getElementById('gcode').focus();
}, 100);
}
}
// 이전 로그인 정보 처리
function handlePreviousLoginInfo(data) {
let hasPreviousInfo = false;
if (data && data.Gcode) {
if (data && data.LastGcode) {
// 부서 선택
const gcodeSelect = document.getElementById('gcode');
gcodeSelect.value = data.Gcode;
gcodeSelect.value = data.LastGcode;
hasPreviousInfo = true;
}
if (data && data.UserId) {
// 사용자 ID 설정 - 세미콜론으로 구분된 경우 첫 번째 요소만 사용
const userId = data.UserId.split(';')[0];
document.getElementById('userId').value = userId;
if (data && data.LastId) {
// 사용자 ID 설정
document.getElementById('userId').value = data.LastId;
hasPreviousInfo = true;
}
// 이전 로그인 정보가 있으면 비밀번호 필드에, 없으면 부서 선택에 포커스
setTimeout(() => {
if (hasPreviousInfo) {