성능향상을 위한 TIP

XPLATFORM 개발시 성능향상을 위한 TIP

업데이트 일자 : 2015.1.19
해당 내용은 고객사의 프로젝트 성격에 따라 달라질 수 있으므로 참고용으로 사용하시기 바랍니다.

항목

내용

중요도

서비스 요청시 통신 방식을 동기 통신방식보다 비동기 통신방식 사용을 권장합니다.

화면에 여러 개의 서비스 요청이 있을 경우 동기 통신은 순차적으로 하나씩 실행하는 방식입니다

즉 1개의 서비스를 호출한 후 완료될 때 까지 기다리다가 통신이 완료된 후 다음 서비스를 실행하는 방식입니다.

또한 통신 요청 후 완료될 때 까지는 프로세스 잠금(Lock) 상태가 되어 Application을 제어할 수 없는 상태의 통식 형태를 말합니다

반면에 비동기 통신은 순서와 상관없이 한번에 다중 처리가 가능한 방식이며 프로세스 잠금 형태가 이루어지지 않기 때문에 서비스 통신시

또는 화면 로딩시 동기 통신에 비하여 상대적으로 성능을 높일 수 있습니다

예를 들어 설명하겠습니다

화면을 호출하기 전/후에 통신이 있는 경우 통신 방식에 따라 아래와 같은 형태로 처리가 됩니다

[A:동기 처리 방식]

화면의 앞뒤로 동기통신이 걸려 있기 때문에 화면이 정상적으로 보여지기 까지는 동기통신 까지 완료되어져야 합니다

[B:동기 처리 방식]

화면의 앞뒤에 있는 통신과 상관없이 화면이 호출되어 보여지기 때문에 로딩 속도를 개선 시킬 수 있습니다

transaction( "MyService01" ,"DataSrv::samplexml.jsp","input1=Dataset02","Dataset03=output1","a=b","callbackFunction",true);

미지정시 트랜잭션은 기본적으로 "비동기 방식"으로 동작합니다.

데이터 서비스 그룹화

이는 서비스 요청 건수의 최소화 하여 통신 비용(연결-요청-응답-종료)을 줄여 속도를 개선시키고자 하는 것 입니다

클라이언트에서 성격이 동일한 서비스가 여러 개 있는 경우 개별로 요청하지 말고 한번에 요청해서 OutDataset 을 통해 여러 개의 정보를 받는 형태 입니다

(개선전)

transaction( "MyService01" ,"DataSrv::samplexml.jsp","","output1=output1","","callbackFunction");

transaction( "MyService02" ,"DataSrv::samplexml.jsp","","output2=output2","","callbackFunction");

transaction( "MyService03" ,"DataSrv::samplexml.jsp","","output1=output3","","callbackFunction");

(개선후)

transaction( "MyService01" ,"DataSrv::samplexml.jsp","","output1=output1 output2=output2 output3=output2","","callbackFunction");

대용량 데이터 조회시 분할 처리

서버에서 대용량 데이터를 한거번에 처리시 메모리 문제(OOM) 가 발생할 소지가 있으며 전송 및 처리 과정에서 속도는 당연히 느려 질 수 밖에 없습니다

Paging 처리 방식 및 서버에서 데이터를 일정크기 만큼 나누어 보내는 FirstRow 방식으로 전환 하시기 바랍니다

