신입 연수원 활동 [o]
2주 5일차 강의 [o]
인턴교육 직후 사수 도움 요청 업무 [o]
팀장님 지시 업무 [o]
중간/일일 업무 보고 작성 [o]
정기 팀/동기 스터디 모임 참석 및 성실도 [o]
https://firebase.google.com/?hl=ko
파이어베이스는 구글에서 개발한 모바일 및 웹 애플리케이션 개발 플랫폼으로, 다양한 기능을 제공합니다.
주요 기능으로는 데이터베이스, 인증, 호스팅, 스토리지, 애널리틱스, 푸시 알림 등이 있습니다.
이러한 기능들을 사용하여 애플리케이션을 개발하면서 파이어베이스를 선택한 이유는 몇 가지가 있습니다.
첫째
로, 파이어베이스는 개발 속도를 높여주는 다양한 기능을 제공합니다.
예를 들어, 실시간 데이터베이스를 사용하면 실시간으로 데이터를 동기화할 수 있고,
인증 기능을 통해 사용자 관리를 쉽게 구현할 수 있습니다.
둘째
로, 파이어베이스는 확장성이 뛰어나며 사용하기 간편합니다.
초기에는 작은 규모의 애플리케이션을 개발하더라도 나중에 규모를 키우거나 추가적인 기능을 추가하기 쉽습니다.
또한, 파이어베이스의 다양한 SDK와 도구를 통해 개발자들은 편리하게 애플리케이션을 개발하고 관리할 수 있습니다.
구글의 인프라를 기반으로 하고 있기 때문에 안정성이 뛰어나며, 사용자 데이터를 보호하기 위한 다양한 보안 기능을 제공합니다.
서버단을 걱정하지 않을 수 있어 클라이언트 부분 개발에 힘을 실을 수 있습니다.
https://www.scalablepath.com/front-end/single-page-applications
SPA는 단일 페이지 애플리케이션(Single Page Application)으로 서버에서 필요한 데이터만 비동기로 받아와서 동적으로 현재 화면에 다시 렌더링 하는 방식을 의미합니다. 사용자가 애플리케이션과 상호작용할 때마다 서버에 요청하여 전체 HTML 화면을 받아오는 방식이 아니라, 화면 렌더링을 로컬 PC에서 즉시 생성하므로 더 빠르게 화면 전환을 처리할 수 있어서 널리 사용되고 있습니다.
SPA가 ‘단일 페이지 애플리케이션’이라고 일컬어지지만, 하나의 페이지만 존재하는 애플리케이션을 의미하지는 않습니다. SPA(Single Page Application)도 여러 페이지가 존재하는데요. 다수의 페이지를 표시하는 데 있어서 과거 전통적인 방식으로 페이지 전환을 수행하지 않고, 마치 하나의 페이지인 것처럼 처리하는 기술을 의미합니다.
1.유저가 Website를 통해 요청을 보낸다.
2.Server는 'Ready to Render'. 즉, 즉시 렌더링 가능한 html파일을 만든다.(리소스 체크, 컴파일 후 완성된 HTML 컨텐츠로 만든다.)
3.클라이언트에 전달되는 순간, 이미 렌더링 준비가 되어있기 때문에 HTML은 즉시 렌더링 된다. 그러나 사이트 자체는 조작 불가능하다. (Javascript가 읽히기 전이다.)
4.클라이언트가 자바스크립트를 다운받는다.
5.다운 받아지고 있는 사이에 유저는 컨텐츠는 볼 수 있지만 사이트를 조작 할 수는 없다. 이때의 사용자 조작을 기억하고 있는다.
6.브라우저가 Javascript 프레임워크를 실행한다.
7.JS까지 성공적으로 컴파일 되었기 때문에 기억하고 있던 사용자 조작이 실행되고 이제 웹 페이지는 상호작용 가능해진다.
User가 Website 요청을 보냄.
CDN이 HTML 파일과 JS로 접근할 수 있는 링크를 클라이언트로 보낸다.
CDN : aws의 cloudflare를 생각하면 됨. 엔드 유저의 요청에 '물리적'으로 가까운 서버에서 요청에 응답하는 방식
클라이언트는 HTML과 JS를 다운로드 받는다.
(이때 SSR과 달리 유저는 아무것도 볼 수 없다.😡)
생략
다운이 완료된 JS가 실행된다. 데이터를 위한 API가 호출된다.
(이때 유저들은 placeholder를 보게된다. )
서버가 API로부터의 요청에 응답한다.
API로부터 받아온 data를 placeholder 자리에 넣어준다. 이제 페이지는 상호작용이 가능해진다.
장점:
초기 로딩 속도가 빠릅니다: 서버에서 완성된 HTML을 클라이언트에 전달하므로 초기 페이지 로딩이 빠릅니다.
SEO(Search Engine Optimization)에 유리합니다: 검색 엔진은 HTML을 분석하여 콘텐츠를 쉽게 인덱싱할 수 있습니다.
모든 사용자에게 동일한 콘텐츠를 제공합니다:
클라이언트의 자바스크립트 환경에 의존하지 않으므로 일관된 사용자 경험을 제공합니다.
단점:
서버 부하가 증가할 수 있습니다:
매번 요청에 대해 서버에서 HTML을 생성하므로 서버 부하가 증가할 수 있습니다.
클라이언트 상호작용이 제한될 수 있습니다:
초기 로딩 이후에도 서버 요청이 필요한 상호작용이 있는 경우에는 추가적인 네트워크 요청이 필요합니다.
장점:
클라이언트 사이드에서 렌더링되므로 서버 부하가 감소합니다:
서버는 초기 요청에만 HTML을 제공하고 이후에는 클라이언트에서 렌더링되므로 서버 부하가 감소합니다.
더 나은 사용자 경험을 제공할 수 있습니다:
클라이언트 사이드에서 렌더링되므로 페이지 전환이 빠르고 부드럽게 이루어질 수 있습니다.
단점:
초기 로딩 속도가 느릴 수 있습니다:
초기에는 빈 페이지가 보여지고, 자바스크립트 파일을 다운로드하고 실행해야 페이지가 완전히 렌더링됩니다.
SEO에 불리합니다:
검색 엔진은 자바스크립트를 실행하지 않거나 실행하기 어려울 수 있으므로 SEO에 불리할 수 있습니다.
부족한 점 : firebase에 RealtimeDB를 사용하려 공식문서를 읽고 적용하는데 어려움을 느낌 (공식문서를 보는 능력을 길러야 할듯함.)
스스로 시도해본 것들 :
Javascript만을 활용한 샘플 SPA 어플리케이션 작성
<!-- example.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SPA Sample</title>
</head>
<body>
<header>
<nav>
<ul>
<li><a href="/example1.html">example1</a></li>
<li><a href="/example2.html">example2</a></li>
<li><a href="/example3.html">example3</a></li>
</ul>
</nav>
</header>
<div id="content"></div>
<script src="example.js"></script>
</body>
</html>
const templates = {
home: `<h1>example1 Page</h1><p>Welcome to the example1 page!</p>`,
about: `<h1>example2 Page</h1><p>Welcome to the example2 page!</p>`,
contact: `<h1>example3 Page</h1><p>Welcome to the example3 page!</p>`,
};
const renderPage = () => {
const path = window.location.pathname;
let pageContent = "";
if (path === "/example1.html") {
pageContent = templates.home;
} else if (path === "/example2.html") {
pageContent = templates.about;
} else if (path === "/example3.html") {
pageContent = templates.contact;
} else {
pageContent =
"<h1>404 Not Found</h1><p>Sorry, the page you are looking for does not exist.</p>";
}
const contentDiv = document.getElementById("content");
contentDiv.innerHTML = pageContent;
}
renderPage();
window.addEventListener("popstate", renderPage);
firebase Realtime DB를 활용한 객체를 이동하여 실시간으로 좌표를 DB에 저장하는 로직 구현
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>GatherTown Example</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div id="character"></div>
<script type="module" src="app.js"></script>
</body>
</html>
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.0.2/firebase-app.js";
import { getDatabase, ref, set, onValue, } from "https://www.gstatic.com/firebasejs/9.0.2/firebase-database.js";
const firebaseConfig = {
apiKey: "your firebase apiKey",
authDomain: "your firebase authDomain",
databaseURL: "your firebase databaseURL",
projectId: "your firebase projectId",
storageBucket: "your firebase storageBucket",
messagingSenderId: "your firebase messagingSenderId",
appId: "your firebase appId"
};
const app = initializeApp(firebaseConfig);
const database = getDatabase(app);
const characterRef = ref(database, "characters/myCharacter");
const character = document.getElementById("character");
let characterPosition = { x: 0, y: 0 };
const updateCharacterPosition = (x, y) => {
characterPosition.x = x;
characterPosition.y = y;
character.style.left = x + "px";
character.style.top = y + "px";
set(characterRef, {
x: x,
y: y,
});
}
updateCharacterPosition(0, 0);
character.addEventListener("click", function () {
const newX = Math.floor(Math.random() * window.innerWidth);
const newY = Math.floor(Math.random() * window.innerHeight);
updateCharacterPosition(newX, newY);
});
const moveCharacter = (deltaX, deltaY) => {
const newX = characterPosition.x + deltaX;
const newY = characterPosition.y + deltaY;
if (newX >= 0 && newX <= window.innerWidth && newY >= 0 && newY <= window.innerHeight) {
updateCharacterPosition(newX, newY);
}
}
document.addEventListener("keydown", function(event) {
if (event.key === "ArrowUp") {
moveCharacter(0, -10);
} else if (event.key === "ArrowDown") {
moveCharacter(0, 10);
} else if (event.key === "ArrowLeft") {
moveCharacter(-10, 0);
} else if (event.key === "ArrowRight") {
moveCharacter(10, 0);
}
});
onValue(characterRef, (snapshot) => {
const newPosition = snapshot.val();
updateCharacterPosition(newPosition.x, newPosition.y);
});
해결 내용 : firebaseConfig를 통해 firebase 연결하고 초기화해서 좌표를 업데이트하여 해결함
알게된 점 : onValue 메서드를 활용해 업데이트를 하는 과정에 대해서 알게됨
헷갈리거나 실수한 점 : Node js에서 사용하던 습관으로 process.env를 사용해 config를 작성했는데 그것은 Node js에서만 사용가능하다라는 것을 알게됨
회고 : 2주 5일차를 진행하면서 기초를 다지는 주차가 마무리되고 있다. 다음주 부터는 주특기 주차로 넘어가는데 주특기에 대해 깊게 알 수 있는 주차인 만큼 더욱 기대가 된다.