2014년 11월 24일 월요일

UniWeb@Unity Asset Store

Socket.io를 이용하기 위해 UniWeb을 사용해본 후, 주의점들 정리해볼까 합니다.

1. Websocket에 한정되는 socket.io접속을 제공(Socket을 이용하기 때문에 Unity Pro라이센스가 아니면 안드로이드, 아이폰용의 빌드는 불가능). XHR-Polling과 같은 다른 접속 메소드를 제공하지 않음! (Unity Basic라이센스에서 xhr-polling으로의 접근을 해결해줄거라 생각한다면 따로 구현해야 한다는 것을 염두)

2. Heartbeat, disconnected(socket.io)의 구현이 되어 있지 않음.  heartbeat는 구현되어 있으나. 지속적인 heartbeat를 해주는 코루틴의 정지부분에 heatbeat라고 오타가 나있는 부분이 있음. 이 부분은 수정해주면 됨. 다만 접속후에 서버를 내려버리면 websocket레이어에서는 이를 캐치해주는 부분의 구현이 존재하나, socket.io까지 이 부분이 적용되어 있지 않음. 구현이 필요함. (개인적으로는 구현했으나, 판매용 에셋의 수정버전이다보니 소스의 공유는 힘들듯 합니다)

3. Websocket의 구현 자체는 자체구현 인듯함. 다른곳에서 구현된 여타 구현들을 도입한 흔적이 없고, 되려 유니티용의 환경별 대처가 되어있음. 토이프로젝트 수준으로 다뤄보는 현 시점에서는 특별히 문제가 되어 보이는 부분은 발견되지 않음.

4. IEnumerator,  코루틴의 사용을 전제로 하는 구현. 다만 socket.io의 사용에 있어서는 각 이벤트별의 핸들링을 실시함.

기본적으로 socket.io에 관련된 부분의 기능구현이 미비합니다.
현 시점에서 sails.io.js에 해당하는 기능까지는 구현해 동작은 확인하고 있지만
사용자가 그렇게 많지 않(거나 티가 안나거나)은 부분으로 미뤄보았을때 도입에 있어서는 조금 주의해야할 부분이 있어 보입니다.

가능하면 도입하게 되더라도 내부 스펙을 다 훑어볼 필요가 있을듯 합니다.

2014년 11월 22일 토요일

MVVM @ Unity3D

몇번의 프로젝트를 경험하며, 프론트엔드(클라이언트)에서의 프레임워크가 필요하다고 생각되어 이리저리 뒤지던차, 최근 Unite 2014에서 시연하던 내용중에 괜찮은 MVVM프레임워크가 발표되어 있어, 한번 손을 대보게되었습니다

uFrame이라는 프레임워크로

MVVM...에 가까운 환경을 제공합니다.

가깝다는 말이 무슨말이냐면, Microsoft에서 제창하고 있는 그 MVVM과 완전히 동일한 물건은 아니라는 말입니다.

개인적으로 MV*패턴에 있어서 가장 이해하고 있는 패턴은 Restful API개발등으로 연이 닿았던 CakePHP와 같은 Rails와 같은 계통의 MVC패턴을 개인적인 범주내에서는 가장 이해를 하고 있습니다.

MVVM은 Model, View, View-model의 약자로, MVC의 Model View Controller에 있어서 Controller가 View-Model이 대치된 형태의 디자인 패턴입니다.

웹에서의 MVC는 기본이 한번의 http리퀘스트에 대한 response까지만 해결을 하면 되기때문에, 기본적으로 클래스를 MVC의 각 역할에 맞춰, 단순한 한번의 호출에 대한 처리에 대한 정리만 해 놓은 정도의 내용입니다만. uFrame에서 말하고있는 MVVM에서의 데이터 연동은, 실시간 적용을 전제로 생각하는 구조를 하고있습니다. 일반적으로 Observer Pattern으로 이야기되는 그런 부분이죠.

Model에 변경이 있었을 경우, Binding된 View로 모든 데이터 변동이 적용되는 구조를 갖추고있는데, 이를 중간역할을 하는 View-Model이 담당을 하고있습니다.

여기에 더불어, uFrame에서는 ViewModel에 대해 Controller가 붙어있습니다.
그래서 엄밀히는 MVCVM이라 부른다는것 같긴합니다.

http://answers.invertgamestudios.com/chat/i-know-mvc-and-mvvm-but-i-m-not-certain-i-quite-get-uframe

