결론 : JavaScript는 (해석 엔진에 따라 컴파일하기도 하는) 인터프리터 언어로 볼 수 있다.

 

Q. JavaScript는 인터프리터 언어라는데 맞나요?

A. 결론부터 말씀드리자면 인터프리터 언어로 분류되지만 해석 엔진에서 컴파일을 하기도 하는 신기한 놈입니다. 인터프리터 언어로 분류되는 이유는 console에서 스크립트를 작성해 실행하는 데에 컴파일이 필요하지 않기 때문입니다. 하지만, V8과 같이 대표적인 JS 엔진에서 컴파일이 필요한 경우, 컴파일을 진행합니다. 

 

1995년, 자바스크립트는 - 단지 HTML page를 동적으로 만들고 싶어서 - 만들어진 아주 라이트한 인터프리터 언어였습니다. 스크립트 언어인 JavaScript는 해석/동작을 위한 엔진이 요구되었고, 구글이 구글맵스(Google Maps)를 개발할 당시 JavaScript 엔진에 한계를 느꼈습니다. 웹 페이지 로드에 5초 이상 넘어가면 피로감이 들기도 했고, 개발되면 될수록 유저간의 많은 인터렉션이 필요하게 되었기 때문입니다.

 

2009년, 이에 답답함을 느낀 구글은 현재까지도 사용되는 V8 엔진(chrome, Node)을 출시했습니다.

 

 

컴파일러(Complier) vs 인터프리터(Interpreter)

컴파일러와 인터프리터 언어의 가장 큰 차이점은 컴파일(Compile)을 하느냐 안하느냐 입니다. 그럼 먼저 컴파일은 무엇일까요?

 

컴파일러(Complier)


 


컴파일(Compile) : 고급언어를 저급언어로 해석하는 것, 곧 0과 1밖에 모르는 컴퓨터에게 인간의 언어를 이해시키는 것.

 

컴파일은 쉽게 말하면 위와 같지만, 인간이 알아볼 수 있도록 프로그래밍된 소스 코드를 0, 1로 이루어진 오브젝트 코드로 변환하는 과정입니다. 컴파일의 과정은 다음과 같습니다.

 

 이와 같이, 컴파일러는 사람이 알아볼 수 있는 소스코드를 위와 같이 4단계에 걸쳐 컴퓨터가 알아보기 편한 실행코드로 변환하는 것을 말합니다. 컴파일하는 시간은 소요되지만, 런타임 환경에서는 빠르게 동작합니다. 예를 들어, 반복문(for문, while문 등) 컴파일을 한 번 하면, 입력값이 몇 개든 빠르게 실행시킵니다. 또한 컴파일을 실행하며 Error를 검출하기에 실제 동작에서의 에러가 적은 편입니다.

 컴파일러 언어의 예로는 C, C++, C#, JAVA 등이 있습니다.

 

 

인터프리터(Interpreter)


 반면, 인터프리터는 고급언어를 바로 그리고 직접 실행합니다. 소스코드를 한 줄씩 즉각적으로 실행하기 때문에 컴파일러와 달리 별도의 컴파일 과정이 없습니다. 어떻게 보면 중간과정이 없기에 참으로 편리하다고 생각이 들 수 있지만, 한줄씩 읽어 실행한다는 점에서 컴파일러보다 실제로는 비효율적입니다.

 

 반복문(for, while 등)에서 컴파일러는 컴파일 후에 굉장한 속도로 계산을 진행합니다. 하지만 인터프리터는 한줄한줄 읽어 실행하기 때문에 반복 횟수(n)만큼 반복문을 구간반복합니다. 그래서 실제로 비효율적이라고 할 수 있지요.또한 컴파일을 하지 않기 때문에 분석을 진행하다가 오류가 발생하면 분석을 멈추고 오류를 알려줍니다.

 인터프리터 언어의 예로는 JS, Python, R 등이 있습니다.

 


 

그럼 다시 본론으로 돌아가서, 자바스크립트는 인터프리터 언어인가?

 

JavaScript의 엔진


 JS의 대표적인 엔진은 다음과 같습니다.

  • V8 엔진 : 구글 개발, 크롬/노드에서 사용. Ignition(인터프리터) + TurboFan(컴파일러)
  • Rhino 엔진 : 모질라 개발. 인터프리터, 컴파일러(부분적으로 JAVA Byte Code로 컴파일)
  • Monkey 엔진 : 최초의 JS 엔진, Firefox에서 사용. 컴파일러(JIT: Just In Time) 사용

 위와 같이, 대부분 JS의 엔진에는 컴파일러가 포함되기도, 인터프리터가 아예 없기도 합니다.

 

 

Chrome V8 엔진 (Last Updated - 2017)


 

