클라이언트 플랫폼

GUI 아키텍처, MVC 패턴에 대해 알아보고, .NET, JAVA, macOS, iOS, Android 등의 플랫폼, 웹의 SPA 프레임워크, 크로스플랫폼 및 하이브리드 앱에 대해서 알아봅니다.
GUI 아키텍쳐, MVC, 플랫폼, 프레임워크, 크로스플랫폼, 하이브리드


플랫폼, 프레임워크

웹이라는 분야는 참 다양한 기술에 걸쳐 있다는 생각이듭니다. 수 많은 기술과 플랫폼, 프레임워크, 라이브러리가 등장하고 또 잊혀지고 있습니다. 그런 와중에 이건 뭐고, 저건 뭔지, 그 본질적인 성격을 구분 할 수 있고, 앞으로 배우고 싶은 것을 선택 할 수 있는 여지를 가질 수 있으면 좋겠습니다.

이 마지막 파트 두 챕터의 제목을 클라이언트-서버, GUI-CLI, 백엔드-프론트엔드 … 어떻게 정할까 고민을 했습니다. 몇가지 플랫폼들에 대해서 생각을 해보겠습니다.

Windows GUI 프로그램은 클라이언트라고 해야되나요?

Windows GUI Socket ServerWindows GUI Socket Server

소켓 서버를 열 수도 있는데요…

Android나 iOS 앱은 GUI라고 해야하나요?

iOS SSH AppsiOS SSH Apps

앱스토어에 SSH라고 검색하면 터미널 같이 생긴 앱이 수도 없이 나오는데요…

그럼 Node.js는 백엔드, CLI 플랫폼이라고 해야되나요?

Atom Editor (by Electron)Atom Editor (by Electron)

Node.js로도 GUI를 띄울 수 있는데요…

플랫폼에 대한 종속성을 탈피하고자 강조하다보니 오히려 혼란을 줄 수도 있을 것 같다는 생각이듭니다. 소 잡는 칼, 닭 잡는 칼이 따로 있듯이 당연히 플랫폼별로 주요한 타겟이 되는 응용 분야가 있습니다. 하지만 아래에서 소개하는 내용 때문에 이 플랫폼은 클라이언트용이구나, 서버용이구나, GUI용이구나 등… 선입견이 생기지 않길 바랍니다.

이 챕터에서는 최종사용자(End-User)용 GUI 클라이언트 프로그램 작성에 주로 쓰이는 플랫폼과 프레임워크를 소개합니다. 우선 몇가지 용어를 정리해보겠습니다.

OS, 플랫폼

OS는 프로그램을 실행하고 자원을 관리하며, 하드웨어와 소프트웨어간의 인터페이스를 제공해주는 프로그램입니다. 그리고 플랫폼(Platform)은 소프트웨어를 개발하고 실행하는 환경을 의미합니다.

플랫폼플랫폼

플랫폼은 각종 생태계를 소프트웨어의 개발 및 실행의 관점에서 구분하는 용어라고 생각하면 좋겠습니다. Node.js, .NET, JAVA, 웹 브라우저 등을 플랫폼으로 볼 수 있겠습니다. 물론 Windows, iOS, Android 등 OS 자체도 하나의 플랫폼으로 볼 수 있겠습니다.

라이브러리, 프레임워크

독립적으로 특정 기능을 수행하는 코드를 라이브러리라고 부릅니다. jQuery를 JavaScript 라이브러리라고 할 수 있겠습니다.

반면 Express.js는 Node.js의 웹 서버 프레임워크(Framework)라고 부릅니다. 프레임워크는 말그대로 특정 목적을 가진 소프트웨어의 뼈대를 구현한 코드입니다. 그 뼈대에 살을 붙혀가면 손쉽게 프로그램을 완성 할 수 있는 이미 실행 준비까지 완료된 코드입니다.

제어의 반전제어의 반전

이 때문에 프레임워크를 사용하려면 제공되는 문서 등을 통해 프레임워크의 작동 원리, 구성 요소, 커스터마이징, 설정 등을 충분히 이해할 필요가 있습니다. 짜여진 틀대로 개발자가 코드를 작성하면 프레임워크가 작동하면서 개발자의 코드를 호출하기 때문입니다. 이러한 디자인 패턴을 제어의 반전(IoC; Inversion of Control)이라고 부르기도 합니다.

