원래는 HTML, CSS로만 웹페이지를 만들던 시절이 있었습니다.
그러다가 좀 동적으로 페이지 내용이 변경되고 interactive한 웹페이지를 만들기 위해 Javascript가 등장하게 됩니다.
그 이후에 많은 브라우저들이 Javascript 엔진을 탑재하기 시작했는데요
크롬에서 만든 JIT(Just-in-time compliation, 프로그램을 런타임에 기계어로 번역하는 컴파일 기법, 실행 시점에서 인터프리트 방식으로 기계어 코드를 생성하면서 그 코드를 캐싱하여, 같은 함수가 여러 번 불릴 때 매번 기계어 코드를 생성하는 것을 방지한다.)을 지원하는 V8 엔진이 굉장히 성능이 좋았습니다.
Edge도 원래는 Chakara를 사용하다가 V8 엔진으로 변경했습니다.
Node.js®는 Chrome V8 JavaScript 엔진으로 빌드된 JavaScript 런타임입니다.
공식문서에 나와있는 설명입니다.
런타임이라고 하니까 무슨 말인지 잘 모르겠지만 쉽게 말하자면, V8 엔진이 탑재된 JavaScript를 실행할 수 있는 실행기입니다.
브라우저 환경에서 벗어난 다른 환경에서도 JavaScript를 실행할 수 있게 만들어주는 것이 Node.js 입니다.
Node.js는 플랫폼 독립적이기 때문에 Node.js가 설치된 모든 곳(Windows, Mac, Linux)에서 JavaScript를 실행할 수 있습니다.
브라우저 환경에서 실행할 수 있는 JavaScript는 태생이 그랬습니다. 그런데 Node.js를 사용하면 브라우저 외의 환경에서도 JavaScript를 실행할 수 있게 됩니다.
덕분에 Server Side Application도 만들 수 있게 된 것입니다.
하나의 언어로 front와 back-end를 구성할 수 있다는 장점이 있습니다.
Uber, Netflix, PayPal 등 이미 큰 회사에서도 노드를 이용하여 enterprise급 서버 사이드 애플리케이션을 구성하고 있습니다.
즉, 이미 Node.js를 이용해서도 품질 높은 백엔드 구성이 가능하다는 것이 증명되었다고 볼 수 있습니다.
Node.js는 배우기 쉽습니다. 또한 큰 커뮤니티가 존재하고 많은 수의 라이브러리들을 패키지 매니저를 통해 설치할 수 있습니다.
즉, 낮은 러닝 커브와 많은 라이브러리를 통해 높은 생산성을 낼 수 있습니다.
크롬 브라우저의 V8 엔진은 C++로 작성되어있으며 성능이 좋습니다. Node.js는 V8 엔진을 탑재하고 있습니다.
Node.js 애플리케이션은 기본적으로 싱글스레드로 동작합니다.
입출력 작업(파일, 네트워크, DB 등)을 I/O 작업이라고 합니다.
Node.js는 Non-Blocking I/O를 지원합니다. 입출력 작업 시 작업이 완료될 때까지 스레드가 기다릴 필요가 없습니다.
우리의 애플리케이션은 싱글 스레드로 동작합니다.
Node에서 제공하는 API를 호출하여 비동기 작업을 수행할 수 있고, 동시에 콜백을 전달해서 특정 이벤트가 발생했을 때 우리가 전달한(등록한) 콜백(핸들러)를 실행하도록 요청할 수 있습니다.
우리가 작성한 애플리케이션은 애플리케이션 레벨에서 실행됩니다.
싱글스레드로 동작하는 것은 우리가 작성한 애플리케이션입니다. Node.js 런타임 환경에서는 멀티스레딩을 사용합니다.
우리가 Node에서 지원하는 API를 사용하여 비동기 작업을 할 수 있는 이유입니다.
싱글스레드라고 이야기 하는 이유는 우리가 작성한 프로그램에서 우리가 컨트롤하는 스레드가 하나 뿐이기 때문입니다.
비동기 작업을 수행하게 되면 Node내부에서 해당 작업을 수행하고 작업이 완료되면 우리가 등록한 콜백을 태스크 큐에 집어 넣습니다.
이벤트 루프는 태스크 큐를 계속 확인하면서 태스크 큐에 작업이 남아있나 확인하고, 콜 스택이 비었을 때 태스크 큐에 남아있는 작업을 콜 스택으로 불러들여 콜백을 수행합니다.
노드로 작성한 애플리케이션은 싱글스레드로 동작하기 때문에 많은 CPU 연산이 동반되는 무거운 작업(Image Resizing, Algorithme 작업)을 하기 적합하지 않습니다.
콜백 또한 결국 메인으로 동작하는 싱글스레드에서 수행됩니다.
따라서 많은 I/O 작업을 수행하는 서버에 적합하며, 무거운 CPU 연산을 해야한다면 AWS Lambda, Google Cloud Function, 혹은 해당 작업을 수행하는 서버를 따로 만들어서 구성하는 것이 보통입니다.