서론

일반적으로 디스플레이는 1초에 화면을 60번 그린다. 

디스플레이가 1초에 60번 바뀌는데 웹페이지가 1초에 10번 그려진다면, 사용자는 페이지가 느리다고 느낀다. 우리는 이런 현상을 Jank 라고 부른다.

그렇다면 최적화가 필요한데, 웹페이지 렌더링을 최적화 한다는 것은 브라우저가 1초에 60번 렌더링 할 수 있도록 하면 된다.

웹페이지를 회작화 하기 위해 느린 부분을 찾아서 개선해야 한다. 어떤 부분이 느린지를 찾으려면 웹페이지가 화면을 어떻게 그리는지를 알아야 한다.




브라우저 렌더링이란?

사용자로부터 요청받은 내용을 브라우저 화면에 표시하는 일.

주로 크롬, 사파리, 파이어폭스, IE 브라우저가 있는데, 각 브라우저 마다 엔진이 다르므로, 용어나 렌더링 결과가 다르게 보이는 경우가 있다. (일명 브라우저 호환문제 라고 함)

브라우저 렌더링 엔진

Webkit (웹킷)

사피리와 크롬 브라우저가 사용중인 엔진이다. 최초 리눅스 플렛폼에서 동작하기 위해 제작된 오픈소스 엔진인데 애플이 맥과 윈도우에 사파리 브라우저를 지원하기 위해 수정을 가했다. http://webkit.org

Gecko (게코)

파이어폭스 브라우저가 사용중인 엔진 이름이다.


브라우저 렌더링 과정


brouser3



DOM트리는 HTML 구조를 있는 그대로 표현하는 트리라면
렌더트리는 스타일 정보를 더한, 즉 생상 또는 면적과 같은 시각적 속성이 있는 사갈형을 포함하고 있는데, 정해진 순서대로 화면서 표시되는 트리이다.
렌터트리 생성이 끝나면, 배치가 시작되는데 이것은 각 노드가 화면의 정확한 위치에 표시되는 것을 의미한다.


렌더링 엔진은 좀 더 나은 사용자 경험을 위해 가능하면 빠르게 내용을 표시하는데,
모든 HTML을 파싱할 때까지 기다리지 않고 배치와 그리기 과정을 시작한다. 네트워크로부터 나머지 내용이 전송되기를 기다리는 동시에 받은 내용의 일부를 먼저 화면에 표시한다.
brouser9

렌더링 엔진 용어

* layout(웹킷), reflow (게코): 브라우저가 요소를 화면에 배치하는 일.
* attachment(웹킷): 렌더트리를 생성하기위해 DOM 노드와 시각정보를 연결하는 과정.


스크립트와 스타일 시트의 진행 순서

스크립트

웹은 파싱과 실행이 동시에 수행되는 동기화(synchronous) 모델이다. 웹 페이지 제작자는 파서가 <script> 태그를 만나면 즉시 파싱하고 실행하기를 기대한다. HTML4에서는 스크립트가 실행되는 동안 문서의 파싱을 중단된다. 스크립트가 외부에 있는 경우 우선 네트워크로부터 자원을 가져와야 하는데 이 또한 실시간으로 처리되고 자원을 받을 때까지 파싱은 중단된다.
하지만 HTML5는 스크립트를 비동기(asynchronous)로 처리하는 속성을 추가했기 때문에, 웹 페이지 제작자는 스크립트를 "defer"로 표시해서 HTML 파싱을 중단하지 않을 수 있다. 문서 파싱이 완료된 이후에 스크립트가 실행된다 별도의 맥락에 의해 파싱되고 실행된다.

스타일 시트

이론적으로 스타일 시트는 DOM 트리를 변경하지 않기 때문에 문서 파싱을 기다리거나 중단 할 이유가 없다. 그러나 스크립트가 문서를 파싱하는동안 스타일 정보를 요청하는 경우라면 문제가 된다. 스타일이 파싱되지 않은 상태라면 스크립트는 잘못된 결과를 내 놓기 때문에 많은 문제를 야기한다. 