일반적인 Rails의 MVC의 C는 엄밀히 이야기하자면 Framework에 정의된 routing의 결과 주소에 관한 endpoint에 대한 하나의 http리퀘스트의 처리 컨트롤을 지칭하고 있지만,

uFrame에서의 Controller는 View----Command----->ViewModel---->model과 같은 뷰 모델로의 커맨드 처리의 로직을 구현하는 부분에 해당하는것 같습니다.

실제로 관련 로직이 Controller에 배치되게끔 권장이 되고 있습니다.

현 시점에서 디자인패턴에 관한 이야기는 위와 같은 정도로 정리를 할 수 있을거같고, 향후에 더 조사를 하며 실제 프로젝트에 적용이 가능한지 정도까지를 조사를 진행해볼 생각입니다.
다만 1.5버전 자체가 아직 베타버전으로 파이널 릴리스가 나와있지 않기때문에 현재 작업을 해보면서 발생하는 문제나, 문서화의 부족등으로 인한(소스는 오픈소스가 아님) 난제가 없지않아 남아있기 때문에 아직은 사용상에 문제가 많이 발생할지도 모르겠습니다.


그럼에도 불구하고, 이 프레임워크를 사용해보려는 이유는 아래와 같습니다.

1. 스튜디오급 이상의 조직에서 개발되고있으며, 유지보수가 진행중
2. 다이어그램을 통한 클래스의 형상관리가 가능. 심지어는 다이어그램을 중심으로 해서 관련 기반 코드가 자동 작성됨(!)
3. 어느정도 정립된 패턴에서 비지니스 로직을 개발함으로서, 타인과의 소통이 용이, 스파게티 코드의 회피.
4. 기존 몇몇 mv*프레임워크가 없는건 아니지만, 현 시점에서 유지보수가 되고있는지는 미지수, 혹은 그런 흔적이 보이지 않음.


아직 개발도상에 있는 프레임워크지만, 중단기적으로 생각했을때 어느정도 기대해볼수 있지 않나라는 생각이 들어서... 가 주요 이유가 되겠습니다.

아무래도 실제 개발투입에 이용하기 어렵다는 결론이 나오면 다른 오픈소스 프레임워크 등으로 눈을 돌려야겠지만 말입니다.

요 며칠 실제로 만져보며 이것저것 해본결과, 어느정도 Element운용(메모리 사용량 등의 이유)에만 주의하면 충분히 좋은 프레임워크로서 이용 가능하지 않나 하는 생각이 듭니다.

그리고 문서화좀 더...

Overview
http://invertgamestudios.com/uFrameAPI/Default/webframe.html#uFrame%201.5%20Overview.html

Asset Store
https://www.assetstore.unity3d.com/en/#!/content/14381

2014년 11월 16일 일요일

node.js, vert.x?, websocket? sails 0.10.x

이번에 진행할 토이프로젝트의 솔루션 선정에 있어서 고려한 내용들을 정리해보고자 합니다.

결론부터 정리하자면, 서버측의 app운용은 sails.js(node.js+express.js+socket.io)를 이용해 개발을 진행해볼까 합니다.

sails.js?
sails.js프레임워크는 express.js와 socket.io를 기반으로 하는 node.js mvc 프레임워크입니다.

websocket을 기반으로 하는 애플리케이션을 개발함에 있어서 정형화된 rails와 흡사한 형태의 프레임워크를 고르자고 했을때

http://nodeframework.com/

가장 주목받고 있는 프레임워크가 sails.js가 아닌가 생각되어, 우선 이 프레임워크를 이용해 토이프로젝트를 진행해볼까 생각하고 있습니다.

node.js, 더불어 express.js를 통해 개발을 진행한다 하였을 경우, 소스 운용에 관한 구조를 직접 구조화할 필요가 있습니다. 물론 그것 자체를 개개인이 만들지 못할것도 없지만, 공개된 오픈소스중에 서비스를 운용함에 있어서 충분한 기능, 검증이 된 프레임워크를 이용한다면, 팀이 확장될 경우라던가의 경우, 그 팀원이 해당 프레임워크의 지식이 있었다면 조금이나마 빠르게 소스의 파악이 가능하고, 혹여 모른다 하더라도 공식 배포처에서 제공, 혹은 제 3자가 거친 시행착오를 가까운 사람이나, 인터넷의 커뮤니티 등을 통해 해결할 수 있을 가능성이 높아집니다. 이러한 문제를 생각한다면, 어느정도 기반이 정리된 프레임워크를 이용하는 것이 현명하지 않나 하는 생각이 들곤합니다.

