RSS구독하기:SUBSCRIBE TO RSS FEED
즐겨찾기추가:ADD FAVORITE
글쓰기:POST
관리자:ADMINISTRATOR

MySQL 성능을 죽이는 15가지 방법이라는 아주 재미있는 내용의 프리젠테이션...

MySQL 을 기반으로 한 다양한 웹 서비스들을 만들어가고 또 운영되는데 있어서
항상 MySQL 이라서 느려...MySQL 이니까 이 정도도 감지덕지... 라고 하지 말고
제대로 알고 제대로 쓸 수 있도록 해보자.
원문 : Jay Pipes@MySQL, Inc
http://www.slideshare.net/techdude/how-to-kill-mysql-performance


#1. Thinking too small
시작은 미미했으나... 그 끝도 미미 하리라는 생각은 버려라.

분명 시스템은 처음에는 매우 단순한 구조로 이루어지겠지만
커져가면서 결코 한 군데에 다 때려박아서 커버하기가 불가능해진다.

다수의 웹 서버들과 어플리케이션 서버 , DNS 서버 등의 여러 서버(혹은 서비스)들이 존재하게 된다.

이러한 서비스들에서 오는 모든 요청들로 인한 부하들이 집중되면 아무리 짱짱한 시스템이 들어와도 이를 감당해내기 힘들어진다.
그래서 부하들을 매 단계별로 Proxies 과 Caching 을 해서 최종적으로 넘어오는 부하의 양을 최소화 해야 할 필요가 있다.

특히 Caching 을 적극적으로 활용하지 않는 대형 웹 사이트를 존립시킬 수 없다.

그리고 각 서비스 컴포넌트 나 어플리케이션을 적극적으로 분리를 하고
무리하게 집중시키지 마라...
Scale-Up 을 통해서 성능향상을 바라는 것은 금방 한계점에 달하고 비용도 매우 많이 소요된다.
그보다 효율적으로 분산해서 처리하는 것이 더 현명한 선택이 될 것이다.

그리고 닥치기 전에 복제(replication) 나 분할(Partitioning) 에 대한 계획을 미리 수립하는 것이 좋다.
세션데이터는 최소화 하여 관리한다.

하지만 너무 허황될 만큼 크게 생각하진 말길.

성능이 반드시 확장성을 가져오는 것은 아니다.

#2. Not using EXPLAIN
EXPLAIN 은 입력된 SQL 문장을 해석하여 옵티마이져의 실행 계획을 보여주는 명령어 이다.
입력된 SQL 을 해석한 뒤 테이블의 데이터/인덱스 등을 판단하여 어떻게 실행 할지 보여주게 되는데.

Extra 컬럼에 "Using Index" 라고 나온다면 제대로 돌아 가고 있다 라고 봐도 거~~의~~ 무방하다.

특히 MySQL 5.0 이전 버전에서는 단 하나의 Index 만을 이용 할 수 있었는데.
MySQL 5.0+ 버전에서는 Index Merge optimization 을 통해서 좀더 향상된 속도를 얻을 수 있다.
이는 곧 인덱스 수립 계획에도 큰 도움이 된다. ( 슬라이드 Page 13 참조 )


#3. Choosing the wrong date types
Index ( 혹은 데이터) 는 가급적이면 단일블럭(Single Block) 안에 들어갈 수 있게 하는 것이 좋다.
기본적으로 DBMS 는 데이터가 늘어가면서 I/O 가 많이 일어나고 그리고 성능에 매우 민감하게 영향을 미치게 된다.
특히 디스크 처럼 매우 느린장치(CPU 연산 과정에서 보자면  HDD 는 아직 한참 멀었다.)에 접근 횟수를 줄일 수 있다면 당연히 느려진다는 것이다.

반대로 말하자면 데이터를 가져올때 횟수를 최소화 할 수 있다면 곧 속도향상을 얻을 수 있다라는 이야기.

그렇기 때문에 Index (혹은 데이터) 를 저장함에 있어서 가급적이면 최소한의 컬럼을 유지하는 것이 I/O 횟수를 줄이는데 유리하다.
슬라이드에서는 IP 정보를 저장할때 Varchar 형을 사용하거나 UNSIGNED INT 형을 사용 하는 2가지 경우를 가지고 이야기를 한다.

일반적으로 Varchar 형을 이용하여 저장하는 경우가 많은데. INET_ATON()/INET_NTOA() 함수를 이용하여 변환하여 INT 형에 저장 할 수 있게 되는데.
저장하는 데이터 크기도 줄이고 또한 Index range scan 을 통한 성능 향상도 꾀 할 수 있다는 장점이 있다.

슬라이드에서는 설명하고 있지 않지만 굳이 음수형으로 데이터를 저장할 필요가 없다면 UNSIGNED INT 와 같이 선언을 하게 되면 SIGNED INT로 선언했을 때 보다 약 2배 가량 속도 향상을 얻을 수도 있다고 한다.
그러니 *반드시* 필요한 데이터형의 크기를 잘 정해서 설계하는 것이 중요하다.

#4. Using persistent connection in PHP
MySQL 연결 시간(Connection Time) 을 줄이기 위해 영구적인 연결(Persistent Connection) 을 이용하는 경우가 있다.

