본문바로가기

Document

웹 퍼포먼스 향상 가이드

본 내용은 웹사이트 구축 시 보편적으로 많이 사용되는 가이드입니다.참고하여 개발에 적용하면 성능 향상에 도움을 줄 수 있습니다.

HTTP 요청 최소화

웹 사이트는 주로 마크업, 이미지, 스타일시트, 자바스크립트 등으로 구성됩니다. 각 구성 요소는 모두 웹 서버에 있으며,이들을 다운 받기 위해 HTTP 요청을 보내고 응답을 받는 데 많은 시간이 소요 될 수 있습니다. 이를 최소화하기 위해 다음의 방법을 사용하면 효과적입니다.

CSS 스프라이트 기법 활용

CSS 스프라이트 기법은 이미지 여러개를 하나로 만들고 스타일시트에서 background-position 속성을 설정해 필요한 부분의 이미지만 보여주는 기술입니다. 여러 이미지를 하나의 이미지로 합치기 때문에 HTTP 요청 횟수를 줄일 수 있고, 이미지의 컬러 테이블과 같은 메타 데이터를 하나로 합칠 수 있어 파일 크기가 줄어듭니다.

JavaScript 파일 통합 및 중복 방지

불필요한 요청 및 파일 사이즈를 줄이기 위하여 중복되는 스크립트를 최대한 제거하고 통합시키는 것이 좋습니다.이로 인해 HTTP 요청을 줄일 수 있습니다.

서비스 요청 건수 최소화

서비스의 응답시간은 요청 건수 및 패킷 사이즈, 서버성능 및 네트워크 환경에 따라 영향을 받습니다. 따라서 요청 항목을 최소화 하는게 중요하며 transaction처리시 같은 성격의 여러개 서비스는 개별로 요청하지 말고 그룹으로 묶어 한번에 요청하는게 좋습니다.

초기 렌더링 시 서비스 요청 최소화

화면의 최초 서비스 요청 후 받은 데이터를 이용하여 화면 구성에 필요한 추 처리 작업을 진행할 경우, 속도에 영향을 줄 수 있으므로 가능한 서비스단에서 후처리에 필요한 작업까지 진행하여 최종적인 데이터를 화면에 표현해 주는 것이 좋습니다.

ETag 헤더 설정

ETag는 HTTP/1.1에 기본으로 사용하도록 설정된 태그로서 파일캐시 및 갱신 진위여부를 가리는데 사용됩니다. 캐시와 밀접한 연관이 있으므로 외부파일의 헤더에는 ETag를 항상 설정하여 전송량을 최소화할 수 있습니다.

캐시 만료일 설정

웹페이지가 점점 각종 JavaScript, CSS, Images 등이 증가 하게 되며 이는 많은 HTTP 요청를 유발하게 됩니다. 하지만 expire header를 추가 한다면 이것들을 캐싱시킬수 있습니다.
Expire header를 사용하면 그 날짜가 지나기 전에는 resource를 재 호출하지 않습니다. 만약 아파치서버를 사용중이라면 ExpireDefault값을 이용하여 지정을 해줄수 있습니다.

파일 크기 최소화

gZip 압축

네트워크를 통해 HTTP 요청과 응답을 전송하는데 걸리는 시간에는 영향을 주는 여러 변수들이 있습니다.그 중 하나로 서버에서 HTML,JavaScript,CSS 등을 압축해서 리소스를 받는 시간을 줄임으로 성능을 개선시킬 수 있습니다.

가장 많이 사용하는 방법으로 gZip 압축을 사용합니다. 일반적으로 gZipping은 약 70%까지의 응답크기를 줄일 수 있습니다.다른 압축형식은 deflate이지만, 이것은 gzip보다는 덜 대중적이고 효과적이지 못합니다.

현재 대부분의 브라우저는 이 gZip 압축을 지원하고 있으며, 브라우저는 서버에게 Accept-Encoding 이라는 헤더를 통해서 지원 여부를 알려주고, 서버는 Content-Encoding 라는 헤더를 넣어서 보내는 방식으로 사용할 수 있습니다.

  • Accept-Encoding: gzip, deflate
  • Content-Encoding: gzip

각 서버(WAS)별 gZip 설정방법은 해당 밴더사에 문의하시기 바랍니다.

JavaScript 및 CSS의 압축

JavaScript 및 CSS의 사이즈를 Minify 하여 사이즈를 최소화하는 방법으로 성능을 높일 수 있습니다.
Minify는 파일 내부의 개행과 주석 그리고 인텐트(들여쓰기) 등, 시스템이 이해하기에 불필요한 문자열을 제거하여 용량을 줄이는 방법입니다.

비동기 통신 사용