따라서 이번에 작성하는 토이 프로젝트는 rails like MVC framework for node.js인 sails.js를 이용하고자 합니다.

Vert.X?

웹소켓이 가능한 서버개발환경을 고려했을때, node.js이외에 생각해볼법한 프레임워크로서 Vert.X가 곧잘 거론되곤 합니다.

Vert.X는 node.js에서 영향을 받아, 싱글 스레드의 구조로 인한 멀티코어의 활용 등에 관한 문제점. javascript에 종속되어있는 node.js에 비해 여러 언어를 서포트하는것을 특징적으로 꼽을수 있는, java가 대표적인 기반언어인 프레임워크입니다.

성능상의 문제등으로 nodejs의 대안으로 vert.x가 떠오르고 있는듯 한데, 아직은 관련 모듈이 그렇게 많지가 않다는점. 어느정도 정리가된 프레임워크가 존재하여 여러 사람들에 의한 검증이나 그에 관한 자료가 보이지 않는 점 등에서 vert.x는 시기상조가 아닌가 하는 생각이 듭니다. (개중엔 결국 다른 환경에 embedded된 vert.x를 이용해야 효율적인거 같다라는 말이 들리기 까지도... 거기에 더해 embedded된 환경이기에 추가적으로 제공되는 모듈의 이용이 불가능하다는 제약조건까지... 라면 역시나 좀 시기상조인 느낌이 드는건 어쩔수 없는거 같습니다. 하다못해 최소한의 특정 언어용이나마 vert.x용 프레임워크가 있다면 간편하게 이용하면 좋을 것 같지만, 직접 짜야한다면 비지니스 코드에 할애하고 싶을 시간이 아까울거 같다는 생각마저 들어버리는건 어쩔수가 없는거같습니다)

vert.x의 경우 멀티스레드를 띄워 중추가되는 하나의 node.js를 이용하는 경우에도, 멀티코어 서버에서 인스턴스를 여러개 띄워 로컬 파일 데이터베이스나 memory-adaptor를 이용하지 않는다면 운용함에 부족함이 없는 성능을 낼 수 있지 않을까 하는 생각이 들기때문에, 무리하게 vert.x를 이용하지 않더라도 성능문제에서 문제가 될건 없다는 생각이 들었습니다.

http://vertxproject.wordpress.com/2012/05/09/vert-x-vs-node-js-simple-http-benchmarks/

실제로 벤치마크한 결과가 거재된 내용인데, 6프로세스에서 저정도의 성능저하선이라면, 아직까지는 서드파티 모듈의 이점을 버릴정도는 아닐까 하는 생각이 들곤 합니다.

어차피 어느정도 AWS의 auto-scaling/로드 밸런서를 통한 분산처리를 전제로 생각하고 있기에, 1개 서버에서 복수 인스턴스를 띄워 운용함으로서 위의 그래프 정도 선의 퍼포먼스까지는 끌어낼수 있지 않나 하는 생각이 듭니다.

따라서 이번에는 일단 적용하지 않기로.

socket.io? Websocket?
실시간 통신을 구현함에 있어서 일반적인 tcp/ip를 이용하지 않고, websocket을 이용하고자 하는 이유는 아래와 같습니다.

1. 프론트환경인 유니티에서 websocket(socket.io)이 동작하는것은 확인완료.
2. socket.io(사실 sails를 이용한다면 순정이 아닌 일종의 수정버전이긴 하지만)의 존재로 인한 개발의 간편함. pubsub패턴이 몹시 편리하다.
3. tcp/ip를 통해 전용 프로트콜을 이용하기에는 일반적으로 사용되지 않는, 여타 프로트콜과 충돌하지 않는 포트를 이용하여야 하나, websocket은 기존 http리퀘스트의 연장선이기에, 80번 포트로 그대로 이용이 가능함. 기존의 인프라에 영향을 최소화 할수있음.
firewall/router등에 대한 대책등도 실시간 통신을 위해 고려하지 않아도 된다는 잇점을 들수있음.

그리고 socket.io는 websocket, xhr-longpolling, jsonp, 등과 같은 여러 웹에서 실시간 정보를 얻을 수 있는 패턴중에 통신 가능한 수단으로 웹 브라우저에 실시간 피드를 가능케 해주는 모듈입니다.