반면에 라이브러리는 자잘한 작업을 돕는 세련된 도구의 느낌이 큽니다. 개발자가 직접 프로그램의 흐름을 관리하면서 필요에 따라 라이브러리를 호출하게 됩니다.

모듈, 라이브러리, 패키지

  • 모듈(Module)
    독립적인 namespace를 갖는, 즉 격리된 스코프에 있는 객체들의 집합.
  • 라이브러리(Library)
    다른 라이브러리나 프로그램에서 쓰일 수 있는 특정한 기능을 하는 모듈들의 집합.
  • 패키지(Package)
    라이브러리든 프로그램이든 소스코드를 배포하기 위한 묶음.

용어를 최대한 명확하게 구분 할 필요는 이후에 필요한 코드나 지식을 찾을 때 검색을 정확하기 하기 위함에 있습니다.

GUI 아키텍쳐

MS WordMS Word

텍스트 편집기를 통해서 GUI 프로그램의 일반적인 구조에 대해서 생각해봅시다.

상태, 데이터

GUI 프로그램은 사용자의 조작에 따라서 그 모습이 변합니다. 예를 들어 메뉴가 열리고, 창이 열리고, 텍스트가 스크롤됩니다. 이때 어떤 메뉴가 열리고 닫혔는지, 스크롤바 위치가 어딘지 등 프로그램의 상태(status)를 기록 할 필요가 있습니다.

그리고 편집 중인 텍스트 파일처럼 데이터라고 부르기에 적합한 값들이 있습니다. 상태와 데이터의 구분은 화면을 구성하기 위한 필요한 부수적인 값, 프로그램에서 다루고자하는 본질적으로 값 정도가 되겠습니다.

화면

편집기 화면을 그려봅시다. 가장 먼저 창 제목, 최소화 버튼 등을 포함한 윈도우 창부터 생성해야 겠습니다. 배경을 칠하고, New, Open, Save 등을 포함한 메뉴를 생성하고. 이때 물론 폰트 파일을 로드하고 비트맵으로 변환해야 글자를 그래픽으로 표현 할 수 있겠습니다. 그리고 모니터에 화면을 부드럽게 표시하려면 그래픽카드의 메모리에 버퍼링을 … (기타 등등) … 이제 프로그램이 종료되지 않도록 무한히 반복문을 돌면서 적정한 시간 간격으로 화면을 갱신해줍니다. 마법처럼 그냥 되는 일이 없습니다.

그래픽을 낮은 수준에서 제어하는 게임의 GUI그래픽을 낮은 수준에서 제어하는 게임의 GUI

OS 응용프로그램 개발자가 그래픽카드의 메모리에 직접 접근해 모든 작업을 하도록 한다면 플랫폼의 룩앤필에 일관성을 유지하기 힘들고, 개발자들이 비지니스 로직에 집중하기 힘들겠습니다. 때문에 플랫폼 API는 일관성있는 테마로 UI 컴포넌트(Component)를 제공해줍니다.

.NET WPF Office 2010 Theme.NET WPF Office 2010 Theme

많은 플랫폼들에서 창, 메뉴, 버튼, 체크박스, 텍스트, 폼, 테이블 등을 제공합니다. 그래요. HTML Element들과 비슷합니다. 플랫폼별로 제공하는 컴포넌트와 그 역할이 대부분 비슷합니다. GUI 프로그램들은 이렇게 제공되는 UI 컴포넌트를 조합하고 데이터, 상태와 연결해서 화면을 구성하게 됩니다.

XML in AndroidXML in Android

그리고 대부분의 최신 GUI 플랫폼에서는 HTML으로 웹 브라우저에 DOM 객체를 생성했던 것처럼, XML 같은 마크업 언어를 이용해서 뷰를 선언적으로 프로그래밍 할 수 있도록 지원하기도 합니다.

JavaScript

let myText = document.createElement('input');
myText.type = "text";
myText.name = "myText";
myText.value = "hello";

let myPass = document.createElement('input');
myPass.type = "password";
myPass.name = "myPass";
myPass.value = "1234";

let myForm = document.createElement('form');
myForm.name = "myForm";
myForm.appendChild(myText);
myForm.appendChild(myPass);

document.body.appendChild(myForm);

위 코드로 한눈에 DOM Tree가 상상되시나요?

HTML

