0. 의문의 시작
최근 같은 전공의 대학 동기들을 만나 술자리를 가지던 중 Ajax와 XMLHttpRequest에 대한 대화를 나누게 되었고, 아래 내용에 대해선 모두 의견의 차이가 없었다.
- Ajax 는 비동기 통신을 위한 하나의 '프로그래밍 기법'이며, javascript 진영에서는 이 기법을 구현하기 위해 XMLHttpRequest를 사용한다.
- 이 기법과 DOM API를 사용하여 화면 전체를 다시 그리지 않아도 된다.
- XMLHttpRequest는 HTTP 프로토콜을 사용하여 서버와 통신한다.
그러나 아래 대화까지 도달했을 때, 모두 제대로 설명할 수 있는 사람이 없었다.
- XMLHttpRequest의 원리?
- 언어 레벨과 프로토콜 레벨 사이에, 이것을 실행시켜주는 것은 무엇?
결국 다음과 같은 결론을 내고 대화는 마무리가 되었다.
- XMLHttpRequest 객체를 브라우저나 Node.js와 같은 엔진(런타임)이 실행한다
집에 와서도 찜찜함이 남아있어 해당 내용을 좀 더 세부적으로 공부해야겠다는 생각이 들어 이 포스팅을 적게 되었다.
1. 그래서 정답은 무엇인가
- 비동기 통신을 위한 XMLHttpRequest는 브라우저 내 내장된 자바스크립트 엔진에 의해 실행되며, HTTP 프로토콜로 변환되어 서버로 전송된다.
- 결국 브라우저의 내장 API에 대한 지식이 부족했던 것.
- Node.js에서 실행되는 Javascript의 경우, XMLHttpRequest 를 지원하지는 않고 http, request, axios와 같은 모듈을 별도로 설치하여 이와 같은 역할을 수행할 수 있다.
2. XMLHttpRequest 와 Ajax에 대하여
Ajax는 XMLHttpRequest 를 wrapping한 별도의 라이브러리?
- Ajax를 일부 주니어 개발자들은 'XMLHttpRequest 를 wrapping한 별도의 라이브러리'라고 생각하고 있지만, 이는 틀린말이다.
- 아마 JQuery의 $.ajax를 사용하다보니 그렇게 생각할 수 있다.
- JQuery의 github를 보면 JQuery.ajax()는 XMLHttpRequest 를 wrapping했다는 말이 맞지만 이는 JQuery.ajax()이지 Ajax가 아니다.
- Ajax는 라이브러리나 프레임워크가 아닌, 서버와 비동기 통신하기 위한 프로그래밍 기법이다.
- 그래서 이 기법을 꼭 XMLHttpRequest를 사용하여 구현할 필요는 없다.
// fetch()를 사용한 Ajax 프로그래밍 예제
fetch('https://example.com/data.json')
.then(response => response.json())
.then(data => {
// 데이터를 화면에 표시하는 로직
console.log(data);
})
.catch(error => {
console.error('데이터 가져오기 실패:', error);
});
XMLHttpRequest말고도 Web Browser에 내장되어있는 API 종류들?
- 아래와 같은 내장 API들이 존재한다.
1. canvas - javascript 및 HTML을 통해 그래픽 요소를 그리는 데 사용되며 주로 2D 그래픽을 다룬다.
2. Storage, Cookie - 브라우저 내 할당 된 메모리나 접속한 클라이언트의 하드디스크 등에 저장된다.
3. DOM API - HTML형태로 작성된 내용을 객체로 표현해주고, 이를 조작한다.
4. Fetch API : XMLHttpRequest 대신 사용할 수 있는 새로운 API로, Promise를 이용하여 데이터를 주고받는 기능을 제공.
5. Web Workers : 백그라운드 스레드에서 JavaScript 코드를 실행 가능하도록 함.
6. Web Socket : 실시간 양방향 통신을 지원하는 기능 제공.
- 이 외에도 정말 다양한 API들을 제공한다. 확인하고 싶으면 아래 페이지를 접속해보면 된다.
https://developer.mozilla.org/en-US/docs/Web/API
Web APIs | MDN
When writing code for the Web, there are a large number of Web APIs available. Below is a list of all the APIs and interfaces (object types) that you may be able to use while developing your Web app or site.
developer.mozilla.org
- 또한 WebRTC API의 경우 Chrome과 Firefox에서는 거의 완전히 동일한 기능을 제공하지만, Safari에서는 일부 기능이 제한되는 등 웹 브라우저들마다 세부적으로 동작하는 방식이 다르고, 지원하는 API목록도 다를 수 있다.
- 아래는 fetch API를 지원하지 않는 오래 된 브라우저에서도 서버와 통신하기 위해 코드를 분기처리하는 간략한 예제이다.
if (window.fetch) {
// fetch API 사용
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
} else {
// XHR 객체 사용
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data');
xhr.onload = () => {
if (xhr.status === 200) {
console.log(xhr.responseText);
} else {
console.error('Error!', xhr.statusText);
}
};
xhr.onerror = () => console.error('Error!');
xhr.
- 이렇게 매번 분기처리를 하기에는 번거로우므로 babel, polyfill등을 사용하여 오래 된 브라우저와 모던 브라우저 간 동작성을 같게 한다.
- 대부분의 Browser는 웹 표준을 지키면서 개발되고 업데이트되므로, 개발에 필요한 API들은 대부분 사용하는 방식이 비슷하다.
Ajax 덕분에 화면 전체를 새로 렌더링하지 않아도 된다?
- 내 생각에는 틀린 말이다.
- 정확히 말하면, DOM API 덕분에 화면 전체를 렌더링하지 않아도 되는것이다.
// DOM API를 사용한 화면 일부 업데이트
document.getElementById('update-button').addEventListener('click', function() {
var container = document.getElementById('container');
var paragraph = container.getElementsByTagName('p')[0];
// 새로운 텍스트를 생성하여 화면에 업데이트
var newText = document.createTextNode('화면이 업데이트 되었습니다.');
paragraph.replaceChild(newText, paragraph.firstChild);
});
- 그러면 왜 Ajax 덕분에 화면 전체를 새로 렌더링하지 않아도 된다는 말이 나왔을까?
- 그건 아마도 아래와 같은 이유일 듯 싶다.
1. XMLHttpRequest와 같이 '다양한 형태의 데이터를 응답으로 받을 수 있는' 방법이 나오기 이전에는 요청을 보내면 응답으로 HTML 전체를 받는 형태로 동작하였고, 이 말은 곧 전체를 다시 렌더링한다는 의미이다. XMLHttpRequest는 XML 형식 뿐만 아니라 JSON을 포함한 대부분의 포맷으로 원하는 데이터만 응답으로 받을 수 있다.
2. Ajax와 같이 '비동기 통신'이 가능한 방법을 사용하지 않는다면(동기 통신으로 데이터를 받는다면) 요청을 보낸 뒤 응답이 오기 전까지 브라우저는 동작을 멈출 것이다. 그 후 브라우저 자체로 설정되어있는 Time-Out에 걸린다면, 결국 화면 전체를 새로 렌더링 해야하는 상황이 발생한다.
위 두 가지 이유로 'Ajax 덕분에 화면 전체를 렌더링하지 않아도 된다'는 말이 나온 것 같다.
전통적인 SSR과 모던 SSR의 차이
- 위에서 언급했듯이, XMLHttpRequest와 같은 원하는 포맷의 데이터를 받을 수 있는 방법이 나오기 이전에는 HTML 전체를 다시 받아와 렌더링하였다.
- 이는 곳 Server Side Rendering 방식이라는 말인데, 현대에도 React 진영의 Next.js, Vue.js 진영의 Nuxt.js 와 같은 SSR 프레임워크가 있고, SEO 등의 이유로 이를 선호하는 추세이다.
- 두 가지 SSR은 무엇이 다른것일까?
- 고전적인 Server Side Rendering에서는 서버에서 HTML 전체를 생성하여 브라우저에 전송한다.
- 브라우저는 HTML을 받으면 즉시 화면에 렌더링하고, 화면에 그려진 이후에 JavaScript 파일을 다운로드하고 실행한다.
- 이는 초기 로딩 속도가 빠르지만, 서버가 매번 전체 HTML을 생성하여 전송해야 하므로 서버 부하가 발생한다.
- 반면에 현대적인 Server Side Rendering에서는 서버에서는 HTML의 일부분과 필요한 JavaScript 파일을 전송하고(하이브리드 방식이라고도 한다), 브라우저는 JavaScript를 실행하여 화면을 완성한다.
- 이는 초기 로딩 속도가 상대적으로 느리지만, 클라이언트 측 JavaScript의 실행을 활용하여 서버의 부하를 줄일 수 있고, 필요한 부분만 변경되므로 사용자 경험 측면에서도 긍정적이다.
-퍼가실 때는 출처를 꼭 같이 적어서 올려주세요!
'Dev > [Javascript]' 카테고리의 다른 글
[Javascript] 자바스크립트의 컴파일에 대하여 (0) | 2023.07.14 |
---|---|
[Javascript] Module과 Module 시스템에 대해서(feat. CommonJS, ES6) (0) | 2023.03.13 |
[javascript] 렉시컬 환경(Lexical Environment) (0) | 2023.01.17 |
[javascript] 스코프(Scope) (0) | 2023.01.16 |
[javascript] 실행 컨텍스트(Execution Context) (1) | 2023.01.10 |