하지만 영구적인 연결(Persistent Connection) 인 경우 자원을 공유하지 않은 구조로 인하여
Apache 프로세서가 Zombie 상태에 빠지게 되면 그대로 자원을 낭비하게 된다.

애초에 MySQL 은 수명이 짧고 경량형 으로 디자인 되어있어서 Connection Time 은 Oracle 이나 PostgreSQL 에 비해서 10~100배 가량 빠르다고 하니 pconnon_* 계열 에 목 매지 맙시다.

#5. Using a heavy DB abstraction layer
이식성(Portability) 때문에  ADODB , MDB2  혹은 PearDB 같은 무거운(Heavy) 추상화 라이브러리(abstraction Library) 를 쓰는데
그것 보단 PDO 같은 경량형 라이브러리를 이용하는 것이 좋다.  거기에 Scale-out 을 위한 부분도 추가해주 면 좋다.

#6. Not understanding storage engines
MySQL 에서는 매우 다양한 DB Engine 을 가지고 있는데 각 Engine 의 특성에 따라서
장 단점이 있는데 이에 대한 이해를 통해 적절한 Storage Engine 을 활용하면 보다 나은 성능을 발 휘 할 수 있다.

반대로 그러한 이해가 없이 사용하면 오히려 성능저하의 원인이 되기도 한다.

예를 들어 웹 로그 기록 같이 한번 입력하면 변경은 이루어지지 않고 고속의 INSERT 성능이 필요한 경우엔 Archive Engine 을 쓰는 것이 낫다 더욱이 압축 효율 또한 우수하여 ( MyISAM 대비 6~8배 ) 디스크 관리에도 유리하다.

반대로 주간 베스트 와 같이 크지는 않지만 빠른 입출력이 필요한 경우 Memory Engine 을 사용하면 Disk based Engine 에 비하여
획기적으로 빠른 성능을 제공 할 수 있다.

이처럼 적절한 Engine 을 활용 하는 것이 보다 나은 성능을 보장해준다.
다시 한번 말하지만 InnoDB 는 어디에도 붙일 수 있지만 성능을 보장해주는 것은 아니다.


#7. Not understanding index layouts
INDEX 선정과 Storage Engine 을 선탁하는데 매우 중요한 부분이다.
모든 Engine 들 은 Data 와 Index 를 메모리(Memory) 와 디스크 ( Disk ) 에 저장 한다.

Clustered 방식은 Primary Key 를 기준으로 정렬된 Data 묶음 단위로 디스크에 저장을 하고
Non-Clustered 는 그렇지 않다.

Non-Clustered 의 경우에는 큰 영향은 없지만.
Clustered 의 경우 데이터를 검색 할 경우 Primary key 를 보고 실제 데이터로 이동하여 데이터를 검색 하기 때문에
데이터 조회시 가급적 PK 를 이용하여 데이터를 검색하는 것이 좋다.

그리고 Clustered  방식에서 생성되는 모든 Second Index 는 PK 를 참조하여 만드므로 PK 는 최대한 작게 만들어주는 것이 좋다.

#8. Not understanding how the query cache works
사용하는 Application 의 Read/Write 비율을 이해한 상황에서
CPU 사용율과 읽기 성능을 적절하게 조율해야 한다.

Query Cache 를 늘린다고 성능이 무작정 증가하지도 않는다.

Cache 검증하는데 매우 투박한 검증방식 을 채용했는데
이유는 Cache 된 데이터를 찾아서 저장하는데 너무 많은 CPU 자원을 사용을 방지 하기 위해서 이다.

이는 SELECT 할 때 Table 에 어떠한 변화가 생긴 경우 모든 Cache 정보들은 유효하지 않게 된다는 것이다.
결국 Table 에 매번 변화가 생길 경우 매번 Cache 갱신을 하게 되고
Query Cache 의 효율이 떨어지게 되는 것이다.

그래서 자주 업데이트 되는 컬럼들을 분리 할 필요가 있다.

#9. Using stored procedures improperly
모든 RDBMS 는 Connection thread 별로 컴파일(Compiled)된 Stored Procedure 의 실행 계획을 유지하게 되는데

이것은 PHP 로 만든 페이지에서 요청을 보내서 SP 를 이용하여 데이터를 가져온다면
매번 컴파일을 거친다는 것이고 이것은 매우 큰 낭비라는 것이다(7~8% 정도)

특별히 매우 복잡하고 요쳥 빈도수가 많지 않은 작업이거나...
한번에 매우 많은 횟수의 Query 를 요청하는 경우가 아니라면....말이다.

그냥 Prepared Statements 를 써라...

#10. Operating on an indexed column with a function
Index Column 을 펑션으로 변환해서 사용하게 되면 Index 를 사용할 수 없게 된다.
그러니 있는 그대로 Index Column 을 사용 할 수 있도록 하는 것이 중요하다.

#11. Having missing or useless indexes
Index 는 SELECT 할때 검색 속도 향상에 매우 도움이 크다.

하지만 사용하지 않는(혹은 빈도 수가 매우 적은) Index 는 INSERT/UPDATE/DELETE 할때 매우 부담이 된다.
필요 없는 Index 는 반드시 삭제해주는 것이 좋다.