<form name="myForm">
  <input type="text" name="myText" value="hello">
  <input type="password" name="myPass" value="1234">
</form>

위처럼 선언적인 언어로 뷰를 작성하면, 코드만으로 뷰의 계층 구조를 파악하며 화면을 상상하기 쉽고, 코드량을 줄이고, 프로그램의 뷰를 다른 코드로부터 분리 할 수 있습니다.

데이터 바인딩

이제 껍데기뿐인 화면에 연관된 상태 및 데이터를 서로 연결하면 되겠습니다. 예를 들어 편집중인 문서(데이터)를 텍스트 UI로 그려주고 싶습니다.

간단하게는 데이터가 변경되는 로직마다 UI 객체를 다시 그려주면 되겠습니다. 하지만 데이터의 변경 시점마다, 관련된 UI 요소들을 일일이 다시 그려주는 코드는 비지니스 로직과 화면 작업을 뒤섞이게하며, 생산성을 저해하기 쉽겠습니다.

Android 데이터 바인딩Android 데이터 바인딩

이 때문에 많은 GUI 프레임워크에서는 데이터 바인딩(Data Binding)이라는 이름으로 이를 자동화 해줍니다. 데이터 바인딩에는 몇가지 방식이 있습니다.

일회성 바인딩

일회성 바인딩은 최초에 UI 컴포넌트를 생성 할 때만 데이터를 화면에 반영하는 방식입니다. 별 다를 것 없이 데이터를 화면에 반영하는 기본적인 방식입니다. 이 방식은 프로그램 실행 이후로 변경될 가능성이 없는 데이터에 사용하기 적합합니다.

단방향 바인딩

단방향 바인딩단방향 바인딩

다음으로 유용한 단방향 바인딩(One-Way Binding)이 있습니다. 이 방식은 연결된 데이터가 변경될 때마다 자동으로 UI 컴포넌트를 갱신해줍니다. 예를 들어 편집중인 문서(데이터)가 변할 때, 자동으로 화면의 UI가 갱신되는 셈입니다. 이는 직접적인 로직으로부터만 데이터를 변경 할 때 쓰입니다.

또는 역으로 UI 컴포넌트가 변할 때, 메모리의 데이터를 변경하는 바인딩을 지원하기도 합니다. 예를 들어 화면의 UI를 조작하면, 편집중인 문서(데이터)가 변경되는 셈입니다. 이는 UI 조작으로만 데이터가 변경되는 경우에 쓰입니다.

양방향 바인딩

마지막으로 양방향 바인딩(Two-Way Binding)이 있습니다. 데이터의 변경을 UI가 반영하고, UI의 변경을 데이터가 반영하는 식입니다. 이는 로직에서도, UI 조작으로도 데이터가 변경되는 경우에 쓰입니다.

양방향 바인딩양방향 바인딩

번거로우니 전부다 양방향 바인딩을 하면 안될까요? 굳이 이렇게 여러 종류의 바인딩을 구현하는 것은, GUI 프레임워크가 바인딩을 구현하기 위해서 내부적으로 들이는 비용의 차이가 있기 때문입니다.

MODEL의 변화에 따른 DOM 조작MODEL의 변화에 따른 DOM 조작

플랫폼별로 데이터 바인딩의 구현 방식에 차이는 있지만, 쉽게는 프로그램이 스스로 바인딩된 데이터와 UI의 변화를 주기적으로 확인한다고 생각 할 수 있습니다. 때문에 꼭 양방향 바인딩이 필요한 경우가 아니라면, 단방향으로 바인딩하는 것이 GUI를 위해서 소모하는 비용을 아낄 수 있겠습니다. 또한 데이터의 흐름이 양방향이라면 대규모 프로그램의 경우 전체적인 데이터 흐름이 꼬여 잦은 버그를 만들기도 쉽습니다.

입력 및 이벤트 제어

마지막으로 버튼을 클릭했을 때, 키보드를 눌렀을 때, 입력에 따라서 특정한 로직을 수행 할 필요가 있습니다. JavaScript에서 EventListener를 통해서 마우스 클릭이나 키보드 입력을 제어했듯이, 많은 플랫폼에서는 UI에 대한 이벤트 시스템을 제공합니다. 그리고 이벤트 시스템은 어떤 특별한 구현체라기보다는 단순한 아키텍쳐기에 플랫폼마다 비슷한 인터페이스를 갖습니다.