ForstRow 방식은 고객지원센터(http://xplatform.co.kr/) 게시판(기술문의 및 내역 )에서 관련 샘플을 받아 보실 수 있습니다

Cache 사용 여부 및 CacheLevel 조정

[ CacheLevel의 정의]

  • session

XPLATFORM 엔진을 기동할 때, 단 한 번만 수신하고(서버에 있는 파일이 갱신되지 않았다면 로컬에 캐시된 파일을 재사용) 해당 엔진이 종료될 때까지 로컬에 캐시된 파일을 사용합니다.

  • none

캐시를 사용하지 않고 매번 서버에서 파일을 수신합니다.

주로 Dataset 관련 통신 시 사용합니다.

  • static

서버에서 수신된 파일은 XPLATFORM 엔진의 재실행과 상관없이 로컬에 캐시된 파일을 재사용합니다.

재수신을 원할 때에는 version을 올려주어야 합니다.

  • dynamic

화면 요청시 매번 서버에 있는 파일을 비교하여 갱신되었을 때만 수신합니다.

서버에 있는 파일이 갱신되지 않았다면 로컬에 캐시된 파일을 재사용합니다.

cachelevel을 지정하지 않으면 dynamic이 기본 속성으로 적용됩니다


Service 항목중 CacheLevel 지정에 따라 성능차이 많습니다.

화면로딩 속도는 ‘static’ > ‘session’ > ‘dynamic’> ‘none’ 순으로 차이가 발생하여 발생합니다

‘static’은 성능이 제일 높지만 서버에 소스 업로드 후 자동 갱신이 되지 않기 때문에 default_typedef.xml 파일에서 수동으로 version을 올려주셔야 서버에서 다시 받습니다.

그렇지 않은 경우 클라이언트에 반영되지 않습니다.

일부 해외에서 속도 이슈로 이미지파일 같은 정적인 폴더에 적용되는 사례가 있습니다


파일 요청시 서버에 수정된 소스가 클라이언트에 자동 갱신되기 위해서는 CacheLevel을 ‘dynamic’ ‘session’으로 사용하셔야 합니다

‘dynamic’ 에 비해 ‘session’ 으로 지정시 요청(Request) 패킷의 차이로 인해 속도는 50% ~ 80% 정도 성능 개선 효과를 보실 수 있습니다

데이터 처리와 관련된 항목(type:JSP,ASP,SAP) 은 반드시 ‘none’로 설정하셔야 합니다(default:dynamic) 그렇지 않고 cache를 사용할 경우 client에 정보가 기록하기 때문에 오히려 성능에 좋지 않습니다

통신형태 설정

일반적으로 xml 통신 방식보다 binary 통신 방식이 속도가 빠릅니다. 또한 이진 파일 형태기 때문에 1차적인 보안(완벽한 보안은 아님) 처리를 하실 수 있습니다

Network 상황이 좋지 않다면 압축사용을 고려하여 통신 형태를 지정하여야 합니다

[ Client에서 Server로 전송시 XP에서 지정 ]

transaction( "MyService01" ,"DataSrv::samplexml.jsp","input1=Dataset02","Dataset03=output1","a=b","callbackFunction",true,1, true);

Server에서 Client로 전송시 Server FrameWork 에서 지정]

예)

HttpPartPlatformResponse xpPartResponse = new HttpPartPlatformResponse(response,PlatformType.CONTENT_TYPE_BINARY, “utf-8”); //이진파일

xpPartResponse.addProtocolType(PlatformType.PROTOCOL_TYPE_ZLIB); //압축

Dataset 조작시enableevent 설정

반복문(for)을 통해 Dataset의 행(row)을 추가하거나 열(column)의 값을 변경할 때 이벤트 함수가 등록되어 있지 않더라도 자체 이벤트를 발생시켜 속도를 저하시키게 됩니다

이런 현상을 막기 위해서는 작업을 시작할 때 dataset.enableevent 속성을 false로 지정하여 불필요한 이벤트 발생을 막고 작업이 완료 했을 때

dataset.enableevent를 true로 변경하여 원래의 상태로 되돌려 놓는 처리를 하시면 속도를 상당히 개선시킬 수 있습니다

단 dataset.enableevent = false로 지정시 지정된 dataset에 등록된 이벤트가 있을 경우 수행되지 않기 때문에 해당 함수가 처리되는 로직을 점검하여 처리 하셔야 합니다

즉 dataset 이벤트에 등록된 이벤트 함수를 수행할 필요가 없는 단순한 dataset를 반복문을 조작할 경우 사용하시기 바랍니다

예)

Dataset00.enableevent = false;

for(var I = 0; i < 1000; i++){

Dataset00.addRow();

Dataset00.setColumn(i,”Column0”, “Column0값”);

Dataset00.setColumn(i,”Column1”, “Column1값”);

}

Dataset00.enableevent = true;

최초 Loading 속도 개선

1. Theme 파일 최적화

Theme 는 Style 및 이미지들을 바이너리 압축형태로 지정할 수 있는 파일로 Application 구동시 최초 호출되는 파일 입니다

메모리에 해당 파일이 load되면 압축해제 상태가 되기 때문에 용량은 2배정도 커지게 됩니다

파일의 크기에 따라 다운로드 수행시간 및 로딩 속도가 결정되기 때문에 되도록 초기 구동(Launch)을 줄이기 위해서는 Theme 파일을 최적화 하는 것이 좋습니다

1) 불필요한 파일은 삭제한다

2) 전반적으로 많이 쓰이는 파일 위주로 등록한다