V8 엔진은 출시 이후 여러 번의 업데이트를 겪었습니다. 그 과정에서 생성되거나 사라진 컴파일러/인터프리터가 있었습니다. 우리는 2017년 최신 업데이트 된 V8에 대해 간단하게 알아보겠습니다.

 

 

1. 엔진이 실행할 JS 파일을 받습니다.

2. Parser에서 파싱(소스 코드 분석)을 진행합니다.

3. AST(Abstract Syntac Tree : 추상 구문 트리)를 구축하고 결과물을 Ignition(이그니션)에게 보내줍니다.

4-1. 인터프리터인 Ignition이 코드를 읽으며 Bytecode로 변환합니다. (실제 작동)

4-2. 컴파일러인 TurboFan이 자주 사용되는 코드 구문(반복문 등)을 최적화된 코드로 다시 컴파일됩니다.

 

 가장 대표적인 V8엔진을 포함해 최신 자바스크립트 엔진은 모두 컴파일러와 인터프리터를 포함하고 있다고 볼 수 있습니다. 컴파일러와 인터프리터의 장점을 모두 취하기 위해서죠. 아주 똑똑한 방법으로 볼 수 있습니다.

 

 

 

결론 : JavaScript는 (해석 엔진에 따라 컴파일하기도 하는) 인터프리터 언어로 볼 수 있다.

 

 

 

 

 

 

코드를 모든 사람들이 보기 편하게 짜는 것은 프로그래머의 능력입니다.

컨벤션을 익혀서 코드를 짜는 시점에 예쁘게 짜는 것도 좋지만, 적절한 도구를 사용해 예쁘게 만드는 방법도 좋습니다.

 

Mac에서 코드를 짜는 데 도움이 될만한 단축키

 

Extension(확장 프로그램) Prettier

보통 Beautify라는 확장프로그램이 많이 사용됐지만 더 이상 업데이트가 되지 않아 권장되지 않습니다.

다음으로 많이 쓰이는 Prettier 확장프로그램인데요. 사용법은 다음과 같습니다.

 

확장프로그램 -> Prettier 검색 -> Install

-> cmd+shift+P

-> Format Document (전체 문서에 적용)  /  Format Selection (선택영역에만 적용)

 

 

'Front-End > HTML, CSS' 카테고리의 다른 글

HTML의 tag  (0) 2022.11.21
HTML과 CSS, JavaScript 연결(선언)하기 (+비동기방식 async/defer)  (0) 2022.10.28

HTML과 CSS, JavaScript는 웹 페이지를 구성하는 요소로 각각의 맡은 바 역할이 있고, 서로 유기적으로 상호작용합니다.


[각자 맡은 역할]

  • HTML(Hyper Text Markup Language) : 웹 구조를 이룬다.
  • CSS(Cascading Style Sheets) : 웹 시각적 요소를 적용한다.
  • JS(JavaScript) : 웹의 동적 처리를 수행한다.

그러면 따로 떨어져있는 각 파일들은 어떻게 연결될 수 있을까요?

 

1개의 디렉토리 내 3개의 각 파일들

 

HTML - CSS 연결하기 (CSS 선언 방식)


HTML에 CSS를 적용(선언)하는 방법은 크게 3가지가 있습니다.

  1. 내부 스타일시트
  2. 외부 스타일시트
  3. 인라인 스타일

아래 예시를 보며 살펴보겠습니다.

 

 

내/외부 스타일시트 및 인라인스타일

 

1. 내부 스타일시트 : <style> ~ </style>

 내부 스타일시트는 html에 <style> 태그를 직접 넣어서 스타일을 작성하는 방법입니다.

빠르고 간편하게 스타일을 적용할 수 있지만, 해당 html문서만 스타일을 적용할 수 있어 코드가 길어지면 유지관리가 어려워집니다.

 

2. 외부 스타일시트 : <link />

 외부 스타일시트는 <link /> 태그를 넣어 외부에 있는 CSS 파일을 가져오는 방법입니다.

@import를 사용해 직렬적으로 여러 CSS 파일을 적용할 수 있지만 CSS가 적용되는 시간이 늦어져 권장하지 않는 방법입니다. 

많은 css 파일을 적용할 경우 병렬형태로 적용하고자 하는 CSS를 <link />로 가져오는 것이 좋습니다. - 권장 방법!

 

3. 인라인스타일 

 인라인스타일은 요소의 style 속성에 직접 스타일을 작성하는 방법입니다.

선택자가 없어 편리해보이지만, 인라인스타일의 CSS 우선순위가 높아 유지보수에 어려움을 겪을 수 있습니다.

(향후 CSS 우선순위에 대해 알아보겠습니다.)

 

 

권장하는 방법 : <link> tag

 

 

HTML - JavaScript 연결하기 (JS 선언 방식)