이벤트 기반 프로그래밍이벤트 기반 프로그래밍

UI를 가진 프로그램은 일반적으로 무한히 반복문을 돌면서 유저의 입력에 대한 이벤트(혹은 내부적으로 쓰이는 이벤트도)를 처리하는 방식으로 프로그램을 구성하게 됩니다. 입력으로부터 이벤트가 발생하면 상태와 데이터를 조작하고 그것이 반영된 화면이 갱신되는 흐름입니다. 이러한 GUI 아키텍쳐를 이벤트 기반 아키텍쳐(Event-Driven Architecture)라고 합니다.

MVC 패턴

이렇게 GUI 아키텍쳐가 간단하지 않기 때문에, 응용프로그램 개발에 플랫폼에서 제공하는 프레임워크를 이용(물론 바닥부터 직접 구현 할 수도 있습니다)하게 됩니다. 그리고 GUI 프레임워크들은 데이터, 화면과 상태, 입력 및 이벤트 제어라는 역할을 분리하여 고도로 추상화하는 방향으로 발전했습니다.

MVC 패턴MVC 패턴

  • 모델 (Model)
    프로그램에서 다룰 데이터들을 조작하고 추출 할 수 있도록 추상화한 요소.
  • 뷰 (View)
    뷰는 상태를 갖는 UI를 계층적으로 구성하며, 모델의 변화를 직접 감지하거나, 통보 받아서 UI에 반영하는 요소.
  • 컨트롤러 (Controller)
    컨트롤러는 플랫폼에 따라 다양한 모습으로 나타나며, 일반적으로 사용자의 입력과 이벤트를 받아서 뷰의 상태나 전역 상태를 변경하거나, 모델에 데이터 조작을 요청하는 요소.

그렇다면 MVC는 GUI 프로그램을 위한 아키텍쳐냐? 라고 한다면 또 그렇다고 하긴 힘들겠습니다. 그래픽 인터페이스의 유무를 떠나서 응용프로그램의 목적은 입력에 따라서 데이터를 조회 및 조작하는 것이 일반적입니다.

웹서비스의 MVC 패턴웹서비스의 MVC 패턴

일반적인 웹 서비스의 전체적인 흐름을 모식하면 위 그림과 같습니다. 서버는 사용자가 보낸 HTTP Request를 라우팅하여 데이터를 조회하거나 조작 한 뒤, 특정 뷰를 HTTP Response로 응답해줍니다. 이런 구조의 서비스에서도 코드를 MVC로 분리하고 추상화하여 생산성을 높힐 수 있습니다.

MVC 패턴은 개발자의 철학이나, 프로그램이 작성되는 플랫폼에 따라서 다양한 면모를 띌 수 있습니다. 또한 소프트웨어 디자인 패턴은 개발자들끼리도 이해하고 있는 바가 다른 경우가 많고, 실무에서는 여러 패턴이 뒤섞여가며 사용되는 것이 일반적입니다.

MVC와 그 파생MVC와 그 파생

하지만 공통적인 원칙은 데이터를 제어하는 로직, 화면을 제어하는 로직, 그 외의 로직을 분리하여 작성하고 재사용하는 것입니다. 이는 역할을 분담하고, 코드의 집중도를 분배하고, 재사용성을 높히기 위한 다양한 시도라고 생각하시면 좋겠습니다.

크로스플랫폼

이처럼 GUI 프로그램을 바닥부터 만드는 것은 상당히 많은 비용이 필요하기에, GUI 프레임워크를 제공하는 플랫폼에서 응용프로그램을 개발하는 편이 좋겠습니다. 각종 플랫폼들은 개발자들을 끌어들이기 위해서 경쟁적으로 풍부한 API와 프레임워크를 제공합니다.

GUI 플랫폼 및 프레임워크

OS/플랫폼프레임워크
WindowsWin32, .NET
JavaSwing, SWT, JavaFX
macOSCocoa
iOSCocoa Touch
AndroidJAVA Android SDK
Node.jsElectron
Unix 기반X11 구현체들

