DBCC INPUTBUFFER(SPID)
'데이터베이스 > MS-SQL' 카테고리의 다른 글
SQL Server 2005 암호화 함수 (0) | 2013.12.11 |
---|---|
DeadLock(교착상태) 모니터 하기 (0) | 2013.11.27 |
tempdb 관리 (0) | 2013.11.27 |
mdf 파일만 가지고 복구시키기 (0) | 2013.11.27 |
MSSQL 문자열 함수 (0) | 2013.11.01 |
DBCC INPUTBUFFER(SPID)
SQL Server 2005 암호화 함수 (0) | 2013.12.11 |
---|---|
DeadLock(교착상태) 모니터 하기 (0) | 2013.11.27 |
tempdb 관리 (0) | 2013.11.27 |
mdf 파일만 가지고 복구시키기 (0) | 2013.11.27 |
MSSQL 문자열 함수 (0) | 2013.11.01 |
새로 고침과 백스페이스 방지를 위한 방법 (0) | 2014.02.10 |
---|---|
[JavaScript] ESC와 BackSpace 막기 (0) | 2014.02.10 |
웹페이지 로딩속도 빠르게 하기 Image Sprite (0) | 2013.11.19 |
웹사이트 최적화 (펌) (0) | 2013.11.19 |
자바스크립트 튜닝을 통한 사용자 체감속도 높이기 (0) | 2013.11.14 |
MD5
SELECT SUBSTRING(sys.fn_varbintohexstr(HASHBYTES('MD5', 'abcd12345')), 3, 32)
SHA1
LOCK 프로세스 정보확인 (0) | 2014.01.03 |
---|---|
DeadLock(교착상태) 모니터 하기 (0) | 2013.11.27 |
tempdb 관리 (0) | 2013.11.27 |
mdf 파일만 가지고 복구시키기 (0) | 2013.11.27 |
MSSQL 문자열 함수 (0) | 2013.11.01 |
원본 글 : http://sqlmvp.kr/140164120810
최근 들어 서비스에서 DeadLock(교착상태) 이슈가 자주 발생 하여 이번 아티클은 DeadLock을 모니터링하는 방법에 대해서 알아 보도록 하겠습니다..
DeadLock(교착상태)?
한 태스크에서 잠근 리소스를 다른 태스크에서 잠그려고 하여 둘 이상의 태스크가 서로 영구적으로 차단하는 현상. (서로 맞물린 상태의 차단)
l 순환 교착(cycle DeadLock) : 서로 다른 개체를 차단할 때 발생
l 변환 교착(Conversion DeadLock) : 같은 대상에 대해 둘 이상의 세션이 동시에 잠금을 변경하려고 할 때발생
교착 상태를 일으킬 수 있는 리소스
l 잠금 : 개체, 페이지, 행, 메타데이터, 응용 프로그램 등의 리소스에 대한 잠금을 획득하려고대기 하는 경우.
l 작업자 스레드 : 사용 가능한 작업자 스레드를 대기하는 태스크가 교착 상태를 일으킬 수 있음.대기태스크가 모든 작업자 스레드를 차단하는 리소스를 소유하는 경우 교착상태 발생.
l 메모리 : 동시 요청이 사용 가능한 메모리보다 많은 메모리 부여를 대기하는 경우.
l 병렬 쿼리실행 관련 리소스 : 병렬쿼리에 속하지 않는 하나 이상의 다른 프로세스를 포함할 경우 서로 차단하여발생. 서버에서 새 쿼리 실행이 시작되거나 시스템에 작업자 스레드가 부족하여 시스템 작업이 예기치 않게변경되면 교착 상태가 발생.
l MARS(Multiple Active Result Sets)리소스 : MASRS에서여러 활성 요청의 인터리브를 제어하는데 사용.
DeadLock 감지하기.
교착 상태 검색은 데이터베이스 엔진 인스턴스의 모든 태스크에 대한 검색을 주기적으로 시작하는 잠금 모니터에서수행합니다.
l 기본 간격은 5초로 수행.
l 잠금 모니터스레드가 교착 상태를 발견하면 잠금 상태의 빈도에 따라 5초에서 최하100밀리초까지 교착 상태 검색 간격이 짧아 짐.
l 잠금 모니터스레드가 교착 상태 검색을 중지하면 데이터베이스 엔진은 검색 간격을 다시 5초로 늘림.
실습 환경
CREATE PROC SESSION_1 AS BEGIN TRAN UPDATE TBL_A SET COL5 = COL5 * 2 WHERE COL1 = 100 WAITFOR DELAY '00:00:03'; UPDATE TBL_B SET COL5 = COL5 * 2 WHERE COL1 = 100 ROLLBACK TRAN GO CREATE PROC SESSION_2 AS BEGIN TRAN UPDATE TBL_B SET COL5 = COL5 * 2 WHERE COL1 = 100 WAITFOR DELAY '00:00:03'; UPDATE TBL_A SET COL5 = COL5 * 2 WHERE COL1 = 100 ROLLBACK TRAN GO |
서로 다른 세션에서SESSION_1, SESSION_2 실행
1. sp_lock
2. DBCC TRACEON (1204, -1)
교착상태와 관련된 각 노드에 의해 형식이 지정된 교착 상태 정보를 보고.
3. DBCC TRACEON (1222, -1) --SQL Server 2005 이상사용
프로세스별 및 리소스별 순서로 교착상태의 정보를 보고
4. Profiler
5. Perfmon
6. DMV
SELECT TEXT, BLOCKING_SESSION_ID, COMMAND, DATABASE_ID,WAIT_TYPE,WAIT_RESOURCE, * FROM SYS.DM_EXEC_REQUESTS AS REQUEST CROSS APPLY SYS.DM_EXEC_SQL_TEXT(REQUEST.SQL_HANDLE) AS SQL_TEXT WHERE SESSION_ID > 50 AND SESSION_ID <> @@SPID AND BLOCKING_SESSION_ID <> 0 |
7. Job Alert
DeadLocK 최소화 하기
l 적절한 인덱스설정.
l 자원의 한쪽방향 액세스,
l 짧은 트랜잭션
l 테이블 크기최소화
l 잠금 제한시간 설정(SET LOCK_TIMEOUT)
l 적절한 격리수준(READ UNCOMMITTED)
l 하드웨어성능 향상
l 지속적인모니터링
참조 및 참고 사이트
l http://msdn.microsoft.com/ko-kr/library/ms178104(v=sql.105).aspx
LOCK 프로세스 정보확인 (0) | 2014.01.03 |
---|---|
SQL Server 2005 암호화 함수 (0) | 2013.12.11 |
tempdb 관리 (0) | 2013.11.27 |
mdf 파일만 가지고 복구시키기 (0) | 2013.11.27 |
MSSQL 문자열 함수 (0) | 2013.11.01 |
http://www.sqler.com/index.php?mid=bColumn&document_srl=589035
Tempdb 데이터베이스를 많이 사용하면 SQL Server에서 페이지를 할당 하려고 할때 경합이 발생 할 수 있다.
--tempdb를 많이 사용하는 예
-- 경합 확인 방법
SELECT * FROM SYS.SYSPROCESSES 시스템 테이블 출력에서
waitresource가 2:1:1(PFS 페이지)또는 2:1:3(SGAM 페이지)로 표시되며 경합 정도에 따라 SQL Server가 응답하지 않는것 처럼 나타날 수 있다.
--원인
혼합 익스텐트에서 페이지 할당의 일환으로 SQL Server는 PFS(Page Free Space) 페이지를 검색하여 어떤 혼합 페이지를 할당할 수 있는지 확인해야 합니다. PFS 페이지는 모든 페이지에서 사용할 수 있는 여유 공간을 추적하고 각 PFS 페이지는 약 8000 페이지를 추적합니다. PFS 및 SGAM 페이지를 변경하기 위해 적절한 동기화가 유지되며 이를 통해 잠시 동안 다른 수정 작업을 막을 수 있습니다.
-- 해결 방법
-- 참고 링크
SQL Server 2005 암호화 함수 (0) | 2013.12.11 |
---|---|
DeadLock(교착상태) 모니터 하기 (0) | 2013.11.27 |
mdf 파일만 가지고 복구시키기 (0) | 2013.11.27 |
MSSQL 문자열 함수 (0) | 2013.11.01 |
datepart 함수의 인수값 정리 (0) | 2013.09.27 |
Fix : Error Msg 1813, Level 16, State 2, Line 1
Could not open new database ‘yourdatabasename’. CREATE DATABASE is aborted.
This errors happens when corrupt database log are attempted to attach to new server. Solution of this error is little long and it involves restart of the server. I recommend following all the steps below in order without skipping any of them.
Fix/Solution/Workaround:
SQL Server logs are corrupted and they need to be rebuilt to make the database operational.
Follow all the steps in order. Replace the yourdatabasename name with real name of your database.
1. Create a new database with same name which you are trying to recover or restore. (In our error message it is yourdatabasename). Make sure the name of the MDF file (primary data file) and LDF files (Log files) same as previous database data and log file.
2. Stop SQL Server. Move original MDF file from older server (or location) to new server (or location) by replacing just created MDF file. Delete the LDF file of new server just created.
3. Start SQL Server. Database will be marked as suspect, which is expected.
4. Make sure system tables of Master database allows to update the values.USE MASTER
GO
sp_CONFIGURE 'allow updates', 1
RECONFIGURE WITH OVERRIDE
GO
5. Change database mode to emergency mode.
–Following statement will return the current status of the databaseSELECT *
FROM sysdatabases
WHERE name = 'yourdatabasename'
—-Following statement will update only one row in databaseBEGIN
UPDATE sysdatabases
SET status = 32768
WHERE name = 'yourdatabasename'
COMMIT TRAN
6. Restart SQL Server (This is must, if it is not done SQL Server will through an error)
7. Execute this DBCC command in query window of Management Studio, this will create new log file. Keep the name of this file same as LDF file just deleted from new server :DBCC TRACEON (3604)
DBCC REBUILD_LOG(yourdatabasename,'c:\yourdatabasename_log.ldf')
GO
DBCC accepts two parameters : first parameter is database name and second parameter is physical path of the log file. Make sure the path is physical, if you put logical file name it will return an error.
8. Reset the database status using following command.sp_RESETSTATUS yourdatabasename
GO
9. Turn off the update to system tables of Master database running following script.USE MASTER
GO
sp_CONFIGURE 'allow updates',0
RECONFIGURE WITH OVERRIDE
GO
This should be resolve the problem mentioned above. I always check consistence of the database as well as I reset the status of the database to original status.
10. Reset the database status to previous status
–Following statement will update only one row in databaseBEGIN
UPDATE sysdatabases
SET status = (value retrieved IN first query OF STEP 5)
WHERE name = 'yourdatabasename‘
COMMIT TRAN
GO'
Note : If during steps 8, 9 , 10 if there is error if database is in use.
Set the database to status single user.sp_DBOPTION 'yourdatabasename', 'single user','true'
Once the steps 8,9,10 are completed if database is not already in multi user mode run this script.sp_DBOPTION 'yourdatabasename', 'single user','false'
If there is any issue while doing above process to fix the error let me know. Make sure that you have done all the steps in order and restarted SQL Server where it is mentioned.
Reference : Pinal Dave (http://blog.SQLAuthority.com), BOL (many topics)
SQL Server 2005 암호화 함수 (0) | 2013.12.11 |
---|---|
DeadLock(교착상태) 모니터 하기 (0) | 2013.11.27 |
tempdb 관리 (0) | 2013.11.27 |
MSSQL 문자열 함수 (0) | 2013.11.01 |
datepart 함수의 인수값 정리 (0) | 2013.09.27 |
http://likenew.tistory.com/201
이미지 Request를 줄일 수 있는 팁이 자세한 설명과 함께 들어있어요.
[JavaScript] ESC와 BackSpace 막기 (0) | 2014.02.10 |
---|---|
HTML 긴 문자열 CSS로 자르기 - text-overflow:clip, ellipsis (0) | 2013.12.23 |
웹사이트 최적화 (펌) (0) | 2013.11.19 |
자바스크립트 튜닝을 통한 사용자 체감속도 높이기 (0) | 2013.11.14 |
페이지 빠르게 로딩하는 방법 (0) | 2013.11.12 |
제이콥 닐슨은 웹사이트의 반응 시간을 다음과 같이 평가한다.
제이콥닐슨은 웹페이지의 반응시간이 되도록 1초 이내여야 사용자 경험에 긍정적인 영향을 미친다고 분석했다.
브라우저가 어떤 단계로 동작하는지, 단계별로 얼마나 시간이 걸리는 지 정의한 연구 활동이 W3C의 내비게이션 타이밍 명세다. 다음 그림은 내비게이션 타이밍 명세에서 브라우저가 사용자의 요청을 처리하는 순서를 정리한 프로세싱 모델에서 웹페이지 최적화와 관련 있는 단계를 정리한 것이다.
사용자가 웹 서비스를 이용하다 다른 주소로 이동할 때 브라우저가 제일 먼저 실행하는 단계다. 다른 주소로 이동하기 전에 보고 있던 페이지에서 실행하는데, 브라우저 성능과 직결된다.
웹서비스를 이용하면 페이지가 표시될 때 우리도 모르게 이벤트가 할당되고 이때 메모리를 조금씩 사용한다. 그런데 이 메모리를 더 이상 사용하지 않을 때,즉 페이지를 떠날 때는 메모리를 해제해야 한다. 이 메모리 해제 작업이 서비스 이동 단계에서 실행하는 작업 가운데 하나다.
필요없는 메모리 해제를 담당하는 가비지 컬렉션 기능이 제대로 동작하지 않으면 브라우저가 응답 없음 상태가 되거나 실행 속도가 급격히 느려진다. 웹 페이지에서 동시에 많은 변수가 생성되고 처리되는 동안 브라우저에서 허용한 임계치를 넘었을 때 가비지 컬렉션이 동작하는데, 가비지 컬렉션이 동작하면 스크립트 실행이 중단된다. 가비지 컬렉션이 완료되기 전까지는 스크립트가 동작하지 못해 페이지가 느려지는 것이다.
서비스 이동 단계의 작업은 브라우저 내부에서 자동으로 실행한다. 만약 별도로 처리하려면 beforeunload 이벤트를 활용할 수 있다. beforeunload 이벤트를 활용하면 메모리 해제를 담당하는 모듈을 만들 수 있다.
서비스 이동 단계에서 일어나는 성능 문제를 개선하려면 필요 없는 변수나 객체를 삭제하고, 이벤트를 해제해 메모리를 관리해야 한다.
사용자가 요청한 URL에서 다른 URL로 다시 보내는 단계다. 쉰게 볼 수 있는 리다이렉트는 SNS에서 사용하는 단축 URL이다.
리다이렉트가 발생하면 상태 코드로 '301'이나 '302'를 반환한다. 리다이렉트가 발생하면 어떤 자원도 다운로드하지 않으며 브라우저에 일시적으로 빈 페이지가 보인다. 그렇기 때문에 의도하지 않게 리다이렉트가 발생한다면 바로 잡아야 한다.
리다이렉트 관련한 흔히 저지르는 실수 가운데 하나는 URL뒤에 슬래시(/)를 넣지 않아 302 redirect가 발생하는 것이다. 두번째 실수는 웹페이지를 이용한 리다이렉트다.
1.
<meta http-equiv=
"refresh"
content=
"1; url=http://www.naver.com/"
>
이 코드에는 두가지 성능 문제가 있다. 첫번째는 이 코드를 실행시킬 별도의 페이지를 거쳐야 리다이렉트된다는 점이다. 두번째는 최종 페이지에 도착했을 때 캐시가 설정된 리소스임에도 불구하고 조건부 GET 요청이 이뤄진다는 점이다. 조건부 GET 요청은 브라우저에 캐싱된 리소스를 사용하기 전에 해당 리소스를 사용해도 되는지 서버에 물어 보는 것이다. 이때 헤더의 If-Modified-Since 정보를 이용해 서버에 요청을 보낸다. 리소스가 수정되지 않았다면 '304 Not Modified' 코드를 받아 캐시에 있는 리소스를 사용한다. 자원이 수정됐다면 서버로부터 리소스를 다운로드 한다.
캐시의 만료 날짜를 설정했다면 서버의 확인을 거치지 않고 바로 캐싱된 리소스를 사용할 수 있는데, 메타태그로 리다이렉트하면 조건부 GET 요청으로 불필요한 서버 통신이 발생해 응답 속도가 느려진다.
웹 페이지의 주소뿐 아니라 이미지와 시타일시트, 자바스크립트와 같이 페이지를 구성하는 요소도 리다이렉트될 수 있다. HttpWatch로 301이나 302 상태 코드가 발생하는 요소들을 찾아서 바로 잡아야 한다.
리다이렉트 작업을 마치고 HTTP 요청을 처리하기 위한 준비를 마쳤다면 브라우저는 맨 먼저 서버로 요청을 보낸다. 서버에서 응답이 오면 개별 요소(이미지, 스타일시트, 자바스크립트 등)가 사용자 PC에 있는지 캐시 데이터를 찾는다. 별도로 설정하지 않았다면 윈도우 운영체제에서는 C:\Documents and Settings\{User}\Local Settings\Temporary Internet Files 디렉터리에 캐시 데이터가 있다. 캐시 데이터의 종류에는 쿠키, 이미지, 스크립트, 스타일시트 등이 있다.
캐시 데이터가 있는 이유는 무엇보다도 사용자가 동일한 페이지를 다시 방문했을 때 브라우저와 서버 사이에 통신을 하지 않고 캐시에 있는 자원을 사용하겠다는 것이다. 다시 방문한 사용자에게 좀 더 빠른 응답 속도를 제공하려면 애플리케이션 캐시를 잘 활용해야 한다.
프로세싱 모델의 DNS, TCP, Request, Response는 모두 네트워크 통신에 관련된 단계다. 네트워크 비용을 줄이는 첫번째 방법은 Expire 설정이나 Cache Control 속성을 이용해 사용자 웹 페이지에 다시 왔을 때 캐시를 사용하는 방법이다. 두번째 방법은 스타일시트나 자바스크립트와 같이 파일을 합쳐서 서비스해도 문제가 없는 리소스를 합쳐 하나의 링크로 제공해 요청 횟수를 줄이는 방법이다.
프로세싱 모델의 Processing과 onLoad에 해당하는 브라우저 처리 단계는 서버에서 받은 HTML과 이미지, 스타일시트를 조합해 사용자가 실제로 보는 화면을 만드는 단계다. 서버에 요청한 요소가 모두 도착하면 브라우저는 DOM을 생성하기 시작한다. 그리고 DOM이 존재하는 그 시점에 DOMContentLoaded 이벤트나 onload 이벤트가 발생한다. 하지만 두 이벤트는 발생 시점이 다르다.
onload 이벤트는 DOM에서 기본적으로 제공하는 이벤트로 문서에 있는 모든 이미지, 스타일시트, 자바스크립트 등이 모두 다운로드될 때마다 발생한다. 이와는 달리 DOMContentLoaded 이벤트는 기본적으로 DOM 생성에만 관련돼 있다.즉, DOM이 로딩되고 난 직후에 발생한다.
많은 양의 이벤트를 바인딩해야 하고 이미지나 스타일시트의 개수가 많은 페이지를 개발한다면 onload 이벤트보다는 DOMContentLoaded 이벤트를 이용하는 게 좋다.
HTTP 요청 최소화는 최적화에서 가장 기본이면서도 중요한 부분이다. 다운로드해야 하는 구성 요소의 개수를 줄이는 것은 가장 효과가 크고 중요한 최적화 방법이다.
이미지를 많이 사용하면서도 HTTP 요청을 최소화하는 방법 가운데 하나가 CSS 스프라이트 기법이다. CSS 스프라이트 기법은 이미지 여러 개를 하나로 만들고 스타일시트에서 background-position 속성을 설정해 필요한 부분의 이미지만 보여 주는 기술이다.
하나로 합친 CSS 스프라이트 이미지를 사용할 때는 다음 예제와 같은 형식으로 스타일 시트를 작성한다.
1.
/* CSS 스프라이트용 이미지를 설정한다. */
2.
.menu_list li a {background:url(http:
//example.com/some.png) no-repeat}
3.
4.
/* background-position 속성의 왼쪽과 위쪽 기준을 설정해 보여 줄 이미지를 지정한다. */
5.
.menu_list li a.me {background-position:0 0;}
/*첫번째 아이콘*/
6.
.menu_list li a.me {background-position:0 -52px;}
/* 52픽셀 아래에 있는 두번째 아이콘 */
헤더에 만료 날짜를 추가하는 이유는 웹페이지를 구성하는 이미지, 스타일시트 파일, 자바스크립트 파일 등을 사용자 컴퓨터의 캐시에 저장해서 재사용하기 위해서다.
만약, 만료 날짜 전에 수정사항이 있어 파일을 변경해야 한다면 파일 이름을 변경하거나 파일 이름 뒤에 쿼리스트링을 추가해 새로 추가된 파일임을 알려야 바로 반영된다.
1.
//방법1: 파일 이름을 변경한다.
2.
<script type=
"text/javascript"
src=
"some_20120622.js"
></script>
3.
4.
//방법2: 쿼리스트링을 추가한다.
5.
<script type=
"text/javascript"
src=
"some.js?20120622"
"></script>
브라우저에서 캐싱된 파일을 이용할지 서버에 요청할지 판단하는 기준은 파일이름과 인터넷 주소다. 그렇기 때문에 위와 같이 작업해서 파일 이름이나 파일의 주소를 바꾸지 않으면 계속같은 파일로 인식하고 사용자 컴퓨터에 있는 파일을 로딩한다.
성능을 높이는 방법중 하나로 여러 개의 자바스크립트 파일을 하나의 파일로 합쳐 파일 개수를 최소화하는 것이다. 웹사이트의 성능을 개선할 때는 파일의 용량보다 파일의 개수가 더 중요하다. 웹페이지의 성능을 높이는 제일 좋은 방법은 파일의 개수를 줄여 HTTP 요청을 최소화하는 것이다.
점점 커지는 자바스크립트 파일과 스타일시트 파일의 크기를 줄이는 가장 효과적이고 쉬운 방법은 파일을 압축하는 것이다. 아파치 웹서버에서 파일을 압축하는 대표적인 인코딩 방식으로 Gzip 방식을 사용한다. 보통 이미지 파일은 이미 압축돼 있기 때문에 압축하지 않고, 스타일시트 파일과 자바스크립트 파일을 압축한다. 스티브 사우더는 파일 크기가 1~2KB 이상일 때 압축할 것을 권장한다. Gzip으로 압축해 전송하면 평균 70% 정도 파일 크기가 작아지는 효과를 볼 수 있다.
렌더링 성능 향상의 목표는 페이지를 요청했을 때 사용자가 대기하는 시간을 최대한 줄여서 체감 속도를 높이는 것이다.
아래는 브라우저가 어떤 순서로 마크업을 파싱해서 화면에 보여주는지 기본적인 흐름이다.
스타일시트 파일은 페이지 제일 위쪽에 놓고 자바스크립트 파일은 페이지 맨 아래쪽에 놓아야 한다. 브라우저 렌더링 단계에 따르면 사용자에게 화면을 보여 주기 전에 렌더 트리를 생성해야 하는데, 이때 스타일시트 파일이 반드시 필요하다. 스타일시트 파일을 최대한 빨리 다운로드해야 하는 이유다.
자바스크립트 파일을 페이지 아래에 놓아야 하는 가장 큰 이유는 파일을 다운로드해서 실행하기 전까지 브라우저가 DOM 파싱도 중지하고 아무것도 렌더링하지 않기 때문이다. 따라서 자바스크립트 파일은 </body> 태그 바로 위에 놓는 것이 좋다.
인터넷 익스플로러에서는 <table> 태그를 렌더링할 때 표안에 있는 텍스트와 이미지 등을 모두 파싱할 때까지 화면에 표를 그리지 않는다. 그러므로 페이지 전체의 레이아웃을 <table> 태그로 구성하는 것을 피해야 한다. 또한 전체 태그의 개수(보통 1000개 이하를 권장)를 줄이는 것도 중요하지만 중첩된 태그를 최소로 하는 것이 더 중요하다.
배열은 생성자 혹은 리터럴 형식([])을 사용해 객체를 생성할 수 있다.
1.
// Array() 생성자를 사용한 배열 생성
2.
var arr =
new
Array();
1.
// 리터럴 형식으로 배열 생성
2.
var arr = [];
리터럴 형식을 사용한 경우에 여러 브라우저에서 좀 더 좋은 성능을 보인다.
배열의 각 요소에 데이터를 할당하는 방법에는 접근자 []를 사용하는 방법과 push() 메서드를 사용하는 방법이 있다.
1.
// 접근자를 사용한 데이터 할당
2.
var arr = [];
3.
4.
for
(var i=0;i<1000;i++){
5.
arr[i] = i;
6.
}
1.
// push() 메서드를 사용한 데이터 할당
2.
var arr = [];
3.
4.
for
(var i=0;i<1000;i++){
5.
arr.push(i);
6.
}
크롬을 제외한 대부분의 브라우저에서 접근자를 사용한 데이터 할당이 push() 메서드를 사용한 데이터 할당보다 성능이 더 좋다.
오브젝트 객체도 객체를 생성하고 초기화하는 방법으로 리터럴을 사용하는 방법과 생성자를 사용하는 방법이 있다.
1.
// 리터럴을 사용한 오브젝트 객체 생성
2.
var obj = {};
1.
// 생성자를 사용한 오브젝트 객체 생성
2.
var obj =
new
Object();
큰 차이는 없지만 리터럴을 사용하는 방법이 약간의 더 좋은 성능을 보인다.
오브젝트 객체를 초기화할 때는 .연산자를 이용한 방법과 []연산자를 이용한 방법이 있다.
01.
// .연산자를 이용한 데이터 삽입
02.
var obj = {};
03.
04.
obj.a = 1;
05.
obj.b = 2;
06.
obj.c = 3;
07.
obj.d = 4;
08.
obj.e = 5;
09.
obj.f = 6;
01.
// []연산자를 이용한 데이터 삽입
02.
var obj = {};
03.
04.
obj[
"a"
] = 1;
05.
obj[
"b"
] = 2;
06.
obj[
"c"
] = 3;
07.
obj[
"d"
] = 4;
08.
obj[
"e"
] = 5;
09.
obj[
"f"
] = 6;
safari를 제외한 대부분의 브라우저에서 비슷한 성능을 보였다. 단 safari에서는 .연산자가 더 좋은 성능을 보였다.
런타임 환경에서 자바스크립트의 실행 성능을 저해하는 요인이 변수, 객체, 함수 등의 메모리상의 위치를 찾는 탐색 작업이다.
함수를 실행하면서 변수, 객체 등에 접근해야 할 때 객체에 접근하기 위한 객체의 참조를 특정한 공간에 저장해 둔다. 이 공간이 바로 스코프 체인이다.
스코프 체인의 구성 요소에는 활성화 객체와 전역 객체가 있다. 함수 내부에서만 접근할 수 있는 함수의 지역변수나 this, arguments 객체 등은 스코프 체인의활성화 객체에 포함되며 함수 외부에서도 접근할 수 있는 window, document, 전역함수, 전역변수와 같은 속성은 스코프 체인의 전역 객체에 포함된다.
window, document 등의 전역객체는 웹페이지의 자바스크립트가 동작하는 모든 시간동안 존재하며, 함수 실행시 함수에서 전역속성을 탐색하는데 사용된다. 반면 활성화 객체는 함수가 실행되는 동안에만 존재하며, 함수 내부에서 자주 사용하는 데이터가 모여 있는 만큼 최우선으로 탐색하는 대상 객체가 된다.
실행문맥은 함수가 동작하는 환경을 나타내며, 브라우저 내부에서 사용되는 객체다. 실행문맥은 함수가 실행될 때 새로 생성되고 함수가 종료될 때 소멸되며 함수의 스코프 체인에 대한 참조를 가지고 있게 된다. 함수는 어떤 속성에 접근해야 할 때 실행문맥을 통해 스코프 체인에 접근한다.
실행문맥은 자신과 연관된 함수의 스코프 체인을 참조하고 있으며, 함수에서 접근해야 할 어떤 속성의 탐색 경로는 '실행문맥>스코프체인>활성화객체>스코프체인>전역 객체'와 같이 구성된다.
다음은 파라미터 값이 0인지 판별하는 isZero() 함수의 코드이다.
1.
function isZero(num){
2.
var res = (num === 0);
3.
return
res;
4.
}
5.
6.
var result = isZero(0);
isZero() 함수에 있는 구문을 실행할 때 함수의 파라미터 변수인 num과 함수의 지역변수로 선언된 res에 대해 해당 변수의 메모리에 접근해야 하는데, 둘 다 활성화 객체에 포함돼 있는 속성이기 때문에 '실행문맥>스코프 체인>활성화 객체'의 경로로 탐색해 접근한다. 전역 객체는 탐색하지 않는다. 만약 window, document 등의 전역변수에 접근해야 한다면 '실행문맥>스코프 체인>활성화 객체>스코프 체인>전역 객체'의 경로로 속성을 탐색했을 것이다. 즉, 활성화 객체를 먼저 탐색한 후 찾는 속성이 없을 때는 스코프 체인에 참조돼 있는 다음 탐색 대상인 전역 객체를 탐색하게 된다.
만약 함수가 중첩될 경우에는 중첩이 깊어질수록 활성화 객체는 함수의 중첩된 깊이만큼 생성된다. 즉, 3번 중첩된 함수에서 가장 안쪽의 함수는 스코프 체인에 3개의 활성화 객체를 갖게 되는 것이다. 스코프 체인의 최상위에는 현재 실행 중인 가장 안쪽에 중첩된 함수의 활성화 객체를 참조하며, 그 뒤로 바깥쪽 방향으로 중첩된 함수의 순서대로 각 함수의 활성화 객체를 참조하게 된다. 그리고 마지막으로 전역 객체를 참조하게 된다.
이 경우가장 안쪽의 함수에서 전역 속성에 접근할 때는 '실행문맥>스코프체인>활성화객체1>스코프체인>활성화객체2>스코프체인>활성화객체3>스코프체인>전역 객체'와 같이 긴 탐색 경로를 거쳐야 한다. 이러한 탐색 경로를 줄임으로써 실행 시간을 단축하고 자바스크립트 성능을 향상시킬 수 있다.
첫 번째로 탐색하는 활성화 객체에 찾고자 하는 속성이 있는 경우 추가로 발생할 수 있는 다른 활성화 객체, 전역 객체를 탐색하는 과정을 줄여 성능을 향상시킬 수 있을 것이다.
01.
// 함수 내에서 전역 스코프 변수에 직접 접근하는 예제
02.
window.htmlstring = [];
03.
04.
function makeList(){
05.
htmlstring.push(
"<ul>"
);
06.
for
(var i=0;i<100;i++){
07.
htmlstring.push(
"<li>value: "
+ i +
"</li>"
);
08.
}
09.
10.
htmlstring.push(
"</ul>"
);
11.
}
12.
13.
makeList();
makeList() 함수가 실행되면 함수 내부에서 htmlstring, i 속성에 접근하기 위해 스코프 체인을 탐색한다. 이때 htmlstring 객체를 찾기 위해 활성화 객체에 먼저 접근해서 탐색하지만 찾지 못하고, 다시 전역 객체를 탐색해서 찾아야 한다. 다음과 같이 코드를 수정해 성능을 높일 수 있다.
01.
// 함수 지역변수로 참조해 전역 스코프 변수에 접근하는 예제
02.
window.htmlstring = [];
03.
04.
function makeList(){
05.
var htmlstr = htmlstring;
06.
htmlstring.push(
"<ul>"
);
07.
for
(var i=0;i<100;i++){
08.
htmlstring.push(
"<li>value: "
+ i +
"</li>"
);
09.
}
10.
11.
htmlstring.push(
"</ul>"
);
12.
}
13.
14.
makeList();
위 코드에서 var htmlstr = htmlstring; 부분이 성능 개선의 핵심이다. 전역객체에 존재하는 htmlstring 속성을 makeList() 함수의 지역변수에 저장해 활성화 객체에서 바로 찾을 수 있게 한 것이다. 물론 var htmlstr = htmlstring; 구문을 실행할 경우 최초 한 번만 '실행문맥>스코프 체인>활성화 객체>스코프 체인>전역 객체'와 같은 탐색경로를 거치지만 그 이후에는 활성화 객체에 저장된 htmlstr 속성으로 전역변수인 htmlstring 객체에 접근할 수 있으므로 활성화객체를 거쳐 전역 객체까지 탐색할 필요가 없어진다.
자바스크립트의 모든 객체의 인스턴스는 new 연산자로 생성할 수 있으며, 생성된 인스턴스 객체는 생성자의 프로토타입(prototype)을 참조하게 된다.
1.
var obj =
new
Object();
//obj - 인스턴스 객체, Object - 생성자 함수
인스턴스 객체가 원본 객체 생성자 함수의 프로토타입 속성을 탐색할 때도 탐색을 위한 체인이 생성되는데, 이를 프로토타입 체인이라 한다.
위 코드에서 Object는 자신의 프로토타입을 참조하며, var obj = new Object(); 구문이 실행되면 obj는 Object의 프로토타입을 상속 받는다. 이 과정에서 탐색 경로가 길어질 수 있으며, 탐색 경로의 거리에 따라 프로토타입 체인에서도 스코프 체인에서와 같은 성능 저하가 발생할 수 있다. 그러므로 프로토 타입에 존재하는 속성을 사용할 때 지역변수에 담아서 사용한다면 불필요한 탐색 과정을 줄여 성능을 높일 수 있다.
with 구문과 try-catch 구문은 스코프 체인 탐색에서의 성능 저하가 발생할 수 있으므로 되도록 사용을 자제한다.
아래는 배열을 초기화하는 코드와 성능 비교를 위한 4개의 반복문을 테스트하는 코드이다.
1.
//배열을 초기화하는 코드
2.
arr = [];
3.
for
(var i=0;i<400;i++){
4.
arr[i] = i;
5.
}
1.
//Code1 - for 구문
2.
for
(var i=0, len=arr.length;i<len;i++){
3.
arr[i]++;
4.
}
1.
//Code2 - for in 구문
2.
for
(var i
in
arr){
3.
arr[i]++;
4.
}
1.
//Code3 - while 구문
2.
var i=0, len = arr.length;
3.
while
(i<len){
4.
arr[i]=i;
5.
i++;
6.
}
1.
//Code4 - do while 구문
2.
var i=0, len = arr.length;
3.
do
{
4.
arr[i]=i;
5.
i++;
6.
}
while
(i<len);
테스트는 다음 주소에서 확인할 수 있다. http://jindo.dev.naver.com/jsMatch/index.html?d=35
결과를 보면 for-in 구문은 IE 이외의 브라우저에서는 두드러질 정도로 성능이 좋지 않다. 빠른 응답시간을 구현하려면 되도록 for-in 구문을 사용하지 않는 것이 좋다.
for-in 구문은 인자로 주어진 배열을 배열이 아닌 일반 객체로 취급하며, 반복시점마다 객체의 모든 속성을 무작위로 탐색하여 현저하게 느려진다.
for-in 구문은 그 목적 자체가 객체의 속성을 탐색하는 것이다. 그런 이유로 모든 속성이 순차적으로 정렬돼 있어 선형적인 색인으로 접근할 수 있는 배열보다는 속성의 이름이 제각각이라 색인으로는 접근할 수 없는 객체의 속성을 탐색하는 데만 사용하길 권장한다.
다음은 배열의 모든 요소를 탐색하는 다양한 형식의 반복문이다.
1.
//for구문을 이용한 배열 탐색
2.
var arr=[...];
3.
for
(var i=0;i<arr.length;i++){
4.
...
5.
}
1.
//while구문을 이용한 배열 탐색
2.
var arr=[...];
3.
var i=0;
4.
while
(i<arr.length){
5.
...
6.
7.
i++;
8.
}
1.
//do while구문을 이용한 배열 탐색
2.
var i=0;
3.
do
{
4.
...
5.
6.
i++;
7.
}
while
(i<arr.length);
HTML 긴 문자열 CSS로 자르기 - text-overflow:clip, ellipsis (0) | 2013.12.23 |
---|---|
웹페이지 로딩속도 빠르게 하기 Image Sprite (0) | 2013.11.19 |
자바스크립트 튜닝을 통한 사용자 체감속도 높이기 (0) | 2013.11.14 |
페이지 빠르게 로딩하는 방법 (0) | 2013.11.12 |
웹페이지 최적화, 브라우저 다이어트, 페이지 로딩 속도 빠르게 하는 방법 PageSpeed (0) | 2013.11.12 |
웹페이지 로딩속도 빠르게 하기 Image Sprite (0) | 2013.11.19 |
---|---|
웹사이트 최적화 (펌) (0) | 2013.11.19 |
페이지 빠르게 로딩하는 방법 (0) | 2013.11.12 |
웹페이지 최적화, 브라우저 다이어트, 페이지 로딩 속도 빠르게 하는 방법 PageSpeed (0) | 2013.11.12 |
CSS에 대한 자세한 설명이 있는 곳 (0) | 2013.11.12 |