파이어폭스는 아직 로드중이거나 파싱중인 스타일 시트가 있는 경우 모든 스크립트 실행을 중단한다.
웹킷은 로드되지 않은 스타일 시트 가운데 문제가 될만한 속성이 있을 때만 스크립트 실행을 중단한다.



DOM 트리와 렌더 트리의 관계

렌더러는 DOM 요소에 부합하지만 1:1 로 대응하는 관계는 아니다. 예를들어 "head" 요소와 같은 비시각적 DOM 요소는 렌더 트리에 추가되지 않는다. 또한 display: none 도 마찬가지 이다.

brouser13
























window.scrollTo(0, window.innerHeight + this.getEndPositionOfChar().y);
 // 두번째 인자는 offsetLeft 의 값



'WEB > HTML' 카테고리의 다른 글

HTML 페이지에 공백(space) 삽입  (0) 2015.01.01
날짜 animation  (0) 2014.11.03
HTML 태그 총정리  (0) 2012.08.15
HTML 페이지 프레임 나누기  (0) 2012.08.14
HTML에 웹폰트 적용하기  (0) 2012.08.12


JSON(JavaScript Object Notation) 표기법은 

서로 다른 프로그래밍 언어간에 데이터를 교환하기 위한 표기법으로서 읽고 쓰기 쉬운 표기법이다.


사용되는 데이터 형식은 두가지 이다.

  • 이름/값 쌍
  • 배열

이름/값 싸을 표현할 때에는 다음과 같은 표기법을 사용한다.

{이름1:값1, 이름2:값2, 이름3:값3}


예를들어, 국가별 코드와 이름을 표현하고 싶다면 다음과 같이 JSON 표기법을 사용할 수 있다.


var countries = {ko:'대한민국', fr:'프랑스', uk:'영국'};
var koName = countries.ko;
var frName = countries['fr'];



배열로 표기하고 싶다면

[값0, 값1, 값2, 값3]


var countryCodes = ['ko', 'fr', 'uk', 'us']
var idx0 = countryCodes[0];   // 'ko'
var idx2 = countryCodes[2];   // 'uk'



이름/값 형태와 배열 혼함

var number = {
   name:'최범균',
   favoriteColors:['파랑', '노랑', '빨강']
};
var message = member.name + "님이 좋아하는 색상은 " + member.favoriteColors.length + "개 이고," ;
message += "그 중 첫번 째 색상은 " + member.favoriteColors[0] + "입니다.";






자바스크립트에서 eval()은 사악한(evil) 함수이다.


동적인 프로퍼티에 접근할 때에는 대괄호 표기법이 더 간단하고 좋다.


//안티 패턴
var obj = {name:"javascript"};
var property = "name";
alert(eval("obj."+property))
// 권장 패턴
var obj = {name:"javascript"};
var property = "name";
alert(obj[property])






setInterval(), setTimeout(), Function() 인자로 문자열을 넘기는 것도 eval()과 비슷하다.


반드시 eval()을 사용해야 한다면 

  1. new Function()으로 감싸서 사용하자.
    Function() 생성자로 감싸게되면 유효영역이 새로 만들어져 var 선언 변수들이 전역에 선언되는 경우를 막을 수 있다.
  2. eval() 호출을 즉시실행 함수로 감싸서 실행되도록 하자.
console.log(typeof un);    // undefined
console.log(typeof deux);    // undefined
console.log(typeof trois);    // undefined

var jsstring = "var un = 1; console.log(un);";
eval(jsstring);    // "1"

jsstring = "var deux = 2; console.log(deux);";
new Function(jsstring)();    // "2"    // 생성자로 생성한 함수를 바로 호출한다. 
     // 유효범위가 새로 생기므로 deux는 로컬변수가 된다.

jsstring = "var trois = 3; console.log(trois);";
(function() {
   eval(jsstring);
}()); // "3" // eval()을 함수로 감싸고 그 함수를 즉시 호출한다. trois 또한 함수의 로컬변수가 된다.