차라리 Java처럼 OS에 독립적인 플랫폼에서 프로그램을 만들어서 모든 OS에 배포하면 어떨까요? 여러 플랫폼에 배포할 필요가 있는 클라이언트 프로그램이라면 그렇게 할 수 있겠습니다. JAVA뿐만 아니라 여러 진영에서 많은 플랫폼을 지원하는 크로스플랫폼 GUI 라이브러리/프레임워크를 개발하기 위해서 노력하고 있습니다.

크로스 플랫폼크로스 플랫폼

하지만 플랫폼별로 제각기 특징이 있기 때문에, 고성능으로 많은 플랫폼을 지원하는 것이 쉽지는 않겠습니다. 스마트폰 플랫폼과 Java를 예로 들면, Android는 Java에 친화적이지만 응용프로그램의 라이프사이클이나, 사용자 인터페이스 자체가 데스크탑과 다르기 때문에 프로그램을 그대로 앱으로 이식 할 수는 없습니다. 심지어 iOS에서는 Java 런타임에 대한 설치를 지원하지도 않고 있습니다.

유니티의 크로스 플랫폼유니티의 크로스 플랫폼

차라리 게임이나 CLI 프로그램처럼 플랫폼의 GUI에 대한 의존성이 적은 프로그램은 차라리 크로스플랫폼이 쉽겠습니다. 게임 개발 플랫폼인 Unity는 동일한 소스코드로 10개가 넘는 플랫폼에 대한 일괄 빌드를 지원하기도 합니다.

Message from Webpage? (Adobe Air)Message from Webpage? (Adobe Air)

크로스플랫폼이 어려운 기술이라고해도 여전히 많은 오픈소스 또는 상용 GUI 크로스플랫폼 기술들이 있습니다.

JAVA SwingJAVA Swing

우선 Java의 Swing, SWT, JAVA FX 같은 GUI 프레임워크로 데스크탑 프로그램을 만들수 있겠습니다.

Mongotron (by Electron)Mongotron (by Electron)

또는 Electron , NW.js 등의 Chromium 웹 브라우저 기반의 프레임워크에서 HTML, CSS, JavaScript와 Node.js 기술을 이용해서 데스크탑 프로그램을 만들 수도 있습니다.

XamarinXamarin

MS의 .NET 기반의 Xamarin 이나 Adobe Air 를 이용해 iOS, Android, Windows App 등의 스마트폰 앱을 만들 수도 있습니다.

크로스플랫폼을 지원하는 GUI 라이브러리/플랫폼 목록

SPA 프레임워크

Angular.jsAngular.js

다시 웹으로 돌아와서 SPA(Single Page Application)에 대한 얘기를 해보겠습니다. 이전 파트에서 SPA에 대해 잠깐 다루긴 했지만 그 구체적인 내용은 다루지 않았습니다. 왜냐면 GUI 아키텍쳐를 이해하기 앞서서 Angular.js 같은 SPA 프레임워크를 접하기면, 그 필요성과 구조를 받아들이기 힘들기 때문입니다.

SPA의 예시

SPA와 서버의 통신

SPA는 웹 브라우저 환경에서 GUI 프로그램을 흉내내는 JavaScript 프로그램입니다. 다시 말해, 웹 브라우저라는 GUI 프로그램 속에 구현된 GUI 프로그램이라고 생각 할 수 있겠습니다.

SPA ArchitectureSPA Architecture

위 그림에서 전통적인 웹과 SPA를 비교하고 있습니다. 최초의 요청에서 JS 및 CSS를 포함한 HTML을 전송(프로그램을 배포)해줍니다. 이때 전송된 웹 페이지는 하나의 독립적인 GUI 프로그램처럼 작동하며, 이후 서버와의 통신이 필요한 경우 Ajax로 비동기 통신합니다. 이는 일반적인 GUI 프로그램이 서버와 비동기 통신하는 것과 동일합니다.

오프라인에서 작동하는 SPA를 만든다면 서버가 필요 없을 수도 있습니다. 단순히 HTML, JS, CSS 파일을 배포하면 되겠습니다.

SPA 프레임워크

대체 그럼 Angular.js , React.js , Vue.js 등 수 많은 SPA 프레임워크들이 하는 일은 뭔가요? 이미 웹 브라우저에서 DOM과 이벤트 시스템 등 GUI를 위한 API를 제공하고 있지 않나요?

웹 브라우저 플랫폼이, JavaScript가 GUI 프레임워크를 제공하느냐? 라고 물으면 그렇다고 하기 힘듭니다. 제공된 native API만으로는 GUI 프로그램을 밑바닥 부터 만드는 것과 비슷합니다.