sails.js에서는 이 socket.io를 확장해, 자신이 가진 모델에 대한 pubsub패턴을 제공하고 있어 간단하게 사용이 가능합니다.
(아직 문서화가 부족한듯 하여 처음에 이용하는데 조금 애는 먹었지만.)

다만 sails에서 클라이언트도 커스텀된 내용으로 제공하고 있기 때문에, 현재 사용을 검토중이던 UniWeb의 클라이언트를 참조하여 어느정도 sails.io.js(클라이언트용 io스크립트)와 동등한 기능을 제공하는 mod-component의 작성이 불가피해 보이긴 합니다.

sails.js에서의 websocket의 복수 서버환경에서의 동작은, 동작 메모리를 local-disk에 두고있는 부분을 redis서버로 치환, 인프라내의 1개소의 redis로 설정하는것으로 커버가 가능할거란 부분도 직접 확인을 했습니다 (2개의 다른 포트의 인스턴스를 띄워 local-redis에 접근하거나, 기본설정으로 운용하거나로 메세지가 오고 오지 않음을 확인)

2014년 11월 7일 금요일

sails 0.10.x와 기준, 기존에 보이는 샘플들과의 상이점 정리

adapters.js moved to connecters.js

기존 adapters.js의 기능들은 connecters.js로 이동

Javascript dependencies

view(html)에서 js를 이용함에 있어서 구버전과의 차이

/assets/js/dependencies/...에 파일을 두면
/tasks/pipelines.js에 설정된 규칙에 의거하여 레이아웃에 출력해줌.


// (uses Grunt-style wildcard/glob/splat expressions)
var jsFilesToInject = [
  
  // Load sails.io before everything else
  'js/dependencies/sails.io.js',

  // Dependencies like jQuery, or Angular are brought in here
  'js/dependencies/**/*.js',

  // All of the rest of your client-side js files
  // will be injected here in no particular order.
  'js/**/*.js'
];

기본적으로 이 부분이 해당되게 되는데. 아래를 보는 한 굳이 dependencies이하가 아닌 assets/js이하의 모든 js파일을 읽어들이는 것으로 생각됨

Socket.IO

일반적으로 socket.io client를 이용할때는 클라이언트 js를 읽어들인 상태에서 socket...으로 접근하는듯하나, sails.js 0.10.x에 포함된 sails.io.js에 포함된 io.socket을 통해서 소켓에 해당하는 기능을 이용 가능한듯함.

sails.io.js에 포함된 아래 코드에서 확인.

    // In the mean time, this eager socket will be defined as a TmpSocket
    // so that events bound by the user before the first cycle of the event
    // loop (using `.on()`) can be rebound on the true socket.
    io.socket = new TmpSocket();

아래 첨부 사이트에서 소개된 예제중 소켓을 이용하는 부분에서 socket...으로 접근이 불가능했던 부분에 대해서 앞에 io.를 붙임으로 동작의 확인이 가능했음.

[구버전의 샘플]
http://tech-sketch.jp/2013/11/sailspubsub.html

[공식문서]
http://sailsjs.org/#/documentation/reference/websockets/sails.io.js

{model}.Subscribe Deprecated

PubSub pattern에서 sub에 해당하는 {model}.subscribe(...); 가 deprecated되어있어 경고를 목격함. watch로 치환하라고 한다.

범용적인 이름을 두고 바꿀필요가 있나...?

[GitHub Issues]
https://github.com/ryancp/sailng/issues/2

[Sails Socket Client] event handles as model name (11.14 추가)

기존의 socket.io와 같이, message, created ...와 같은 고정 메세지 명으로io.socket.on을 통해 수신하는게 아니라, 모델명을 가지고 각 이벤트를 수신하는 형식으로 변경됨.
처음에 모델명을 Message로 테스트하다가, Chat으로 아무 생각없이 바꾸고나서부터 메세지 수신이 되지 않아 한참을 붙들고 있다가, 위와 같은 변경사항이 있었단걸 발견.

(socket)io.of와 같이 특정 네임스페이스에 바인딩되는 구조가 현재 보이지 않는거로 볼땐(get한 대상의 controller에서 socket에 대해 subscribe(watch)하여 통신하고 있는거로 보여짐)
아무래도 유니티 등에서 사용하기엔 sails용의 websocket기반 클라이언트의 작성이 불가피해보임.