console.log(typeof un);        // "1"
console.log(typeof deux);   // "undefined"
console.log(typeof trois);    // "undefined"


eval()과 Function()의 또다른 차이


eval()은 자신의 유효범위 다음으로 자신을 감싸는 유효범위를 바라보고 있다.

하지만 Function()은 자신의 유효범위 다음으로 전역 유효범위를 바라보고 있다.

따라서 eval()은 유효범위 체인에 간섭을 일으킬 수 있다.

(function () {
	var local = 1;
	eval("local = 3; console.log(local);");    // 3이 출력된다.
	console.log(local);    // 3이 출력된다. 감싸고있는 함수의 local 변수의 값을 바꿔버린다.
}())

(function () {
	var local = 1;
	Function("console.log(typeof local);")();    // undefined가 출력된다. 
	// Function 객체의 상위 유효범위는 전역.
	// 전역에 local 변수가 없으므로 undefined.
}())

'WEB > javascript' 카테고리의 다른 글

객체 생성자의 함정  (0) 2012.07.22
자바스크립트 리터럴 표기법  (0) 2012.07.22
호이스팅(hoisting): 분산된 var 선언의 문제점  (0) 2012.07.12
자바스크립트 전역변수  (0) 2012.07.10
strict mode  (0) 2012.07.10

http://dmitrysoshnikov.com/ecmascript/es5-chapter-3-1-lexical-environments-common-theory/#more-1751


분석해보고 정리하겠음.



모든 자바스크립트는 실행환경에서 전역 객체(global object)가 존재한다.

변수에 값을 assign 할 경우 var 선언을 하지 않으면 전역 변수로 생성된다.


myglobal = "hello";    // 안티패턴 myglobal : 암묵적 전역 변수
console.log(myglobal);           // "hello"
console.log(window.myglobal);    // "hello"
console.log(window["myglobal"];  // "hello"
console.log(this.myglobal);      // "hello"


실수하기 쉬운 전역변수 선언

function sum(x, y) {
	// 안티 패턴 result : 암묵적 전역
	result = x + y;
	return result;
}

//안티패턴 b : 암묵적 전역 변수
function foo() {
	var a = b = 0;
}


전역변수의 문제점



  • 광고같은 서드파티 스크립트들로인해 중요한 변수가 덮어쓰여지거나 삭제 될 수 있다.


 위의 코드는 엄밀히 말하면 전역 객체에 변수가 아닌 프로퍼티가 result가 추가되는 것이다. (var 선언이 없기 때문)

프로퍼티는 delete 연산자로 삭제 가능하지만 변수는 불가능 하므로 주의해야 한다.


예를들어, 함수내에서 살아있어야 하는 변수를 전역 프로퍼티로 잘못 생성하면 서드파티 코드에서 우연히 삭제할 가능성이 있기 때문이다.







'WEB > javascript' 카테고리의 다른 글

자바스크립트 리터럴 표기법  (0) 2012.07.22
eval() 안전하게 사용하는 방법  (0) 2012.07.22
호이스팅(hoisting): 분산된 var 선언의 문제점  (0) 2012.07.12
strict mode  (0) 2012.07.10
객체지향 언어  (0) 2012.07.09


ECMAScript 5에 추가된 기능.


실제로 기능을 추가한 것이 아니라 제거함으로써 프로그램을 더 간단하게 만들고 오류 발생 가능성을 낮춘것.

예를들어 with를 스트릭트 모드에서 쓰면 에러가 발생한다.

function my() {
	'use strict'
	with(o) {    // error
	}
}


'use strict'  유효범위는 함수, 전역, 또는 eval()로 전달된 문자열.


ES는 추후에 스트릭트 모드만 지원하려고 계획중이다.

따라서 ES5는 개발자에게 strict mode에서 동작하는 코드를 작성하도록 권장하는 과도적인 버전.

+ Recent posts