과거의 웹 (Yahoo)과거의 웹 (Yahoo)

예를 들어 HTML Element들은 다른 플랫폼들의 UI 컴포넌트들에 비하면, 데이터 바인딩이나 상태에 대한 설계 없이 단순한 껍데기만 존재하는 수준입니다. 애초에 웹이라는 플랫폼은 정적인 문서를 네트워크를 통해 주고 받는 것이 목적이었기 때문에, GUI 아키텍처는 웹 브라우저 플랫폼의 관심사가 아니였습니다.

이러한 배경 때문에 SPA로 GUI 프로그램을 흉내내는 것은 손이 많이 가는 일입니다. native DOM API 및 그러라고 만들어둔게 아닌 각종 API를 잘 이용해서 GUI 아키텍쳐를 구현 할 필요가 있습니다.

요청을 보내지 않으면서 URL을 변경요청을 보내지 않으면서 URL을 변경

SPA 프레임워크는 플랫폼 자체에서 지원하는 것이 아니었기 때문에 지금껏 많은 구조의 프레임워크가 존재 해왔습니다. 그리고 SPA 생태계가 충분히 발전한 지금은 GUI 아키텍쳐와 MVC에 대한 골조뿐만 아니라, 완성도 높은 UI 컴포넌트들까지도 제공하는 여러 오픈소스 프로젝트들이 있습니다. 세가지만 소개하도록 하겠습니다.

SPA 프레임워크UI 컴포넌트 라이브러리
Angular.jsAngular Material
Vue.jsElement.io
Sencha Ext JS (유료 라이센스)(자체 포함)

React.js 는 완벽한 GUI 아키텍쳐를 구현하지 않습니다. 단순히 뷰 레벨에서 DOM 껍데기에 상태 및 데이터 바인딩을 도입한 UI Component를 작성하기 위한 라이브러리로 볼 수 있겠습니다. React.js로 SPA를 구현하려면 다른 프레임워크와 함께 사용하거나, 전역 상태 관리 등을 처리 할 다른 라이브러리( Mobx , Redux 등)를 쓰거나 직접 구현 할 필요가 있습니다.

검색엔진 최적화

검색엔진 최적화(SEO; Search Engine Optimization)는 웹 페이지의 방문 트래픽을 높히기 위해서 구글, 네이버 같은 검색엔진이 수집하기에 적절하게 HTML을 구성하는 것을 의미합니다. 검색엔진은 크롤링 봇을 운영하면서 웹사이트들의 HTML 소스코드를 열어 보고 텍스트를 수집하고, 또 연결된 링크를 타고 이동하면서 인터넷을 헤집고 다닙니다.

SPA의 HTML 코드

<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>SPA DEMO</title>
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
</head>
</html>
<body>

<nav class="navbar navbar-default">
    ...
    <!-- list section -->
    <div class="col-sm-6">

      <!-- list group -->
      <div class="list-group" data-app="list">
        <a href="#" class="list-group-item" data-app="list-item-template">
          <h4 class="list-group-item-heading" data-app="list-item-name">Name</h4>
          <p class="list-group-item-text">
            <span class="glyphicon glyphicon-earphone"></span> Phone: <span data-app="list-item-phone">010-1234-1234</span><br>
            <span class="glyphicon glyphicon-envelope"></span> Email: <span data-app="list-item-email">abc@def.com</span>
          </p>
        </a>
      </div>

      <!-- list loading -->
      <div class="alert alert-info" data-app="list-loading">
        Loading Contacts...
      </div>

      <!-- list empty -->
      <div class="alert alert-info" data-app="list-empty">
        Empty Contacts...
      </div>
    </div>
  </div>
</div>

<script src="/static/js/jquery-3.2.1.min.js"></script>
<script src="/static/js/app.js"></script>
</body>
</html>

SPA의 소스코드는 최초에 앱을 실행하기 위한 script, link 태그나 데이터가 비어 있는 뷰 껍데기 정도로 구성이 되있을 뿐입니다. 이후 앱이 초기화되고 데이터를 불러오면서 DOM을 조작하지만, 그 소스코드는 일반적인 웹 페이지처럼 컨텐츠에 충실한 HTML로 구성되지 않습니다.