혹시 대량의 데이터를 입력이 필요 할 경우 경우에 따라서는 INDEX 를 삭제한 뒤
입력을 완료하고 인덱스를 생성하는 것이 나을 것이다.

#12. Not being a join-fu master
최대한 단순하게
복잡한 SQL 문을 쪼개서 데이터 묶음(Sets)으로 생각하라.

반복된 작업(Subquery,loop) 가 아닌 데이터 묶음(Join)으로 생각 해야 한다.
데이터의 묶음으로 처리하기 때문에 보다 나은 성능을 얻을 수 있다.

( 46~48p 를 반드시 참조하라!)

#13. Not accounting for deep scans
정렬된 데이터(ordered set)에서 매우 깊숙한(Deep scan) 곳에 데이터의 일부를 가져오는 것은 비용이 매우 많이 든다.

보통 게시판의 Paging 을 하면서 LIMIT 를 이용하게 되는데

페이지 넘버가 커지면 커질 수록 느려지는 경험을 해봤을 것이다.

이유는  LIMIT 를 이용하여 목록을 가져 오는 경우
1. 데이터를 정렬하고
2. 검색에 필요한 위치(offset) 을 지정해서 목록을 가져 온다.

여기서 데이터를 가져오는 위치(offset) 이 크면 클 수록 그 만큼 scan 을 하는 비용이

Full scan 비용에 근접하게 된다.
이를 피하기 위해선 해당 정렬된 데이터(Ordered set)의 크기를 줄여서 가져오는 것이 보다 나은 성능을 보장 할 수 있다.

#14. Doing SELECT COUNT(*) without WHERE on an InnoDB table
InnoDB 는 SELECT count(*) 로 Table 전체 Row 개 수를 가져오는 작업은 매우 퍼포먼스가 느린 작업이다.


InnoDB 내부적으로 매우 복잡(?) 한 구조로 인하여 생긴 문제인데 ( MyISAM 에서는....괜찮았다...)

필요하다면 별도의 테이블을 생성하여 Table 마다 Trigger 를 작성하여 Table Row count 를 관리하도록 하는 것도 방법이 되겠다.

#15. Not profiling or benchmarking
시스템 성능의 Bottleneck 을 항상 관찰하고(Profiling)
어플리케이션의 성능이 어느정도 까지 버틸 수 있는지 얼만큼의 부하를 견딜 수 있는지 테스트(Benchmark) 해볼 필요가 있다.

(54~56p 참조)

#16. Not using AUTO_INCREMENT
MySQL 에서 AUTO_INCREMENT 는 매우 PK 에 최적화 되어있다.

복합적으로 진행 되는 매우 많은 INSERT 에도 고성능으로 처리가 가능하다.
(Lockless reading and appending)

#17. Not using ON DUPLICATE KEY UPDATE
Application 에서 해당 Row 가 존재하는지 보고 Update or INSERT 를 결정하는 경우가 있는데
DB Connection 을 오가면서 소모되는 비용을 줄 일 수 있다. ( 약 5~6% 정도 )
물론 많은 양의 데이터가 와도 가능하다.

