메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

한빛랩스 - 지식에 가능성을 머지하다 / 강의 콘텐츠 무료로 수강하시고 피드백을 남겨주세요. ▶︎

IT/모바일

Flex 애플리케이션의 성능을 보장하는 10가지 팁

한빛미디어

|

2009-09-15

|

by HANBIT

17,603

제공 : 한빛 네트워크
저자 : Andrew Trice
역자 : 이준하
원문 : 10 Tips for Flex Application Performance

플렉스 애플리케이션을 다룰 때 반드시 지켜주어야 하는 10가지 내용을 알아본다. 내용을 실천에 옮긴다면 좀 더 빠르고 간결하고 즉각적인 응답을 기대하게끔 만들 수 있다.

첫 번째 원칙 - 지저분한 코드를 정리하자.

코드를 깔끔하게 관리하는 것은 대부분의 경우 도움이 된다. 제대로 정돈된 읽기 편한 코드만을 이야기하는 것이 아니라 메모리 누수나 과도하게 CPU 자원을 점유하는 것과 같이 코드 뒤에 감추어진 문제점이 없는 상태를 의미한다.

1) 이벤트 리스너를 관리하자.
이 말에는 두 가지 의미가 있다. 첫 번째는 항상 더 이상 필요하지 않은 이벤트 리스너는 지워주어야 한다. 객체를 계속 참조하고 있으면 가비지 컬렉터가 동작하는 것을 방해하며 메모리 누수를 유발하게 되고 문제가 발생할 경우 원인을 추적하기 힘들게 만들고 애플리케이션의 성능을 저하시킨다. 이벤트 리스너를 사용할 때 약한 참조를 사용하게 되면 메모리 누수를 감소시킬 수 있다. 하지만 명시적으로 사용하지 않을 때에는 지워주는 것이 좋다. 두 번째로 이벤트 리스너를 지워주지 않을 경우 성능과 관련된 이슈가 발생할 수 있다. 이벤트 핸들러는 아무도 모르게 애플리케이션 내에서 발생하기도 한다. 자식 컴포넌트 내에서 이벤트를 발생시켰을 경우에 해당 이벤트는 DOM 목록을 타고 부모 객체로 올라가면서 동일한 이벤트를 발생시킨다. 이런 일을 막고자 한다면 명시적으로 이벤트 핸들러에서 특정한 타입의 이벤트를 처리하게 하며 애플리케이션에서 더 이상 필요하지 않은 이벤트 리스너들은 삭제해주어야 한다.

2) 로더를 정리하자.
일반적으로 어떤 객체를 사용하는 것은 (Image, SWFLoader 와 같은) 로더 기반에서 동작하게 된다. 최선의 방법은 unloadAndStop()을 호출해주어 해당 로더에서 컨텐츠를 제거해주고 GC가 동작하게 해야 한다. 이렇게 하면 시스템 리소스를 절약해줄 수 있고 CPU가 쓸데없이 낭비되는 것을 방지할 수 있다. 정적인 이미지 파일을 불러올 때도 이런 방식을 사용한다면 메모리가 꾸물꾸물 올라오는 것을 막아줄 수 있다.

3) 리소스를 한꺼번에 청소하자.
커스텀 컴포넌트나 데이터 관리자, 화면에서 객체의 리소스를 깨끗하게 청소해줄 수 있는 dispose()와 같은 함수를 만드는 것은 좋은 방식이다. dispose() 함수는 객체를 더 이상 사용하지 않는 시점에 명시적으로 호출된다. 그러면 dispose() 함수에서 더 이상 필요 없는 객체들을 처리하고 리소스에서 제거해주게 된다. 예를 들면 타이머를 멈추게 하고 이벤트 리스너를 제거해주며 로더에 올라온 객체들을 지워주는 일을 처리해주는 것이다. 메모리 누수나 CPU 점유율을 화면 뒤에서 잠식하는 것들을 제거해줄 수 있다. 물론 이러한 처리는 CPU를 사용해 동작하게 된다. 하지만 이 작업은 매우 쉬우며 객체를 명시적으로 처리할 때 하나하나 계산하며 관리하는 수고를 덜어준다. 괜히 시간낭비해가며 리소스를 계산하고 메모리 누수와 성능과 관련된 이슈를 처리하기 위한 비용을 들일 필요가 없다.

두 번째 원칙 - 하지 않아도 된다면 하지 말자.

다음 지침으로는 무언가를 하지 않아도 된다면 하지 않는 것이 좋다는 것이다. 물론 이것은 "일하지 말고 놀아라"나 "이빨을 닦지 않아도 좋다"는 것을 의미하지 않는다. 이러한 것은 해야 하는 것들이다. 대신에 계산을 필요로 하거나 리소스를 소비하게 되는 행동의 경우에는 필요하지 않다면 하지 않아야 한다는 것이다.

4) 컬렉션을 적절하게 다루자.
여기에는 관심을 기울여야 할 몇 가지가 있다. 잘못 코딩된 부분은 항상 적절하게 처리해주어야 한다. 컬렉션(ArrayCollection, XMLListCollection 등)은 array나 xmllist와 같은 원시 구조를 싸주는 헬퍼 클래스이다. 이런 원시 구조의 자료를 좀 더 쉽게 다룰 수 있게 컬렉션 클래스는 개발자들이 번거로워하는 연산처리를 대신해준다. 컬렉션은 기본적으로 바인딩처리가 되어있어 매번 아이템을 add, remove, update 할 때마다 이벤트가 호출된다. 그리고 매번 이벤트를 처리하면서 해당 컬렉션을 갱신하게 된다.