보통의 봇들은 웹 브라우저로 JavaScript를 실행하면서 데이터를 수집하진 않습니다. 때문에 어떤 링크에 접속했을 때, JavaScript 앱이 실행되기도 전에 소스코드가 적절한 컨텐츠를 포함하고 있을 필요가 있습니다. 이 문제를 해결해주는 기술을 서버 사이드 렌더링(Server-Side Rendering)이라고 하며, 최신의 인기 SPA 프레임워크들은 대부분 이 기술을 지원합니다.

우리가 Windows, iOS, Android 응용프로그램을 만들면서 검색엔진에 대한 노출을 걱정하지 않는 것처럼, 모든 SPA에 SEO가 필요하진 않겠습니다.

SPA가 필요한가?

NEED TO BE SPA?NEED TO BE SPA?

  • 일반적인 웹 페이지와 다르게 반응성있는 GUI 프로그램
  • REST 등의 API 서버에 대응되는 웹 클라이언트 프로그램
  • URL을 통해서 앱의 상태를 포착하고 공유 할 수 있는 GUI 프로그램 (접속하는 URL에 따라서 앱의 상태를 복원하도록 구현한다면)
  • 웹 브라우저만 있다면 어떤 플랫폼에도 제한되지 않는 프로그램
  • 접속만으로 배포하고 바로 실행 수 있는 프로그램

SPA는 위와 같이 아주 특별한 특징을 갖는 프로그램이 되겠습니다. 또한 거꾸로 생각하면, 위와 같은 특징이 필요한 GUI 프로그램이 필요할 때 SPA를 구현 할 필요가 있다는 말도 되겠습니다. 걸맞지 않는 프로젝트에 SPA를 도입 할 필요는 없겠습니다.

하이브리드 모바일 앱

SPA로 GUI 프로그램을 흉내내봤는데 이 기술을 다른 플랫폼에 적용 할 수도 있을까요? 웹 기술로 개발한 모바일 앱들을 하이브리드 앱(Hybrid Mobile App)이라고 합니다.

하이브리드 앱하이브리드 앱

여기서 하이브리드는 웹 기술과 스마트폰 플랫폼 기술의 하이브리드를 의미합니다. 하이브리드 앱의 구조는 일반적으로 Angular.js, React.js, Sencha Touch, Ionic 등을 통해 SPA를 개발하고, SPA와 터치 이벤트, 카메라 등 스마트폰의 native API를 이어주는 PhoneGap, React Native 등의 플랫폼을 이용해서, 각각의 모바일 플랫폼에 맞게 SPA를 감싸고 있는 앱을 빌드합니다.

PhoneGap iOS StructurePhoneGap iOS Structure

앱의 작동 원리는 기본적으로 모바일 플랫폼에 내장된 웹 브라우저 엔진을 통해서 SPA를 돌린다고 보면 되겠습니다. 이런 이중적인 구조 때문에 native API만을 이용한 native 앱과는 성능 차이가 나겠습니다.

React Native는 HTML 기반의 UI 컴포넌트 대신에, 각 플랫폼별이 제공하는 native UI 컴포넌트를 이용합니다.

멀티 플랫폼

단일 서버에 대응하는 멀티플랫폼 클라이언트단일 서버에 대응하는 멀티플랫폼 클라이언트

서버 쪽으로 넘어가기 전에 한가지 사실을 되새기자면, 네트워킹이 필요한 서비스에서는 일반적으로 단일 플랫폼에서 서버를 구축하고, 많은 클라이언트에게 배포하기 위해서 Windows, macOS, Android, iOS, Web(SPA) 등 각종 플랫폼별로 클라이언트를 구현하곤 합니다.

네트워크 인프라를 설계하고 서버를 개발하는 백엔드 개발자도 바쁘겠지만, 멀티플랫폼으로 타겟을 정하면 클라이언트 개발자는 참 할 일이 많겠습니다. 그러니 저렇게 하이브리드고 크로스플랫폼이고 이런 저런 수요가 있지 않을까요?

목차
7. 다른 플랫폼으로
저자

김동욱

개발 경력 약 10년, 전문 분야는 웹 및 각종 응용 소프트웨어 플랫폼입니다. Codeflow를 운영하고 있습니다.

2018년 04월 09일 업데이트

지원되지 않는 웹 브라우저거나 예기치 않은 오류가 발생했습니다.