3) 사용 비중이 아주 적고 용량이 큰 파일은 삭제하고 prefixeid로 등록된 폴더에 해당 이미지를 링크하여 사용한다

2. Global 객체 최적화

Style, Global dataset 및 Variables 등에 불필요한 부분이 있다면 삭제하여 사이즈를 줄이고 TypeDefinition에 등록된 객체(Objects) 중에서도 사용하지 않는 객체가 있다면

(예: Animation, Spin, GraphicPath, GroupBox 등) 이를 제거함으로써 로딩 속도을 조금이나마 높일 수 있습니다

3.User Component 사용 점검 (User Form, Composite)

User Component 도 Global 객체이기 때문에 최초 로딩시 호출대상이 됩니다

대부분 업무 공통과 관련된 파일로서 해당 화면뿐만 아니라 그 속에 포함된 이미지 파일들, 또한 Include js(*.xjs) 된 파일들을 동시에 호출하게 됩니다

따라서 User Component의 개수에 따라 그 속에 포함된 include 파일의 개수에 따라 속도 차이가 발생하므로 최초 로딩 속도가 문제가 된다면 점검이 필요한 사항 입니다

Include 파일 최소화

1. Division 및 Tabpage url를 통한 서브 페이지 지정시 포함된 파일의 개수가 많으면 많을수록 호출(Request)및 로딩 작업이 추가적으로 처리되기 때문에 가급적 적게 사용하는 것이 좋습니다

2,화면에 포함된 include js(*.xjs)파일이 개발 편의상 하나로 묶어 삽입하는 경우가 대부분 입니다

하나로 묶인 include 파일을 열어보면 안에 많은 js파일이 또 include되어 있는 구조로 되어 있다면 되도록 필요한 파일만 include 하도록 하고 include된 xjs파일안에 또 재귀적으로 같은 파일이 include되는파일이 없도록 하는 것이 좋습니다

그리드에서 expr 사용점검

그리드에서 컬럼별 expr 사용은 스크립트의 처리량을 증가시켜 상당한 부하를 일의키는 주요 요인 중에 하나 입니다.

사실 이 부분은 구현상 편의성 측면에서는 상당히 유용하나 성능적인 측면에서는 상반된 결과를 초래하는 것으로 어찌되었건 성능을 고려한다면 사용을 자제하고 우회하는 방법을 찾아야 합니다

  • Expr을 지정할 수 있는 셀 중 컬럼을 지정할 수 있는 속성은 되도록 컬럼 바인딩으로 처리, 이때 해당 해당 값을 처리할 별도의 컬럼이 필요 하고 컬럼에 값을 지정해 주는 처리 필요

행(row) 별 동적인 처리가 필요 없는 것은 스크립트에서 후처리로 구현

: 주로 그리드 style 및 Summary 영역에 데이터셋 관련된 get관련 계산식 함수

(예: rowcount, getSum,getMax,getMin,getCount 등)들은 Grid.setCellProperty() 메서드로 처리하도록 변경

var dSum = Dataset00.getSum("amount");

var bSucc = Grid00.setCellProperty( "Summary", 0, "text", dSum);

서버에서 결과값을 전송받아 표시 가능한 것은 화면에서 expr을 제거하고 대신 사용

웹서비스 경로 지정시 되도록 prefixed 사용

스크립트에서 객체에 웹서비스 경로 지정시 전체 경로를 바로 지정하는 것보다 Services항목에 지정된 prefixid를 이용하여 호출하는 것이 성능에 좋습니다

예)

[ 변경전 ]

ImageViewer.image = "URL('http://www.tobesoft.com/logo.gif')"

[ 변경후 ]

Services항목에 prefixed = “ImageHost”, url=’'http://www.tobesoft.com/’ 이 등록되어 있다면

ImageViewer.image = "URL(‘ImageHost::logo.gif')"

Tab 컴포넌트에서 preload 설정

Preload는 TabPage에 연결된 Form의 onload 이벤트 발생 시점을 지정하는 속성입니다

tab.preload=false 일 경우

tab.tabindex 에 해당하는 TabPage 만 로딩 한 후 main form의 onload 이벤트가 발생합니다.

나머지 tabpage는 해당 TabPage가 activate 됐을 경우 로딩됩니다.

tab.preload=true 일 경우

main form 실행시 tab 에 있는 모든 TabPage를 로딩합니다.