컬렉션의 사용을 최적화하기 위한 첫 번째 팁은 컬렉션에서 10만 건의 아이템을 업데이트 하는 작업을 하게 된다면 10만 번의 이벤트가 발생하게 된다. 이는 성능의 엄청난 부하를 가져오게 되고 애플리케이션의 UI처리가 막히기도 한다. 컬렉션이 계속 갱신될 필요가 없다면 disableAutoUpdate() 함수를 사용해서 강제적으로 컬렉션의 이벤트를 막아줄 수 있다. 그리고 작업이 완료되었을 때 enableAutoUpdate() 함수를 호출해서 다시 원상태로 돌려놓을 수 있다.

두 번째는 필요하지 않다면 컬렉션을 사용하지 않는 것이다. 10만 건의 아이템을 처리하는 작업이 있고 데이터바인딩이 필요하지 않다면 array를 사용하는 것이 좋다.

세 번째 팁은 컬렉션은 filter function만을 사용해서 필터링 처리해야 한다는 것이다. filter function을 적용할 때에는 새로운 객체를 컬렉션에 추가할 때마다 refresh() 함수를 호출하지 않아도 된다. 몇 가지 경우에 성능상 문제가 발생하기도 한다. 예를 들어 데이터그리드에 컬렉션을 연결하고 해당 컬렉션을 업데이트했다고 하자. 컬렉션에 필터 처리를 추가한 경우 컬렉션에 addItem 함수를 호출할 때 마다 필터링 처리가 발생하게 된다. 아이템을 추가한 다음에 refresh() 함수를 호출하게 되면 데이터그리드의 list data를 사용할 수 없게 된다. 그래서 전체 데이터그리드를 다시 연산해서 다시 그려주어야 한다. 이러한 부분은 최적화를 처리할 때 쉽게 놓치는 부분이며 애플리케이션의 성능을 좌우하는 부분이기도 하다.

5) 인스턴스 생성을 적절히 조정하자.
기본적으로 플렉스에 있는 네비게이션 컨테이너(탭바, 아코디언, 뷰스택 등)는 필요할 때만 자식을 만들게 된다. 이러한 작업방식은 필요치 않은 수천 개의 컴포넌트가 한꺼번에 생성되는 것을 막아주며 시스템 리소스를 점유하거나 멈춤 없이 애플리케이션이 부드럽게 동작하게 도와주게 된다. 생성되는 규칙을 바꿀 때에 신경을 쓰지 않는다면 큰 문제가 발생할 수 있다.

6) 객체를 재사용하자.
새로운 객체를 만드는 것보다 기존 객체를 재사용하는 것이 비용을 줄이는 방법이다.

7) 변경되지 않는다면 객체를 무효화/제거/다시무효화 하지 말자.
커스텀 컴포넌트를 만들 때 속성을 바꾸는 경우(게터/세터를 이용해서) 값이 바뀌지 않는 경우에는 컴포넌트의 속성을 무효화하지 않아야 한다. 이 작업은 컴포넌트에서 전체 무효와 이를 다시 처리하는 과정을 따르게 되며 속성들도 다시 지정되고 처리된다. 그리고 각 객체들도 디스플레이 리스트에 다시 그려지게 된다. 무언가 실제로 변경이 됐다면 해당 속성만 무효화시키면 된다. 아래는 해당 내용을 설명하기 위한 예제이다.
public function set myProperty( value : Number ) : void
{
  if ( _myProperty != value )
  {
    _myProperty = value;
    propertiesChanged = true;
    invalidateProperties();
    dispatchEvent( new Event( "change" ) );
  } 
}
세 번째 원칙 : 적절한 문법을 사용하자.

액션스크립트 언어는 적절하게 사용하면 성능을 향상시킬 수 있는 기능을 제공한다.

8) 타입 지정 객체를 사용하자.
다이나믹 객체들은 대부분 고유 영역을 가지고 있다. 이러한 것들은 포괄적이며 유연하며 속성들을 쉽게 변경할 수 있고 다양한 상황에서 사용할 수 있다. 하지만 타입이 지정된 객체를 가지고 있고 동적인 속성처리가 필요하지 않다면, 타입이 지정된 객체를 사용하기를 권장한다. 액션스크립트3 에서 타입 지정을 요구하는 이유 중 하나는 빠르게 처리되기 때문이다. 엄격한 타입으로 지정된 객체의 속성에 접근하는 것은 다이나믹 객체의 속성에 접근하는 것보다 간결하고 빠르다.

9) 적절하게 상수를 사용하자.
해당 변수가 변경될 일이 없고 항상 참조하는 것이라면 상수를 사용하자. 상수를 사용하는 것은 빠르게 접근할 수 있고 부하를 줄일 수 있다.

10) 스태틱 멤버를 사용하자.
static 속성과 함수는 호출하거나 접근 시에 변수의 인스턴스를 필요로 하지 않는다. 때문에 인스턴스를 만들지 않고 클래스에서 바로 접근할 수 있다. 그리고 객체를 인스턴스화하기 위한 메모리도 필요로 하지 않는다. 유틸리티 함수나 특정 인스턴스의 속성을 필요로 하지 않는다면 스태틱 함수로 생성하자. 9번에서 설명한 내용처럼 가능하면 스태틱 상수를 사용하기를 권장한다. 메모리의 점유를 최소화하고 클래스 인스턴스를 다루지 않아도 된다.

이러한 것들이 하찮고 작은 부분들 같지만 한번 따라해보자. 코딩 습관을 조금만 고쳐주고 여기서 강조한 부분을 지켜준다면 애플리케이션을 좀 더 안정적으로 만들 수 있을 것이다.
TAG :
댓글 입력
자료실

최근 본 상품0