[GitHub Issues]
https://github.com/balderdashy/sails/issues/1465

2014년 11월 6일 목요일

Promise Pattern

node.js와 같은 이벤트 기반의 언어를 다루게되면,
순차적인 코드 실행순이 아닌 이벤트 기반의 처리에 맏닥뜨리게 됩니다.

하나의 스레드를 중심으로 여러 처리를 이벤트가 발생할때 마다 처리를 수행하는 node.js에 있어서는 필수 불가결한 구조이지만, 이러한 구조는 일반적인 동기식 처리코드에 비해서 어떤 내용이 우선적으로 처리될지, 순차적인 코드 정리가 어지럽혀질 가능성이 큽니다.

무슨말인지 이해하기 힘들다는 생각이 들면, 예를 들어 아래 사이트에 거재된 callback-hell인 코드를 봐주시는게 이해가 빠를거라 생각이 듭니다.

http://callbackhell.com/

코드가 지저분해질 뿐만 아니라, 비동기이기 때문에 어느 코드가 우선적으로 수행될지 직관적으로 알수가 없습니다.

이러한 비동기적 환경 하에서,

여느 디자인 패턴이 그렇듯이 순전히 코드를 깔끔하게, 사람이 알아보기 좋게 하기 위해서 비동기적인 환경에서 순차적인 코드수행의 보장과 정리를 하기 위해 나온 패턴이 프로미스 패턴입니다.

사실 이러한 패턴자체는 제창된지는 제법 되었고, jQuery등에서는 이미 예전부터 사용되고 있습니다.

$("#id").delay(1).fadeOut("slow");

이러한 코드가, 프로미스 패턴의 한 사례입니다.

프로미스 패턴은 현재 어느정도 표준화가 진행되어, Mozilla산하의 표준에서나, nodejs에서 또한 0.12버전부터는 new Promise(...)로 이용이 가능해진다고 합니다.(현 시점에서는 스테이블이 아닙니다)

http://www.html5rocks.com/ko/tutorials/es6/promises/
http://d.hatena.ne.jp/jovi0608/20140319/1395199285

개인적으로는 아직 nodejs의 표준으로 이용할수가 없기 때문에, 대표적인 라이브러리인 q를 사용하고 있습니다.

아래에 프로미스 패턴을 사용해 sails.js의 모델에서 데이터의 검색과 분기로 인한 크리에이션을 정리한 코드를 첨부합니다.

Fish는 sails.js의 하나의 "모델"입니다.
hi function은 sails controller로 인한 RESTful API의 접근으로 접근이 가능한 메소드입니다.
수순적으로 로컬에 정의된 Find()로부터 파생된 검색 내용을 가지고, 없으면 조건부로 생성을 실시하는 수순의 처리 루틴을 타고 있습니다.

데이터베이스로의 접근은 MVC패턴상의 sails.js의 모델을 경유하여 접근하고있고, 데이터 취득자체는 비동기로 처리됩니다. 이 과정중에 프로미스로 인한 정리 수순이 들어가게 됩니다.

/**
 * TestController
 *
 * @description :: Server-side logic for managing tests
 * @help        :: See http://links.sailsjs.org/docs/controllers
 */
var Q = require("q");
var iz = require("iz");

module.exports = {

hi: function (req, res) 
{

    var fishname = "zako";
    var fishtype = "microfish";
    
    // ----------------------------------------------------
    // fishing example
    // ----------------------------------------------------

    Find(fishname)
    .then(

      // ---------------------------------------------------
      // loaded. it exists.
      // ---------------------------------------------------
      function(info) {
        console.log("exists. just loads");
        return Q.resolve(info);
      },

      // ---------------------------------------------------
      // failed. regenerate
      // ---------------------------------------------------
      function(err) {
        console.log("not exists, make new entity");
        return Create(fishname,fishtype);
      }

    ).then(

      // ---------------------------------------------------
      // find or created. show infos.
      // ---------------------------------------------------
      function(info) 
      {
        res.json(info);
      },

      // ---------------------------------------------------
      // creation failed.
      // ---------------------------------------------------
      function(err) 
      {
        res.json({code:"333",message:err});
      }

    );

    // ----------------------------------------------------
    // done
    // ----------------------------------------------------

},

};

// ------------------------------------------------------------