main form의 onload 이벤트도 TabPage가 모두 로딩된 후 발생합니다.

속성값을 true로 지정 시에는 연결된 모든 Form을 초기에 열어 놓기 때문에 상황에 따라 시스템에 부하를 줄 수 있습니다

Preload=false 를 설정하여 활성화된 화면만 수행하도록 처리하는게 좋습니다

tracemode = 'none' 설정

Application 수행중 에러 내용이나 trace 함수 호출시 로그를 남길지 여부를 설정하는 속성입니다

tracemode='none'이 아닌 경우 Application 수행중 에러 내용이나 trace 함수 호출시 로그를 Client에 기록합니다

해당 log는 파일로 저장되기 때문에 운영환경 중 중요한 데이터를 기록하게 되면 보안에 심각한 문제를 끼칠 수 있을 뿐만 아니라

파일사이즈가 커지면 커질수록 파일 I/O에 따른 오버헤드(over-head)가 발생할 수 있어 성능에 악 영향을 미칠 수 있습니다

특히 tracemode='append'인 경우 기존에 있는 하나의 로그 파일에 지속적으로 기록되기 때문에 사용을 자제하여야 합니다

반드시 traceMode= “none”으로 설정하시고 불필요한 trace구문을 삭제하는게 좋습니다

XPlatform에서 traceMode 설정방법: xadl파일 속성에서 traceMode = none 로 설정

소스 컴파일

소스를 Compile된 XML로 저장하면 XML 자체를 암호화 할 수 있고 DOM 자체를 File 형태로 저장하므로 Browser가 기존 xml를 Parsing해서 Dom에 집어넣는 과정이 생략되므로 화면 Browsing 속도가 약간 빨라집니다 또한 70% ~ 80%로 정도의 파일 크기를 줄일 수 있습니다

File -> Save as Compiled XML(Project) 메뉴를 통해 처리하실 수 있습니다

메모리 사용량 줄이기

시스템을 계속해서 사용하다 보면 메모리가 지속적으로 증가하게 됩니다

이로 인해 PC의 성능에 따라 가용 메모리 부족으로 시스템 전체가 느려질 수 있습니다

아래는 불필요게 점유하고 있는 메모리 부분을 정리하여 최적화 해주는 API 입니다

타이머를 설정(setTimer)하여 일정 주기로 실행되게끔 하는 방법과 특정한 부분에 삽입하여 사용하시면 됩니다

var objExport = new ExtCommon();

var ret = objExport.EmptyWorkingSet();

EmptyWorkingSet() API는 2014.8.5.1 이상의 버전에 추가되었으므로 해당 이상의 버전을 사용하셔야 합니다

KeepAlive 사용 여부 설정

HTTP는 아시다 시피 connection less 방식으로 연결을 매번 끊고 새로 생성하는 구조입니다. 이는 network 비용측면에서 많은 비용을 소비하는 구조입니다.

( 최초 연결하기 위한 준비과정을 의미함 )

그래서 HTTP 1.1부터는 Keep-Alive라는 기능을 지원합니다.

Keep Alive란 연결된 socket에 IN/OUT의 access가 마지막으로 종료된 시점부터 정의된 시간까지 access가 없더라도 대기하는 구조입니다.

즉 정의된 시간내에 access가 이루어진다면 계속 연결된 상태를 유지할 수 있다는 것 이죠

즉 keep Alive time out내에 client에서 request를 재 요청하면 socket(port)를 새로 여는 것이 아니라 이미 열려 있는 socket(port)에 전송하는 구조가 됩니다.

이러한 기능을 사용하기 위해서는 Client에서 request에 Connection: Keep-Alive를 넣어서 Server에 전송하여야 하고 서버는 keep alive 기능을 활성화하고 keep alive time out을 설정 하셔야 합니다

XPlatform 입장에서는 Keep-Alive를 사용하겠다고 설정만 해주면 transaction 요청시 자동으로 request 해더에 Connection: Keep-Alive 상태로 전송하게 됩니다. 이후 처리는 서버에 영향을 받습니다

XPlatform에서 Keep Alive 설정방법: xadl파일 속성에서 Usehttpkeepalive = true 로 설정

Keep Alive는 기존의 접속을 재사용하는 것이므로 서버 부하가 적다는 장점이 있습니다

하지만 처리가 끝냈음에도 접속이 살아있어서 쉬게 되는 단점도 있습니다.

때문에 서버에서의 접속시간 설정이 중요합니다.