순차적으로 처리되는 동기통신보다는 병렬처리를 하는 비동기 통신을 사용하게 되면 화면 로딩 및 처리속도를 높일 수 있습니다.
이는 동기통신에서는 순차적인 통신 요청에서 하나의 대기시간에 문제가 생기면 전체 통신 및 로딩 시간이 오래 걸려 시스템 성능 영향에 큰 영향을 줄 수 있습니다.

렌더링 성능 향상

JavaScript 및 CSS의 배치

CSS 파일은 페이지 제일 위쪽에 놓고 JavaScript 파일은 페이지 맨 아래쪽에 놓는 것이 좋습니다.

브라우저 렌더링 단계에 따르면 사용자에게 화면을 보여 주기 전에 렌더 트리를 생성해야 하는데, 이때 CSS 파일이 반드시 필요합니다. 스타일시트 파일을 최대한 빨리 다운로드해야 하는 이유입니다.따라서, CSS 파일은 head 태그 최상단에 놓은 것이 좋습니다

JavaScript 파일을 페이지 아래에 놓아야 하는 가장 큰 이유는 파일을 다운로드해서 실행하기 전까지 브라우저가 DOM 파싱도 중지하고 아무것도 렌더링하지 않기 때문입니다. 따라서 JavaScript 파일은 body 태그 최하단에 놓는 것이 좋습니다.

마크업 최적화

마크업 최적화는 전체 화면이 한꺼번에 나타나는 것이 아니라 영역별로 점진적으로 렌더링하게 하는데에 목적이 있습니다.
IE 브라우저에서는 table 태그를 렌더링할 때 표 안에 있는 텍스트와 이미지 등을 모두 파싱할 때까지 화면 표를 그리지 않습니다.
만약 body 태그부터 시작해서 전체 화면을 그리는 데 table 태그를 사용했다면, 한참 있다가 전체 화면이 한번에 보일 것이다. 반면에 파이어폭스에서는 table 태그가 모두 완료되기 전에도 표 안에 있는 각 요소가 보이기 때문에 부분적인 렌더링이 가능합니다.

  • 본문 전체를 table 태그로 감싸지 않도록 합니다.
  • 되도록 div 태그와 스타일시트를 이용해 레이아웃을 구성합니다.
  • 이미지 크기가 너무 크지 않게 합니다.
  • 중첩되는 태그들을 제거하여 DOM 요소의 수를 최대한 줄이도록 합니다.
Alopex UI 사용 시 성능 향상 TIP

DataBinding, Validator, Convert

selector 및 하위 요소를 탐색하며 수행되는 Javascript API 사용 시 selector 영역을 구체적이고, 최소한의 범위로 지정해야 합니다.

  • DataBinding : $(selector 범위 최소화).setData() / $(selector 범위 최소화).getData()
  • Validator : $(selector 범위 최소화).validator()
  • Convert : $(selector 범위 최소화).convert() / $a.convert(selector 범위 최소화)

부모 window에 include된 라이브러리(js, css 등)와 Popup 자식 window에 include될 라이브러리가 상당 부분 겹치는 경우 {iframe:true} 방식의 Popup을 사용하면 라이브러리의 불필요한 중복 로딩으로 성능 저하의 원인이 됩니다. 이럴 경우 {iframe:false} 방식의 사용을 고려할 수 있습니다.

Progress

duration(Progress overlay 생성 시 animation 효과), durationOff(Progress overlay 제거 시 animation 효과) 등 animation 관련 설정은 성능에 영향을 주기 때문에 상황에 따라 animation 효과를 적절히 설정 합니다.
또한, Progress 객체 생성 시, 변수에 저장하고, 제거 시 이를 재활용합니다.

var progress = $(selector).progress();
progress.remove();

Setup

Alopex Component 및 Javascript API 사용 시 공통 js(common.js 등) 내에 setup으로 코드 양을 줄입니다.

  • Component : $a.setup('dialog', {...}), $a.setup('datepicker', {...}) 등
  • Javascript API: $a.request.setup({...}), $a.navigation.setup({...}), $a.popup.setup({...}) 등

Storage

각 화면에 동일하게 사용되는 데이터는 각 화면에서 통신을 통해 가져오는 방식 보다는 동일 도메인 내 브라우저 종료 전 까지 데이터를 저장할 수 있는 $a.session(key, value) API 를 통해 저장 및 재사용 합니다.

Tree

createNode() 의 반복적 사용을 통해 다수의 Tree 노드 생성 시, 아래의 수동 리프레쉬 방식을 사용하는 것이 성능 향상에 도움이 됩니다.
createNode() 의 3번째 파라미터는 수동 리프레쉬 여부를 결정합니다.

$("#tree").createNode(node, data, true); 
$("#tree").refresh(); // 마지막 노드 추가 시