일반
변수명
영문으로 시작하는 변수명을 사용하십시오.
$r_title(비권장 사용 예) <w2:anchor class="todolist_refresh" id="1" outerDiv="true">
$r_title(권장 사용 예) <w2:anchor class="todolist_refresh" id="anchor01" outerDiv="true"> // 혹은 id 삭제 가능 <w2:anchor class="todolist_refresh" outerDiv="true">
객체 제어
JavaScript는 느슨한 타입(loosely typed) 언어, 혹은 동적(dynamic) 언어입니다. 즉, 변수 타입을 미리 선언할 필요가 없고 프로그램이 처리되는 과정에서 자동으로 파악 변환되기도 합니다. 공통함수가 객체 타입에 따른 대응을 못하고 에러가 발생하는 경우 스크립트가 중지되고 브라우저에 따라 성능 및 메모리에 영향을 받습니다.
$r_title(비권장 사용 예) scwin.addDateSimpleisDate = function(sDate) { try { var date = “”; var isDate = scwin.isDate(pYmd); //8자리 이상의 string여부 체크 if (!isDate) return; cYmd = pYmd.substring(0, 8); var dTime = (pYmd+””).substring(8); var isSet = Number(offset); //isDate에서 숫자인지 체크하지는 않음 if (isDate && typeof isSet == “number”) date = $p.dateAdd(cYmd, isSet); if (typeof format != “undefined” && format == “yyyyMMdd”) { date = date; } else { date = date + “” + dTime; } return date; } catch (e) { } }
$r_title(권장 사용 예) scwin.addDateSimpleisDate = function(sDate) { try { var date = ""; var isDate = scwin.isDate(pYmd); if (!isDate) return; var cYmd = pYmd.substring(0, 8); var dTime = pYmd.substring(8); var isSet = Number(offset); if (!isNaN(isSet)) date = $p.dateAdd(cYmd, isSet); // Number 변환시 NaN가 아닌 경우 dateAdd 수행 if (typeof format == “undefined” || format != “yyyyMMdd”) date = date + dTime; return date } catch (e) { } }
전역 변수 선언
JavasSript는 느슨한 타입(loosely typed) 언어로 변수 선언을 위해 사용하는 var 문자를 누락해도 스크립트는 정상적 수행됩니다. 단, 이 경우 해당 변수는 전역에 선언되어, 함수 종료 후에도 계속 참조가 가능하고 자동 릴리즈가 되지 않습니다. SPA 방식으로 이동하는 화면인 경우 이는 메모리 누수 현상으로 이어집니다.
$r_title(비권장 사용 예) scwin.getDay = function(pYmd, format) { try { if (pYmd.length > 8) { pYmd = pYmd.substring(0, 8); } if (typeof format !== "undefined" && format !== "" && WebSquare.util.getBoolean(format)) { date = WebSquare.date.getDay(pYmd); //date가 var 선언이 생략되어 있어 전역변수로 사용됨 } else { // … } return date; } catch (e) { } }
$r_title(권장 사용 예) scwin.getDay = function(pYmd, format) { try { var date = -1; //var를 생략하지 않고 // date가 가질 수 없는 값을 초기값으로 설정한뒤 // case에 따른 수식결과를 저장한뒤 리턴한다. if (pYmd.length > 8) { pYmd = pYmd.substring(0, 8); } if (typeof format !== "undefined" && format !== "" && WebSquare.util.getBoolean(format)) { date = WebSquare.date.getDay(pYmd); } else { // … } return date; } catch (e) { } }
동기 요청 최소화
대부분의 프로젝트에서는 현재 시간 (서버 시간), 사용자 정보, 또는 사용자 권한을 조회하기 위해 동기 요청을 사용합니다. 한 화면에서 동기 요청을 여러 번 호출하는 것은 성능 저하로 이어질 수 있습니다.
하나의 요청으로 처리 가능한 함수를 구현하십시오.
최상위 scope에 함수 및 변수 선언 제한
WebSquare에서는 업무 화면에서 함수 또는 상수 값 선언 시 객체의 속성으로 설정하여 사용할 것을 권장합니다.
화면 unload 시점에 선언된 객체의 속성으로 등록된 함수 및 상수를 제거하여 메모리 누수를 방지하십시오.
업무화면 내에서 사용하는 전역 변수 또한 지정된 객체의 속성으로 등록해서 사용하십시오.
$r_title(비권장 사용 예제) var GlobalValue = 1; function doInit() { //Something }
$r_title(권장 사용 예제) scvar.GlobalValue = 1; scwin.doInit = function() { //Something }
금지 사항
웹스퀘어를 통한 웹 표준 개발 시, 아래 내용을 준수하십시오.
브라우저 객체(DOM)를 직접 제어하는 모든 API의 사용을 금지합니다.
예를 들어 웹스퀘어에서 제공된 컴포넌트로 그려진 객체(DOM)에 대해 getElementById(); 혹은createElement(); 함수를 사용하지 마십시오.
document.write 와 같은 함수를 사용하지 마십시오.
브라우저 Event의 직접 제어를 금지합니다.
XMLHttpRequest를 직접 생성하고 조작하는 API는 사용하지 마십시오.
웹스퀘어가 제공하는 Submission을 이용하십시오. API를 이용할 경우, WebSquare.ModelUtil.executeSubmission();을 사용하십시오.
prototype.js나 jquery.js와 같은 오픈소스 JavaScript Framework를 동시에 사용할 수 없습니다.
prototype 확장은 금지합니다.
프로그램 구현을 위해 아래 내용이 꼭 필요한 경우, 웹스퀘어 지원 인력과 먼저 확인하십시오.
메모리
최상의 메모리 및 성능을 위해 아래 내용을 확인하십시오.
번호 | 확인 사항 | 설명 |
---|---|---|
1 | Window 팝업을 alert이나 iframe형태의 팝업으로 처리했는가? | 2단 팝업 등에서 메모리 미반환 현상 발생. |
2 | 통신 관련 공통 함수가 객체 대신 string을 사용했는가? | callback 함수에 객체 형태로 전달하면 메모리 누수가 발생. 예) IE8 브라우저 다운현상이 발생할 수 있음. |
3 | 팝업으로 인자 전달 시에 객체 대신 string 을 사용했는가? | 객체 형태로 전달시 메모리 누수 발생. |
4 | 웹 폰트 사용시 부모 페이지 외의 자식 페이지에서 중복 호출되지는 않는가? | 중복 호출 시 IE8 등에서 백화현상 또는 웹 폰트 미적용 현상 발생. |
5 | 외부 모듈 연계시 document mode(DocType)의 지원 범위가 표준을 준수하는가? | 외부모듈 지원 시 DocType이 비표준 모드인 경우 브라우저 하위버전으로 설정되어 렌더링 속도의 영향을 미침. |
6 | 외부 모듈 연계 시 해당 외부 모듈의 메모리 누수 여부를 확인했는가? | 브라우저 전체 메모리에 영향을 미침. |
7 | 외부 모듈(bootstrap 사용시)의 버전 별 메모리 해제 여부를 확인했는가? | bootstrap-2.1.1.min.js 해당버전이 메모리 해제가 되지 않는 문제 발생. |
8 | SSL 환경에서 멀티업로드(플래시 모드)를 사용하는가? | 업로드 성능이 저하되는 현상이 발견. html5_transparent 모드를 권장. (IE 10 이상만 사용 가능) |
9 | 대용량 엑셀 다운로드가 있는가? | Client 환경에서 Data를 수집하고 Server로 보내는 경우 시간이 오래 소요될 수 있음. 권장: Server에서 Data를 직접 처리하도록 Provider를 사용할 것을 권장. |
10
IE8을 지원해야 하는 프로젝트에서 웹 폰트를 사용하는가?
IE8의 경우 웹 폰트를 내려 받기 위한 브라우저 처리 속도가 현저하게 느리기 때문에 웹 폰트 사용을 권장하지 않음.
예) ie8 + iframe + 웹 폰트 사용시 백화 현상이 발생할 수 있음.
11
캐시가 적절히 사용되고 있는지 확인했는가?
(웹스퀘어 환경설정, 웹 서버 만료일 설정, 브라우저의 캐시 설정 등)
웹스퀘어 config.xml 내의 캐시 관련 설정(웹서버 만료일, 브라우저 캐시 설정 등 관련)이 웹페이지 속도에 큰 영향을 미침.
12
DataCollection의 Data를 처리하기 위한 API들이 효율적으로 사용되었는가?
Data 처리를 비효율적으로 API를 반복하여 사용하는 경우 성능 저하 발생.
예) 1개의 Row를 변경하기 위해 setRowJson을 사용하지 않고 각 셀에 대해 setCellData를 반복적으로 사용.
13
대량 Data 처리시 Data 구조체를 적절하게 사용했는가?
array > json > xml 순으로 속도 처리가 빠름.
14
Fasoo DRM 모듈을 사용하는가?
Fasoo DRM Client for LIG NoNX Wix, FSW Client 류의 제품들이 메모리 사용시 팝업을 열고 닫을 때 메모리 사용량이 증가할 수 있음.
15
그리드의 Cell 별로 다양한 서식을 적용하는 사례가 있는가?
GridView의 formatter 및 setCellColor, setCellBackgroundColor 등이 붙을 수록 화면 렌더링 속도 및 스크롤 속도가 느려질 수 있음.
권장:
서버에서 서식을 처리하여 내려주도록 권장.
16
TabControl 사용 시 다수의 탭을 사용하는가?
다수의 탭 중 닫혀진 탭 내부 컨텐츠를 렌더링 하는 방법이 alwaysDraw="true"인 경우, 최초 로딩 시 다수의 탭이 있을수록 화면 로딩 속도가 저하.
권장:
alwaysDraw="false"를 사용하여 탭이 선택될 때 로딩하는 방식 권장.
17
TabControl 내부 Content 항목의 화면 구성 시 별도의 xml 파일 연결을 확인했는가?
TabControl 내부 Content 항목이 iframe을 포함하여 iframe이 중복으로 사용되는 현상 발생.
권장:
TabControl 내의 content 속성 중 src 에서 별도 xml 파일을 선택하도록 해야함.
18
JavasScript 함수 작성 시 지역변수를 적절하게 사용했는가?
함수 내에서 변수 선언시 var 선언을 생략하면 전역변수로 생성되어 메모리 과다 점유 현상 발생.
19
전체 Layout 화면 구성 시 iframe 개수가 지나치게 많이 사용되지는 않았는가?
iframe 사용개수가 많아질수록 화면 렌더링 속도 저하 및 메모리 과다 점유 현상 발생.
권장:
가능한 iframe을 wframe로 변환해서 처리할 수 있도록 권장
20
sync 및 async 통신 방식이 적절히 사용되었는가?
Sync 방식은 완료시까지 스크립트 정지 현상이 발생하므로 async 방식을 권장.
21
MDI(WindowContainer) 사용시 화면 중복 오픈 금지 및 오픈 창 개수 제한이 있는가?
MDI 개별 Window가 지나치게 많아지게 될 경우 메모리 과다로 인해 화면 조작이 불가.
22
JavasScript 로직 내의 오류가 발생하는가?
JS 내 오류 발생시 화면 렌더링 속도 저하.
23
xml 파일 내의 업무 로직 처리를 위한 JavasScript 분량이 적절한가?
하나의 xml 파일 내의 JavasScript 양이 많을 경우 렌더링 속도 저하.
권장:
공통으로 사용되는 함수 등은 xml 파일 별로 넣지 않고 별도의 .js 파일로 분리하여 관리.
24
(갤럭시노트3, 갤럭시탭10.1과 같은) 특정 모바일 장비를 사용하는가?
해당 장비에서는 자체 xml parser가 내장되어 있지 않음
config.xml에서 <userAgentPattern XPathParser="Android 4.3[\w\W]+N900|Android 4.3[\w\W]+E300|Android 4.4"/>을 추가.
/websquare/externalJS/xpath/xpath.js를 로딩하여 사용 시 성능저하 발생.
권장:
근본적인 처리 방안 없음으로 가급적 해당 기기를 사용하지 않을 것.
25
jQuery 1.7.2를 사용하는가?
해당 버전 사용시 메모리 누수 발생.
26
통신 객체의 동적 생성시 중복 문제는 없는가?
동일한 id로 중복하여 생성할 경우 누수 발생.
27
데이터 객체의 동적 생성시 중복 문제는 없는가?
동일한 id로
중복하여 생성할 경우 누수 발생.
28
통신 함수의 응답 객체 사용에 문제가 없는가?
통신 함수에서 사용자 함수 호출 시 응답 결과가 다른 곳과 참조 관계가 없는지 확인.
29
컴포넌트 및 함수의 네이밍은 문제가 없는가?
가이드된 네이밍 규칙을 준수하는지 확인.
30
팝업(프레임)간 Object를 전달하고 있는가?
타 프레임에 Primitives형(예: String)이 아닌 Object를 직접전달하고 있는지 확인.
31
스크립트 오류가 발생하지 않는가?
스크립트 수행이 중지되어 함수가 정상적으로 종료되지 않는 경우가 있는지 확인.
32
웹폰트 사용시 부모 페이지외의 자식 페이지에서 중복 호출되는가?
중복 호출 시 IE8 등에서 백화 현상 또는 웹 폰트 미적용 현상 발생.
33
외부 모듈 연계시 document mode(DocType)의 지원 범위가 표준을 준수하는가?
외부 모듈 지원 시 DocType이 비표준 모드인 경우 브라우저 하위 버전으로 설정되어 렌더링 속도의 영향을 미침.
34
외부 모듈 연계 시 해당 외부 모듈의 메모리 누수 여부를 확인했는가?
특히 SPA기능 사용 시 외부 모듈 추가 로드 또는 사용 완료 시에 메모리에 사용에 문제가 없는지 확인.
35
캐시가 적절히 사용되고 있는지 확인했는가?
개발/운영 환경에 따라 웹스퀘어 config.xml 내의 캐시 관련 설정이 적용되어 있는지와 서버 설정을 확인.
(예) 웹스퀘어 환경설정, 웹 서버 만료일 설정, 브라우저의 캐시 설정 등
36
그리드의 Cell 별로 다양한 서식을 적용하는 사례가 있는가?
한 Row에 셀표현 방식 변경을 위해 formatter류가 많이 사용된 경우 랜더링 속도에 영향을 줄 수 있으므로 Row가 많은 경우는 Server에서 서식을 적용하는 것을 권장.
37
JavasScript 함수 작성 시 지역변수를 적절하게 사용했는가?
var 누락 또는 가이드에 따라 변수/함수가 지정되어 있는지 확인.
모바일
여러가지 해상도 대응은 viewport나 css3의 @media를 사용
모바일 기기의 해상도가 다양하므로 @media속성을 이용해 최적화된 css를 구성하여 각 기기에 맞는 화면을 구성하십시오.
.dynamicScreen { font-family: Arial, Helvetica, sans-serif; height: 250px; color: black; } @media all and (max-width: 320px) { /* 아이폰/아이팟터치/안드로이드의 초기 스크린 해상도 설정 */ .dynamicScreen {background-color: orange;width:320px; } } @media all and (max-width: 768px) { /* 아이패드의 초기 해상도 설정 */ .dynamicScreen {background-color: blue;} } @media all and (min-width: 769px) { /* 아이패드보다 큰 스크린 사이즈와 해상도를 갖는 모든 기기에서의 해상도 설정*/ .dynamicScreen {background-color: green;} }
meta태그의 viewport를 이용해서 기기의 최대가로크기를 정하거나 줌레벨, 사용자 확대축소 방지 여부 등을 설정할 수 있습니다. meta 태그는 websquare.html(jsp)에 넣어야 합니다.
<meta name=”viewport” content=”width=device-width”/> <meta name=”viewport” content=”initial-sacle=1,user-scalable=no”/>
마우스나 키보드 사용을 전제하지 말 것
각종 모바일 기기에 따라 키보드나 마우스 같은 장치 유무가 다르기 때문에 마우스나 키보드 사용을 전제하지 마십시오.
스크롤 사용시 주의 사항
모바일에서 body를 제외하고, overflow:hidden으로 사용하는 것을 권장합니다. 스크롤이 필요한 경우 scrollView 컴포넌트를 사용하여 스크롤을 사용할 수 있습니다.
이벤트 사용시 주의
스마트 폰들은 기본적으로 터치 기반입니다. 더블-클릭 등의 이벤트를 사용하지 마십시오. 마우스 이벤트의 경우 기기마다 다르게 동작할 수 있습니다.
파일 첨부 제한
iPhone의 경우 보안을 위해 허용된 디렉터리의 파일만 첨부 가능합니다.
플러그인 기술 사용금지
기기에 따라 flash나 silverlight 등의 플러그인 사용이 제한됩니다.
모바일 화면 구성 시 iframe 사용 금지
기기에 따라 IFrame으로 화면을 구성 하게 되면, focus, blur 관련 동작이 일반 브라우저와 다르게 동작합니다. 경우에 따라 Input 간 포커싱이 정상적으로 동작하지 않을 수 있습니다.
팝업 사용시 주의 사항
모바일의 경우 팝업을 권장하지 않습니다. 팝업은 새 창(window.open)으로 생성되어 화면 전환이 이루어집니다. 대신 레이어 형태어 팝업 및 링크를 사용하십시오.
사용 금지 컴포넌트
ifame
xsl
ckEditor
chart(iphone에서만 동작함)
upload
muliupload
flash
applet
active
multiselect
slideHide
tabContainer
windowContainer
네트워크
확인된 가장 일반적인 문제는 큐에 저장되거나 지연된 일련의 항목으로 이런 현상이 나타나면 단일 클라이언트에서 너무 많은 리소스를 가져오고 있다는 의미입니다.
HTTP 1.0/1.1 연결의 경우, Chrome은 호스트당 최대 6개의 TCP 연결을 적용합니다. 한번에 12개의 항목을 요청하는 경우, 첫 6개부터 먼저 시작되고 나머지 절반은 큐에 저장됩니다.
첫 절반 중 하나가 완료되면 큐에 대개중인 첫 번째 항목이 요청 프로세스를 시작합니다.
느린 TTFB
느린 TTFB는 긴 대기 시간 즉 녹색이 많이 나타나는 경우입니다. 이 시간은 200ms 미만이 좋습니다. 이 시간이 길다면, 그 원인은 아래와 같습니다.
클라이언트와 서버 사이의 네트워크 상태가 잘못된 경우
서버 애플리케이션의 응답이 느린 경우
처리 용량 확보
네트워크 문제 해결
해결 방안 | 설명 |
---|---|
네트워크 요청 횟수 튜닝 |
|
브라우저 기본 폰트 사용 |
|
시스템 사용을 위한 외부 프레임워크 연계 |
|
단일 frame 사용 |
|
기타
$p.ajax
응답 객체의 직접 할당 금지
WebSquare는 Submission을 이용한 통신을 권장합니다. 그러나 사용자가 직접 통신 관련 설정을 해야하는 경우를 위해 $p.ajax API를 제공합니다.
아래 예제의 경우, 사용자가 직접 제어할 수 있도록 응답 결과 객체를 반환하고 있습니다. 그러나 업무 화면의 콜백 함수로 그대로 넘기기 때문에 업무 화면에서 변수 등에 직접 할당할 경우 통신 완료 후 응답 객체가 메모리에서 릴리즈되지 않을 수 있습니다.
$r_title(비권장 사용 예) $p.ajax({ action : action, mode : mode, mediatype : mediatype, method : method, processMsg : processMsg, requestData : reqData, requestHeader : requestHeader, beforeAjax : function(e) { }, success : function(e) { var resBody = e.responseBody; if (callbackFnc != '') { eval(callbackFnc + '(resBody)'); } }, error : function(e) { return _requestErrCallback(e); } });
$r_title(권장 사용 예) $p.ajax({ action : action, mode : mode, mediatype : mediatype, method : method, processMsg : processMsg, requestData : reqData, requestHeader : requestHeader, beforeAjax : function(e) { }, success : function(e) { if (callbackFnc != '') { window[callbackFnc](JSON.parse(e.responseText)); } }, error : function(e) { return _requestErrCallback(e); } });
Closure 내부에서 객체 참조
Closure는 전역이 아닌 지역 변수 선언이 가능하여 공통 모듈에서 많이 사용합니다. 단, Closure 안에서 Object 형태의 외부 객체를 직접 참조하지 않도록 주의하십시오. 메모리에서 릴리즈 되지 않을 수 있습니다.
특히 Closure 함수를 비동기 형태로 호출할 경우, 객체를 직접 다른 변수에 할당하면 참조 관계가 발생합니다. 이 경우, 함수 실행이 완료되더라도 메모리에서 제거되지 않을 수 있습니다.
아래 예제에서 test2는 test와 직접 참조 관계가 이루어져 test 값 변경에 따라 test2 값이 변경됩니다. 즉 test2와 참조 관계가 발생하여 test 사용이 끝난 뒤에도 메모리에서 제거되지 않습니다.
$r_title(직접 참조 관계 예) //CASE1 var test = {a: "abc", b: "bbc"}; scwin.functionTest = function(value) { scwin.test2 = value; console.log(value); // 결과 : {a: "abc", b: "bbc"} console.log(scwin.test2); // 결과 : {a: "abc", b: "bbc"} for (var item in value) { value[item] = null; } console.log(value); // 결과 : {a: null, b: null} console.log(scwin.test2); // 결과 : {a: null, b: null} }; scwin.functionTest(test); console.log(test); // 결과 : {a: null, b: null} //CASE2 var test = {a: "abc", b: "bbc"}; scwin.functionTest = function(value) { scwin.test2 = value; console.log(value); // 결과 : {a: "abc", b: "bbc"} console.log(scwin.test2); // 결과 : {a: "abc", b: "bbc"} }; scwin.functionTest(test); for (var item in test) { test[item] = null; } console.log(test); // 결과 : {a: null, b: null} console.log(scwin.test2); // 결과 : {a: null, b: null}
$r_title(비권장 사용 예) $p.ajax({ // ... success : function(e) { resBody = e.responseBody; if (callbackFnc != '') { eval(callbackFnc + '(resBody, reqAjaxOptions)'); } } }); } scwin.callback1 = function(resBody, reqAjaxOptions) { if (reqAjaxOptions.mode) { // ... } scwin.orgResData = resBody; }
$r_title(권장 사용 예) $p.ajax({ //... success : function(e) { resBody = e.responseBody; if (callbackFnc != '') { eval(callbackFnc + '(resBody, reqAjaxOptions)'); for(var item in resBody){ resBody[item] = null; } for(var item in reqAjaxOptions){ reqAjaxOptions[item] = null; } } } }); } scwin.callback1 = function(resBody, reqAjaxOptions) { if (reqAjaxOptions.mode) { // ... } scwin.orgResData = JSON.parse(JSON.stringify(resBody)); }
LinkedDataList
LinkedDataList는 DataList 데이터를 필터링하여 아래와 같은 컴포넌트의 선택 항목으로 표시할 때 주로 사용하십시오.
AutoComplete
CheckBox
CheckComboBox
MultiSelect
Radio
SelectBox
권장 사용법
DataList의 데이터는 1,000 건 이하를 권장하며 최대 10,000건까지 지원합니다.
LinkedDataList는 GridView와 직접 바인딩하는 것을 권장하지 않습니다.
$r_title(비권장)
<xf:model>
<w2:dataCollection baseNode="map">
...
<w2:linkedDataList bind="dataList1" id="linkedDataList1">
<w2:condition type="filter"><![CDATA[]]></w2:condition>
<w2:condition type="sort"><![CDATA[]]></w2:condition>
</w2:linkedDataList>
...
<w2:gridView scrollByColumn="false" defaultCellHeight="20"
scrollByColumnAdaptive="false" dataList="data:linkedDataList1">
...
</w2:gridView>
$r_title(권장)
<w2:dataList baseNode="list" repeatNode="map" id="dataList1"
saveRemovedData="true">
<w2:columnInfo>
<w2:column id="col1" name="name1" dataType="text"></w2:column>
<w2:column id="col2" name="name2" dataType="text"></w2:column>
</w2:columnInfo>
</w2:dataList>
...
<w2:gridView scrollByColumn="false" defaultCellHeight="20"
scrollByColumnAdaptive="false" dataList="data:dataList1">
...
</w2:gridView>
GridView
조회 건 수
GridView 조회시 허용 가능한 메모리의 크기는 임계치의 50%내로 사용하는 것을 권장. 그리드의 조회 건수는 약 400,000 Cell을 기준으로 제한하는 것을 권장
visibleRowNum
visibleRowNum 속성을 통해 페이지 당 표시할 행을 지정할 수 있습니다. 단, 최적의 성능을 위해 50행 이하를 권장합니다.
팝업
팝업 종류
아래와 같이 세 가지 종류의 팝업을 생성할 수 있습니다. 단, type을 wframePopup으로 설정한 WFrame 팝업을 대부분의 경우 권장합니다.
옵션 | 설명 | 비고 |
---|---|---|
|
|
|
iframePopup |
|
|
browserPopup |
|
|
동영상
세 종류(WFrame, IFrame, Browser)의 팝업 생성
파라미터 전달
다른 Frame의 함수 호출 시 String 타입의 객체 형태로 파라미터를 전달하십시오. String 타입이 아닌 JSON 객체 등을 직접 전달하여 다른 Frame의 객체에 할당할 경우 일부 브라우저에서 메모리 누수 현상이 발생합니다.
다른 Frame간 전달되는 Object의 타입은 팝업 형식의 호출에만 국한된 것이 아니고 IFrame으로 구성된 화면에도 적용됩니다. Frame 간의 파라미터 전달 방식은 String 타입의 객체를 파라미터로 전달하십시오.
$r_title(비권장 사용 예) //Child comf.onPopupClose = function(retValue) { //... comf.onPopupClose(retValue); } comf.onPopupClose = function(retValue) { opener.comf._onPopupClose(retValue); } //Parent comf._onPopupClose = function(retValue) { scwin.callUserCallback(retValue); }
$r_title(권장 사용 예) //Child scwin.onPopupClose = function() { // ... comf.onPopupClose(retValue); } comf.onPopupClose = function(retValue) { var str = JSON.stringify(retValue); opener.comf._onPopupClose(str); } //Parent comf._onPopupClose = function(str) { var retValue = JSON.parse(str); scwin.callUserCallback(retValue); }
TabControl
TabControl 컴포넌트는 frameMode 속성값으로 iframe과 wframe을 제공하며, 해당 속성값에 따라 컨텐츠를 렌더링합니다. 단, iframe 을 설정할 경우 탭 수에 비례하여 브라우저의 메모리 점유가 증가합니다. 따라서 메인 층에서 사용하는 경우에만 속성값을 iframe으로 지정하길 권장합니다. src 속성은 컨텐츠에 웹스퀘어5 컴포넌트를 직접 구성하지 않고 content 영역을 XML 파일을 불러 렌더링합니다.
다음은 잘못 사용한 코드 예입니다.
$r_title(잘못된 frameMode 설정 (예)) <w2:tabControl confirmTrueAction="exist" useTabKeyOnly="true" id="tabControl1" useConfirmMessage="false" confirmFalseAction="new" alwaysDraw="false"> <w2:tabs id="tabs1" style="width:70px;height:30px" label="" disabled="false"></w2:tabs> <w2:tabs id="tabs2" style="width:70px;height:30px" label="" disabled="false"></w2:tabs> <w2:tabs id="tabs3" style="width:70px;height:30px" label="" disabled="false"></w2:tabs> <w2:tabs id="tabs4" style="width:70px;height:30px" label="" disabled="false"></w2:tabs> <!-- 올바른 예 --> <w2:content id="content1" alwaysDraw="false" frameMode="wframe" src="/tabChild_001.xml"></w2:content> <!-- 잘못된 예. 브라우저 리소스를 많이 사용하게 될 iframe 를 사용 --> <w2:content id="content2" alwaysDraw="false" frameMode="iframe" src="/tabChild_002.xml"></w2:content> <!-- 잘못된 예. frameMode를 사용하지 않음. wframe 를 사용하여 해당 컴포넌트에 src 사용. --> <w2:content id="content3" alwaysDraw="false"> <w2:wframe src="/tabChild_003.xml"></w2:wframe> </w2:content> <!-- 잘못된 예. frameMode 를 사용하지 않음. iframe 를 사용 해당 컴포넌트에 src 사용. --> <w2:content id="content4" alwaysDraw="false"> <w2:iframe id="" src="/tabChild_004.xml" spa="false"></w2:iframe> </w2:content> </w2:tabControl>
WFrame
WFrame 사용 권장
IFrame 수가 지나치게 많은 경우 메모리 점유율이 올라갑니다. IFrame 대신 WFrame을 사용을 권장합니다.
class selector 사용
WFrame을 사용하여 화면을 구성할 경우, 각 화면 내 컴포넌트의 ID는 항상 변합니다. 즉, input1 객체는 연결되는 WFrame에 따라 wframe1_input1이 될 수도 있고 wframe2_wframe22_input1이 될 수도 있습니다. 따라서 id selector 대신 class selector 사용을 권장합니다.
$r_title(사용 예) // class 사용 (권장) <xf:group id="group1" class="contentZ1"/> .contentZ1 { } // id 사용 (비권장) <xf:group id="group1"/> #group1 { }
class명 중복 주의
class selector를 사용할 경우 부모 화면에 정의된 스타일 이름과 겹치지 않도록 주의하십시오. 이름이 겹칠 경우 부모 화면의 class를 덮어 쓰게 되어 부모 화면의 스타일이 변경됩니다.
class명이 겹치지 않도록 화면 ID를 class명 뒤에 붙이는 방법을 권장합니다.