HTML에 JavaScript를 연결(선언)하는 방법은 다음과 같습니다.

  1. 인라인스타일
  2. <head>에 .js 연결
  3. <body> 끝에 .js 연결
  4. <script>에 ansync / defer 속성 사용

1. 인라인스타일 : <script> ~ </script>

 

 CSS 인라인스타일과 같이 HTML 문서 내에서 <script> 태그로 바로 JS를 적용할 수 있습니다.

간단하게 원하고자 하는 부분에 JS를 적용할 수 있지만, CSS와 마찬가지로 JS가 복잡해지면 HTML의 가독성을 떨어뜨릴 수 있습니다.

 

2. <head>에 .js(외부 자바스크립트) 연결

 가장 대중적으로 쓰이는 방법입니다. DOM을 따라 반드시 순서대로 실행되어야 하는 경우 사용합니다.
순서 : .html 렌더 -> JS파일 로드 및 실행 -> 남은 html 렌더 및 실행
단점 : JS가 무거울수록 웹페이지 로드 시간이 오래 걸린다.

 

3. <body> 끝에 .js 연결

 1번 방법에서 단점을 보완한 방법입니다. <head>가 아닌 <body>태그 내에서 외부 JS파일을 가지고 옵니다.
순서 : .html 모두 실행 후 JS파일 로드 및 실행
단점 : JS의 동작이 많을수록 원하는 모양의 페이지를 한번에 불러올 수 없다.

 

4. <script>에 ansync / defer 속성 사용

 

 ansync와 defer로 script를 불러오는 방식을 비동기방식이라고 합니다.

비동기 방식은 왜 생겨났을까요?

 

일반적인 스크립트 로드 순서

 일반적으로 브라우저는 HTML 파일을 렌더한(읽고난) 후 위에서부터 순차적으로 한줄씩 해석합니다.

그러다 script(JS)를 만나면, 그 즉시 해당 script를 다 해석하기 전까지 나머지 HTML 렌더를 일시적으로 멈춥니다.

 

그러면 다음과 같은 문제가 발생합니다.

무슨 문제가 있을까? 직접 실행시켜보자.

1) 스크립트가 동작하지 않음 : 표시된 첫번째 스크립트(console.log)는 DOM에 <div> 엘리먼트가 부착되기 전에 접근하려 했기 때문에 동작하지 않습니다. 두번째 console.log 위에 <div> 엘리먼트가 부착되었기 때문에 두번째 스크립트는 정상적으로 작동합니다.

 

새로운 문제!

2) 홈페이지 멈춤 현상 : 만약 main.js를 읽는 시간이 20초가 필요하다고 가정해보겠습니다. 위와 같이 main.js를 읽는 도중 DOM 파싱이 멈추기 때문에 20초간 웹페이지는 멈춰있는 듯 보여 사용자에게 불편한 경험을 초래합니다. 이를 해결하기 위해 <body>태그 맨 마지막에 넣는 방법이 생겼지만, 이 역시 20초간 js파일을 해석한 뒤 웹페이지가 동작하기 때문에 해결되었다고 볼 수 없습니다.

 

이렇게 브라우저가 스크립트 파일을 병렬로 불러오는 방식으로 DOM렌더 과정을 막지 않게 선언하는 방법이 고안되었고,

이를 비동기 방식(async, defer로 선언)이라고 합니다.

 

  • anync
    <script src="main.js" async></script>	
    <script async src="main.js"></script>	
    <!--src 앞/뒤 상관없이 선언 가능.-->

 브라우저가 DOM을 구성하는 동시에 백그라운드에서 script를 불러올 수 있는 방법입니다.

그러나 로딩이 마치자마자 DOM 렌더를 멈추고 불러온 script를 해석하기 때문에 'DOM에 접근하는 스크립트를 불러오는 것은 적절하지 못합니다.' 결국 실행 순서가 보장되지 않는다는 단점이 있기 때문입니다.

 

 

  • defer - 권장 방식!!
    <script src="main.js" defer></script>
    <script defer src="main.js"></script>

 defer는 async과 비슷하게 동작되지만, DOM렌더를 전혀 방해하지 않고 병렬로 script를 로드합니다.

기본적으로 DOM의 모든 element에 접근할 수 있고, 실행순서도 보장되기 때문에 가장 범용적으로 사용할 수 있습니다.

쉽게 말해 모든 HTML이 실행된 뒤, JavaScript를 실행하므로 script가 어디에 있든 html에 적용할 수 있습니다.

script 파일끼리의 의존성이 있는 경우 defer를 사용하는 것이 좋습니다.

'Front-End > HTML, CSS' 카테고리의 다른 글

HTML의 tag  (0) 2022.11.21
코드를 예쁘게 만들기. (feat. Prettier, Beautify)  (0) 2022.11.04

+ Recent posts