http://joinfu.com/presentations/kill-mysql-performance/kill-mysql-performance.pdf
http://ppassa.wordpress.com/2011/05/15/mysql-optimization-with-indexing/
2012/02/14 00:36 2012/02/14 00:36
이 글에는 트랙백을 보낼 수 없습니다
[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다



아래에 나왔던 웹 성능향상을 위한 14가지의 룰! 에 대한 발표 화면입니다.
 출처 : Y! Developer Network ( Y! Theater )
2008/03/30 13:23 2008/03/30 13:23
이 글에는 트랙백을 보낼 수 없습니다
[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다

재미있는 실험내용이 있어서 이렇게 펌질!~

전송속도 와 대기시간에 따른 페이지 로딩 시간에 관한 실험!

요즘은 너무 광대역폭 빠른 응답속도를 자랑하는 네트워크 망을 가져버린 상황인 지금은 크게 문제가 안되는듯 보이지만.

외국에선 아직도 회선 상태가 좋지 않다보니 이런 테스트도 아직도(?) 하는가보다.
(사실 -_-;; 가장 중요한것 아닌가!!!!!...이런 무개념을!! *쿨럭~*)

Time_to_load_wsj


월스트리트 저널의 홈페이지를 기준으로 테스트를 했는데.

여기서 한가지 재미있는 사실은..
대역폭의 감소보다 대기시간이 길어질 수록 로딩 시간이 더욱더 크게 벌어졌다는것이다.

대기시간이 길어지면서 패킷을 잃게 되고 다시 재전송을 하는데 소비되는 시간이 생각보다 크다는 것이다.

하지만 요즘 사용하는 대부분의 브라우저는 페이지 구성에 필요한 요소들을 다중으로 전송이 가능하다. 그렇다면 그와 연관된 모든 요소들을 한번에 땡겨오면 크게 차이가 나지 않아야 정상이 아닌가?

그렇다면 왜 저런 결과가 나왔을까?

본문에서는 기본적으로 HTML 소스를 읽어 오면서 그와 연관된 소스들을 다운로드
할 수 있어야 하는데, 문제는 "연관된 모든 요소들" 을 브라우저는 모르기 때문이다! 라고 이야기 한다.
HTML 을 모두 해석한 뒤 DOM tree 를 해석하고, 그 다음에 <img> 태그와 같은 외부 소스를 요청하는 것들을 처리하기 시작한다.

문제는 외부 Javascript 파일을 로딩하면서 발생한다.
Script 가 호출이 되기 전까진 HTML 을 해석하는 과정이 모두 중지된다. 여기에 document.write() 와 같은 부분이 끝 마치기 전까진 말이다.
이런것들이 대기시간을 더욱더 길게 만드는 것이다.

여기에 document.write 등으로 외부 소스를 호출하게 되면 더욱더 심각해져간다.


그래서 이 아저씨들이 수정을 살짝쿵 하였는데!
Time_to_load_wsj_preloading

스크립트 로딩하는 동안  메인 해석기( Main Parser) 가 멈춰져 있는 동안.
별도의 해석기 ( Side parser )기 가 나머지 HTML 소스를 기반으로 다른 외부 파일들(이미지,CSS,JS등 )을 호출을 하게 하여 대기시간에 따른 로딩시간 저하 현상을 최소화 하게 한다.

그 차이를 좀더 명확하게 보여주자면 다음 그래프를 보아라!
사용자 삽입 이미지

괜찮은 구조인거 같다..
사실 대역폭과 대기시간은 물리적인 문제라 S/W 적으로 해결하는데는
많은 어려움이 따르기 마련이지만 저정도 수준이면 상당히 의미있는것이 아닌가 한다.

모 CF 광고 처럼.. 미묘한 차이가 명품(?)을 만드는...?

참고 : Webkit - Optimizing Page Loading in the Web Browser
         Ajaxian.com - The importance of bandwidth versus latency
2008/03/29 03:37 2008/03/29 03:37
이 글에는 트랙백을 보낼 수 없습니다
peecky  | 2008/03/29 23:04
innerHTML 콘텐츠 삽입은 지원하면서 document.write 때문에 파싱을 멈추는 건가요~_~?
Dot  | 2008/03/30 12:49
그렇다기 보단 <script></script> 블럭의 연산중에 다른 부분에 대한 로딩이 제한이 된다고 봐야 할듯.
[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다


Yahoo 에서 웹 서비스 속도향상(혹은 개선..)을 위한 '습관들(?)' 을 새로이 올려놨음에
이에 여지없이 펌질을..

그다지 큰 규모의 웹 서비스..가 아닌 사이트에서는 (개인 홈페이지 ,묻혀진 중소 업체들의 페이지..혹은 존재감 없는 개인 만의 은밀한 사이트..) 에서는 그다지 표가 나지 않을 수도 있다.
.....고 하겠지만 전혀 아니다.

단지 그 차이점에서 오는 손익의 차이 정도가 있을 뿐이다.

슬라이드에서 나왔던 예시중에
Google 과 Amazon 가 나온다..
 - 500ms 정도 느려지면 Google 에선 평균 트래픽 발생량이 20% 가 감소한다.
 - 100ms 정도 느려지면 Amazon 에서 판매량이 1% 감소된다..

2008년 01월 google 사의 방문수는 총 1.34억 회... ( 자료 : comScore Media Metrix 2008. 01 (미국내 기준..))
Amazon.com 의 2007년 4분기 매출액은 56.7억불 ( 자료 : Yahoo Finance )

저것을 기준으로 한다면
Google 은 월 평균 2700만명 의 방문자를 놓치게 되며..
Amazon 은 매 분기별 5600만불에 달하는 손해를 입게 된다..

기준점이 될런지 모르겠지만 대략 저들에게 있어서 0.1초의 중요함을 대신 느껴보는게 어떠한가.

당신의 웹 사이트 속도를 향상 시키기 위해서 과연 무엇을 해야 할 것인가.
Yahoo에서 이전에도 이와 비슷한 PT 를 발표한적이 있다.
(Firefox Add-on 인 YSlow 를 설치해도 볼 수 있는..)

거기서 다루는 14개의 조건 들 이외에 추가로 20여개의 주제를 다룬다.

1.  HTTP 요청횟수를 최소화 하라.. (Make fewer HTTP requests)
 요청하는 요소들 (Components) 를 최소화 하는것이 빠른 페이지 로딩에 도움이 된다.
 이는 다수의 HTTP 요청에 의한 오버헤드(overhead) 를 줄여주기 때문이다.
 이를 위해선 CSS/Javascript 등을 통합하여 사용 하거나 이미지는 CSS 스프라이트(Sprites) 를 이용하는게 좋다.

CSS 스프라이트 (CSS sprites) 라는 것은 예전에 게임 등에서 도 이용했던 방법인데
하나의 이미지를 로딩하여 해당 이미지의 일정 부분 만 출력하되 롤오버나 이미지 변환등을
구현할때 해당 이미지의 background-position 을 이동하면서 비슷한 효과를 내는걸 말한다.

2. CDN(Contents Delivery Network) 을 이용하라 ( Use a Contents Delivery Network)
 정적 요소( 이미지나 js 등 특별히 변화되는 파일이 아닌 모든것들..) 을 최종 사용자에게 빠르게 전달하기 위해서 사용자의 네트웍과 가장 근접한 네트웍에서 해당 컨텐츠를 전달하는 것이다....

하지만 실질적으로 이정도 규모를 제공할려면 역시 돈이 좀.;;

3. 캐쉬 제어 . ( Add Expires header or Cache-Control )
 일반적인 정적요소들 ( 이미지,js , css 혹은 내용이 변화 될리 없는 정적 문서 및 파일...) 은
캐쉬 유지시간을 아주 길게 잡아주거나 혹은 계속 캐쉬 하게 함으로써 . 브라우저에서 다시
해당 파일을 서버에 요청하지 않도록 한다. 물론 변경을 해야 할때는 해당 파일명을 바꾼다던지 해서 새로이 캐쉬를 하면 된다..

 동적으로 변화 되는 부분에 대해서는 정책에 따라 캐쉬를 제어 하는데.
 헤더 (Header) 의 Cache-Control 을 이용하거나 혹은 브라우저에서 If-Modified-Since 헤더(Header) 를 이용하여 갱신을 하도록 한다.

 한마디로 동적 컨텐츠에 대해선 일정한 정책(policy) 을 세워 가급적 캐쉬 이용을 유도하는
방향으로 처리하는게 좋다는것이다.


4. 압축하라!! ( Gzip Components )
서버에서 압축해서 보내면 브라우저에서 알아서 압축을 풀게 된다.
요즘 사용하는 모든 브라우저는 기본적으로 제공하니 크게 문제 될리는 없을것이다.
(설마 아직도 IE3.01 이런걸 쓰는 사람들이??..)
가급적 모든 요소들( Components ) 을 압축전송을 하는게 좋다.

하지만 -_- 첨부 파일 다운로드 등을 시도할때
gzip 으로 압축해서 보내는 경우 문제가 생기기도 하는데 이럴땐 적절히 대응하는 것이 좋을듯.

5. CSS 선언은 맨 위에! ( CSS at the Top )
 FireFox 나 IE 는 CSS 파일이 로딩 될때까지 어떠한 내용도 랜더링 하지 않는다.
심지어 인쇄를 할때도 말이다. 그러니 가급적이면 Style 선언부를 맨 위에 올려 놓는게 좋다.

기억하라 일단 눈에 뭔가를 보여줘야 사용자들은 인내심을 가질 수 있다.

6. Javascript 는 맨 나중에. ( Move Script to the Bottom )
 Javascript 도 CSS 와 유사한 문제를 발생시키는데 이를 해결방안은 다르다. CSS 에서는 해당 StyleSheet 가 로딩될 때 까지 페이지 랜더링을 하지 않는데. Javascript 는 해당 스크립트를 로딩하는 동안 그 아래에 있는 모든 컨텐츠 요소들을 랜더링하지 않게 된다. 만약 해당 스크립트 처리에 시간이 오래 걸린다면 결국 전체 페이지 출력 시간에 문제가 될 수 있는 부분이다.

또 하나의 문제는 바로 HTTP 의 다중 연결(parallel downloads) 에 관한 문제다.
HTTP 1.1 규약에서는 호스트당 최대 2개 이상의 연결은 할 수 없다. 다만 다수의 호스트에 연결하여 2*n 개의 요소들(Components) 을 받아 올 수 있다( IE 에서는 100개 이상의 이미지를 한번에 로딩이 가능하다 한다..) 하지만 스크립트 파일을 로딩중엔 이것이 불가능하게 된다는 것이다. 결국 페이지 출력시간은 그만큼 딜레이가 된다는 것.!

(이부분에 대한 이해가 좀 딸리는데 영어빨도 안되다 보니 애먹은 부분이라 원문을 따로 링크를 붙여 놓습니다 . Yahoo Developer - Put JS at the bottom )

7. CSS Expression() 표현식은 가급적 자제해라. ( Avoid CSS Expressions )
 마땅히 해석할만한 말이 없어서 '표현식' 이라고 했는데.
내용은 간단하다. CSS 내에서 IE 5 부터 시작된 강력한 기능이라는데. 이건 IE 에서만 되는 기능에다가 또한 많은 연산을 발생시킨다.

한마디로 -_- 써봤자 좋을것 없는 짓이라는 결론..!

8. CSS 와 JS 를 HTML 에서 분리해라! ( Make Javascript And CSS externel )
 분리 해 놓으면 캐쉬정책에 따라 따로 로딩할 필요가 없게 되고 다른 페이지에서도 공통으로 이용 가능할 수도 있게 된다. 물론 좀더 많은 HTTP 연결을 요구하게 되겠지만 만약 이것이 HTML 페이지에 있었다면 그만큼 증가한 파일 사이즈 만큼 매번 로딩하게 될 것이다.
무엇이 유리할지는 당신이 판단하면 좋을듯~ ^^

9. DNS 에 질의를 줄여라! ( Reduce DNS lookups )
 DNS 가 어떤 역할을 하는지는 다 알것이다. 도메인 명 을 IP 주소로 변환해주는 역활을 하게 되는데 이것 또한 바로바로 되는것은 아니다. 보통 20~120ms (밀리세컨드) 정도 소요되는데 그동안 브라우져는 주소를 받을때 까진 조용히 손가락만 빨고 기다려야 한다는 것이다.

만약 DNS 정보를 Cache 해 놓는다면 좀 났겠지만 그 역시 ip 가 변동된다면 문제가 될것이다.

그렇지 못하다면 도메인 수 만큼 DNS 에 질의를 던져야 할것이고 그만큼 딜레이가 걸린다고 봐야한다. 하지만 도메인 수가 늘어나게 되면 병렬 처리수도 증가 한다는 이야기므로 적정선을 찾아본다면 좋을것이다. 슬라이드에서는 한페이지당 2~4개 정도의 도메인이 적절하다고 한다.

10. Javascript 의 다이어트! ( Minify JavaScript )
 무슨이야긴고 하니! Javascript 내에 불필요한 부분들은 모두 삭제를 한다는 것이다.
예를 들자면 주석나 긴 변수명을 짧게 한다던지 중간에 공백 문자열을 지운다던지 해서 말 그대로 전체 코드 사이즈를 줄인다는 것이다.

사실 주석 같은거야 인간이 보기 위해서 존재할뿐 컴퓨터에겐 전혀 의미가 없다.
장문의 주석은 컴퓨터에겐 쓸데없는 부분일 뿐이다. 하지만
하지만 코딩하는것은 어디까지나 인간 ! 그렇게 변환된 코드는 디버깅하는데 난해함을 줄 수 있다 .

그렇게 된 소스를 디버깅하는것은
인간의 인내심과 엄청난 시력! 그리고 손가락이 고생하게 된다...ㅡㅡ;;;

슬라이드에는 Dojo Compressor (ShrinkSafe), YUI compressorJSMin 을 소개하고 있는데 Dojo Compressor 같은 경우엔 어느정도 가독성을 보장한 형태로 코드를 다이어트 시켜주므로 한번쯤 써볼만 툴인거 같다.

11. 페이지 리다이렉트 연결은 가급적 자제 .( Avoid Redirect )
 HTTP 연결을 시도하지만 바로 다른곳으로 보내게 된다. 결국 그것은 무의미한 HTTP 연결에 시간을 낭비했다고 봐야겠다. 게다가 History Back 버튼에 대한 연결 처리도 신경서야 할것이다.

자주 겪게 되는 리다이렉트 문제가 URL 끝에 디렉토리 PATH 의 슬래쉬(/) 를 빼먹어서 리다이렉트 되는 경우다 Apache 의 mod_rewrite 나 Alias 를 이용해서 처리 할 수도 있다는데.

리다이렉트 를 너무 많이 쓰다보면 개발자들이 혼란을 겪을 우려도 있고 가급적이면 지양해야하는 편이 좋다!


12. 중복된 스크립트 제거 ( Remove Duplicate Scripts )
굳이 말이 필요할까 ㅡㅡ? 말 그대로 같은 파일을 또다시 로딩할 필요는 없는데 또다시 로딩하지 않도록 제거해야 한다는 이야기다.

13. ETags 설정! ( Configure ETags )
이것은 브라우져에서 캐쉬된 파일의 갱신 여부를 확인하기 위해서 참조하는 정보이다.
이것을 참조하여 해당 파일이 변동 되었는지 체크하기 때문에 캐쉬 관리에 좀더 도움이 될것이다.


14. Ajax 도 예외는 아니다! ( Make Ajax Cacheable )
 수많은 Web 2.0  Ajax 로 구현한 어플리케이션도 위에서 말했던 요소들처럼 Gzip등을 이용해서 압축전송을 하고 캐쉬가능한 데이터는 캐쉬하도록 구현하는 것이다.!
 
Ajax 자체가 비동기식 처리 방식 덕분에 페이지 표시에 그다지 문제가 되지 않을것 같지만.
어디까지나 처리하는데 실제 보여지는 페이지에 들어나지 않지만 그것이 페이지 표시에 신속함을 말하는것은 아니다.

게다가 비동기 처리로 인하여 서버로 요청횟수가 기하 급수적으로 늘어날 수 있다.
만약 이것이 비용이 적은 연산이라면 모르겠지만 다수의 메세지를 로딩한다거나. 큰 파일을 불러온다든지의 비용이 큰 연산이라면 그것은 서버의 전체적인 속도에 영향을 미치게 된다.

이를 막기 위해서 가급적 한번 로딩된 데이터들은 캐쉬 해뒀다가 다시 서버로 요청이
가지 않도록 프로그래밍 하는것이 적절할 것이다. 이것은 빠른 응답속도와 서버 리소스의 효율적인 사용을 위해서도 꼭!! 필요한것이다.




여기 까지가 이전에 언급하였던 웹 14가지의 요건들이다.

여기까지 모두 클리어 하였다면 !!
( YSlow 에서 위 조건을 모두 충족 시켜주면 "A" 라는 평가를 받게 된다 ㅡㅡ;;..)

그 다음엔 무엇을 해야 하는가!!!

1. 서버에서는!! ( Tag : Server )
 - 버퍼를 빨리 빨리 비워라!! ( Flush the Buffer early )
   * Server-Side Script 언어들 에서는 출력을 위해서 버퍼에 처리 결과를 담게 된다.
     하지만 중간에 처리되는 부분이 오래 걸리게 되면 출력 시간에 지연이 오게 된다.
     이때 미리 처리 된 부분만큼 먼저 버퍼에 쌓인 처리 결과를 출력하는 것이다.! 그럼 보다 빠르게 출력됨을 알게 될것이고 이것은 체감상 빠르게 로딩됨을 느끼게 된다.

 - Ajax 요청은 GET 방식으로!
  * GET 방식이 데이터의 재사용하는데 좋고 POST 방식보다 전송 단계가 짧고 ( POST 방식은 헤더를 전송한뒤 데이터를 전송하게 된다 )  GET 방식의 경우엔 한 패킷에 전송이 가능하기 때문이다.
   GET 방식으로 전송되는 데이터 양에는 한계가 있지만 ( IE 경우 2KB 가 한계 ..) 굳이 POST 방식으로 보낼만큼의 데이터가 많은 경우가 흔한가??

2. 컨텐츠!! ( Tag : Content )
 - 무엇을 나중에 불러 올것인가.? ( Post-load Components )
  * 페이지의 어떤 부분이 가장 먼저 보여야 할 것인가 를 결정하는 것이다. 처음 부터 보여지지 않을 부분을 출력하기 위해서 로딩속도를 저하 시켜야 하는가? 페이지가 보여진뒤 로딩하면 그만 아닌가!! 그것을 위해서 Javascript 를 이용하는것이다! ( Rule .6 JS to the Bottom 참고 )
 
- 어떤것을 먼저 불러야 하는가! ( Preload components )
 *  위와 같은 맥락으로 사용자가 이후에 어떤 데이터를 불러 오게 될것인가. 미리 준비한다는 것이다. 분명 사용자들이 보편적으로 이용하는 패턴을 통해서 미리 사용자가 다음엔 이런것들을 찾게 되겠지 하고 미리 그 결과를 만들어 놓고 대기 하는 것이다. 그럼으로 하여 신속한 페이지 이동을 하게 될 수 있게 되는것이다.

 구글의 스프라이트 이미지 랄지 , 야후 검색에서 사용자가 다음 어떤 단어를 타이핑할 데이터를 검색 박스에 불러 온다던지 말이다.

- DOM 객체의 숫자를 줄여라! ( Reduce Number of DOM elements )
 * 이건 아주 근본적인 이야기다! 가장 빠른 로딩 시간을 보장하는것은 아무것도 띄우지 않은 화면이다. 페이지 에 객체가 늘어나고 복잡해지는 것은 그만큼 전송해야할 양이 늘어난다는 것이고 Javascript 에서 DOM 으로의 접근 속도도 느려지게 된다.
  또한 잘못된 Markup 문법 또한 문제가 된다.

- 쪼개라! ( Split components accross domain )
 * 최대한 동시 전송 가능한 갯수를 늘려라 . 하지만 너무 많이 늘려서 너무 많은 DNS질의를 보내지 않도록 한다 ( 2~4개 정도 )
 IE 8 에서는 호스트당 동시 처리 연결 갯수를 6개 로 늘린다는데..


- Iframe 을 남발하지 말라! ( Minimize the Number of IFRAMEs )
 * 광고나 다른 외부 컨텐츠를 불러오는데 유용하게 쓰일 수 있지만. 아무것도 안 부를땐 그냥 낭비일 뿐이고 페이지 로딩에 방해가 된다.

 - 못찾는 파일은 없애라! ( No 404s )
 * 404 는 Not Found 의 HTTP 오류 코드 다 ㅡㅡ;;; 보통 이렇게 못 찾는 파일이 있을 경우
  해당 파일을 호출하기 위해서 계속 로드를 하게 된다 이는 전체적인 로딩 시간을 잡아 먹게 되는데 외부 Javasript 파일을 못찾게 되면 브라우저에서는 계속 로딩할려고 시도하게 되고 결국 다른 요소(Components ) 의 로딩을 방해하게 된다.


3. Cookie ( Tag : Cookie )
 - 불 필요한 쿠키는 삭제하고, 쿠키의 크기는 가능한 최소화 한다!
  * 쿠키로 인하여 브라우져의 응답시간의 지연 현상이 일어나게 된다. 가급적이면 쿠키의 만료시간은 짧게 잡고 사용하지 않는 쿠키에 대해선 바로바로 삭제 해주는 것이 좋다.


4. 자바스크립트! ( Tag: Javascript )
 - DOM 접근을 최소화 하라!
  * DOM Access 는 상당히 느린 편이다. 가급적이면 캐쉬할 수 있도록 하며 Javascript 에 의한 수정은 삼가한다.

 - 보다 똑똑한 이벤트 관리방식을 이용하라! ( Develop Smart event handler )
  * onload 보단 DOMContentLoaded 를 써라!
  * 늘어나는 이벤트 들을 위해 attach listener 를 이용하라. ( ...이부분은 좀 -_-..)
  * IE 메모리 누수 현상이 있을만한 곳은 정리!
  * onresize 시엔 조심하라!

객체 혹은 다른 요소들(Components) 에 어떠한 이벤트가 호출이 되면 다양한 메소드 들을 호출하게 된다. 또한 요소들의 숫자가 기하 급수적으로 늘게 되면 일일히 각 요소들(Components)에게 등록된 이벤트 들을 수정하기도 힘겨워 지고 코드도 보기 힘들어진다.

그러기 위해 AttachEvent 나 eventListener 같은걸 이용하는것이 적절할 수도.


5. CSS !! ( Tag : CSS )
 - StyleSheet 파일은 위에서 언급했던 것 처럼 페이지 로딩 최 상단에 배치한다.
 - 필터 사용은 자제 ( Avoid filter )
  * IE 전용에 메모리도 많이 먹고 랜더링 중에 브라우져를 멎게 할 수도 있다.
    게다가 이미지에 먹히는게 아니라 블럭 에 먹히는 거라 원하게 나오지 않을 수도 있다.
   ** IE6 에서는 문제가 되었지만 IE7+ 에서는 수정 되었다 함


6. 이미지 ( Tag : Image )
 - 필요이상의 큰 팔레트 사이즈를 갖는 GIF 이미지를 만들지 말라! 너무 많은 색을 쓰는것도 파일 사이즈를 증가 시킨다.
 - GIF 를 PNG 로 대체 하라 ..대세는 이제 PNG 다!!
 - 이미지 헤더의 주석을 삭제하라! 이로써 이미지 용량을 많이 줄일 수 있다.(생각외로 큰듯..)
 - CSS sprite 최적화!
   * 가로든 세로든 이동할 방향을 결정하고 비슷한 색을 이용하여 만든다.
     단, 너무 크게는 만들지 말라 크게 만들면 파일 사이즈의 크기도 기하 급수적으로 늘어나기 때문이다~ 그러니 되도록이면 바싹바싹 빈공간을 최소화 하는것이 좋다!
 - 이미지를 HTML 에서 크기를 조절하지 말라!
  * 원본 크기에 안 맞게 나올 수 있다.
 - favicon. 는 최대한 작고 저장 가능하게.
 

7. 이동기기 ( Tag: Mobile )
 - 모든 요소들은 가급적 25K 보다 작게 만든다!
  * iPhone 에선 그보다 크면 캐쉬 불가.
  * 압축이 풀린 상태에서 25K 가 넘어가지 않게 한다.
  * HTML 코드도 최소화!



이렇게 최적화를 하는 이유는 앞서 슬라이드에서도 밝혔지만.
Server-Side 에서 최적화를 하는데는 분명 한계가 존재하고 들인 공에 비하면 크게 티가 나지 않는 경우가 많다.

실질적으로 사용자들이 체감하는 로딩속도는 최초 클릭후 무엇인가가 출력이 되고 있구나 라는것을 봤을때 부터다.

그 단 몇초만 잡는다면 이용자들에게 보다 쾌적함을 줄 수 있는 서비스가 될것이다.

누구라도 한번 로딩에 수십초씩 걸리는 서비스를 이용하길 바라는 사람은 없을것이다.

당신이 바꾼 한줄의 코드에 사용자들이 얼마나더 쾌적함을 느낄수 있느냐 없느냐는 분명 큰 차이다. 앞으로 웹 서비스는 계속 늘어날 것이다.

물론 모두가 Google 이나 Amazon 같은 서비스가 되진 않겠지만.
많이 티가 나진 않아도 보다 적은 비용으로 당신이 만든 서비스를 더 많은 사람들이 이용 할 수 있게 된다면 그것이 중요한것 아닐까?


참고 : Ajaxian.com - Yahoo release new performance best practices
         Yahoo Developer ( YSlow )
        
2008/03/29 02:40 2008/03/29 02:40
이 글에는 트랙백을 보낼 수 없습니다
peecky  | 2008/03/29 23:13
script태그에 defer가 표준 속성이군요.
(html 파싱 중에 스크립트로 컨텐츠 변경하도록 짜지는 않으니까, 앞으로 죄다 붙여야지...)
Dot  | 2008/03/30 12:50
표준이긴 한데 DEFER 속성을 제대로 해석하는 브라우져가 별로 없다는 이야기가..*안습*
peecky  | 2008/03/29 23:14
14번 뒤에꺼 링크도 좀 알려주셈
Dot  | 2008/03/30 13:07
그 뒤에 내용은 슬라이드 내용에서 발췌 ..
아직 웹에 공개된건 없는듯..
[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다
Dot:Where is ......
byDot
Where is ......
전체 (177)
주절거림 (60)
윈도우벽지 (2)
Shoveling.. (9)
주워들은것들.. (48)
요집이 괜찮더라!! (0)
찍사놀이 (7)
관심꺼리~ (4)
«   2024/04   »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        
  1. 내 맘대로 보는 세상  2009
    맘에 안드는 Internet Explorer 업데이트 방침!
  2. 시리니  2008
    브라우저 업데이트, 작지만 큰 실천입니다.
  3. Dinosur와 KM의 Blog  2007
    저도 보통 사람
  1. 2019/02 (1)
  2. 2018/07 (1)
  3. 2018/01 (11)
  4. 2017/12 (10)
  5. 2017/10 (1)