var Find = function(name) {

  var deferred = Q.defer();

  Fish.find(
    
    { 
        "name" : name
    },

    function(err,info) 
    {
        if(iz.empty(info)) 
        {
            deferred.reject(err);
        }
        else
        {
            deferred.resolve(info);
        }
    }

  );

 return deferred.promise;

};

// ------------------------------------------------------------

var Create = function(name,type) {

  var deferred = Q.defer();

  Fish.create(
    
    {
      "name":name,
      "type":type,
    },

    function(err,info)
    {
        if(iz.empty(info)) 
        {
            deferred.reject(err);
        }
        else
        {
            deferred.resolve([info]);
        }
    }

  );

  return deferred.promise;

}

// ------------------------------------------------------------


경력 2년차를 바라보며

게임 업계에서 밥을 먹기 시작한지 근 1년 10개월이 지났습니다.

우여곡절 끝에 이런 저런 잡학을 습득하고, 여지껏 습득하고 사용해왔던 기술의 결과물들이
정녕 쓸만한 코드인지 아니면 한번 쓰고 버려지는 실 덩어리인지라고 물었을때 후자라는걸 몸소 체험하고서, 한차례 개인적인 성장의 기점이 왔다고 생각되어, 다시금 이런 사람도 오지 않는 블로그에 이런 저런 내용들을 적어가며 정리해보고자 합니다.

필요한 기술들을 토이 프로젝트를 통해 만져보거나, 코드 리팩토링 및 디자인 패턴에 대해서 다시금 고민하면서 관련된 스터디 내용들을 정리해보려 합니다.

현 시점에서 실무를 거치며 다뤄온것들은

유니티4, c# + unity editor
cakephp, php
mysql
aws 클라우드 시스템으로 인한 인프라
shell scripts
lua
git
svn
android in app purchase v3 api

언제까지고 이 업계에서 누군가를 즐겁게 하는 그런 숫자 배열들을 만들어갈 수 있는 그런 실력이 개인적으로 축적 되었으면 하며, 동종업계의 누군가가 어떤 코드에 막혔을때 우연찮게 같은 이슈에 맞닥뜨린다면 한줄 도움이 될 수 있는 그런 기록이 되었으면 좋을것 같습니다.

이 블로그에서는 몇몇 토이 프로젝트를 가지고, 게임을 런칭할때까지의 필요한 기술을 조사하고 사용상에 문제가 되는 것들을 해결하는 내용을 기록해나가고자 합니다.

현재 당장 예정하고있는 조사 수순은 다음과 같습니다.

nodejs를 통한 웹소켓의 기능 구현 나아가서 리얼타임 피드백을 위한 기능 구현 방법의 파악.
nodejs를 운용함에 있어서 적합한 공용 프레임워크의 조사 및 토이프로젝트상의 적용,
현재는 sails.js를 예정. (국내에선 생소하려나? 제법 그럴듯한 기능을 갖추고 성장중인 MVC@nodejs프레임워크입니다)

데이터베이스의 스케일아웃대책을 위한 NoSQL조사, MySQL fabric/cluster의 시험사용.

cocos2d-js를 통한 브라우저상의 동작환경을 통한 크로스플랫폼 어플리케이션 개발

chef/AWS cloud formation을 통한 서버형상관리 및 인프라형상관리

nodejs, cocos2d-js 및 Unity 5 c++(현 시점에서 베타가 릴리스)를 이용함에 있어서 적용하기 적법한 디자인 패턴에 관한 고찰.

각 작업 환경에서의 코드 퀄리티 향상을 위한 코드 복잡성 지표의 파악과 리팩토링, 클린 코드 작성에 대한 고찰.

cocos2d-js는 개인적으로 프로젝트를 진행할경우 비용 발생을 누르기 위한 2d개발의 선택지라 생각하고 있습니다. 유니티에 관해선 새로 나오는 c++환경이 모노를 제거한 네이티브환경이라면 앱에서 더 나은 퍼포먼스와 개발환경을 제공해주지 않을까 하는 기대에서 한차례 조사를 해나갈까 합니다.

이후에 적히는 블로깅 자료들은 개인적인 조사와 시행착오의 결과물이 될거라 생각합니다.
따라서 내용이 기술적으로 무엇하나 보장되는것도 아니고, 혹여 기록되는 자료를 적용시키시려 하는거라면, 그 결과 어떤 문제가 발생하더라도 책임을 질 수 없는 내용들이니, 참고해주시기 바랍니다.