renderPage(path: string) { let route; const regex = /\w{1,}$/;
if (this.hasRoute(path)) { route = this.getRoute(path); // 경로가 존재할경우 } elseif (regex.test(path)) { route = this.getRoute(path.replace(regex, ":id")); // 경로가 존재하지 않을 경우 동적 라우팅(id) } else { route = this.getRoute(this.fallback); // 그 외의 주소에 대해서는 fallback 실행 } new route(this.$app, {}); // route 객체의 인스턴스를 만듬 }
Context API를 이용하면 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있다.
한계
다시 렌더링 할지 여부를 정할 때 참조를 확인하기 때문에 Provider의 부모가 렌더링 될 때마다 불필요하게 하위 컴포넌트가 다시 렌더링되는 문제가 발생할 수 있다. 예를 들어 아래의 코드는 value가 바뀔 때 마다 매번 새로운 객체가 생성되므로 Provider가 렌더링 될 때마다 하위에서 구독하고 있는 컴포넌트 모두가 렌더링 된다.
js에서 요청/호출되는 일부 속성은 브라우저가 스타일과 레이아웃을 동기적으로 계산하도록 한다.
layout trashing
웹 브라우저는 레이아웃 변경을 즉시 처리하지 않고 비슷한 Style의 수정을 모아서 하게 된다. 즉 화면에서 레이아웃에 대한 정보를 실제로 알아야 할 때까지 레이아웃 계산을 지연시킨다.
layout trashing이 발생하는 경우
DOM이 변경되지 않았음을 보장할 수 있는 경우엔 레이아웃 캐시(이전 계산된 값)에서 값을 가져온다.
하지만 offsetHeight과 같은 최신으로 동기화된 레이아웃에 대한 정보에 접근하는 속성같은 경우 강제로 레이아웃 계산(리플로우)를 발생시켜 동기화 후 값을 가져오게 된다. 즉 아래와 같이 코드를 작성하게 되면 불필요한 레이아웃 계산을 과정이 요구된다.
1 2 3 4
elementA.className = "a-style"; var heightA = elementA.offsetHeight; // layout is needed elementB.className = "b-style"; // invalidates the layout var heightB = elementB.offsetHeight; // layout is needed again
layout trashing이 발생하지 않는 경우
위 코드는 다음과 같이 수정할 수 있다.
1 2 3 4
elementA.className = "a-style"; elementB.className = "b-style"; var heightA = elementA.offsetHeight; // layout is needed and calculated var heightB = elementB.offsetHeight; // layout is up-to-date (no work)
똑같은 작업을 하는 코드지만 위의 코드에 비해 레이아웃 계산의 수가 줄어들게 된다. 레이아웃 계산을 강제로 발생시키는 속성은 여기에서 확인할 수 있다.
연속된 layout trashing 최적화하기
paragraph의 너비를 box의 너비와 같도록 하는 코드를 작성한다고 생각해보자
1 2 3 4 5 6
functionresizeAllParagraphsToMatchBlockWidth() { // Puts the browser into a read-write-read-write cycle. for (var i = 0; i < paragraphs.length; i++) { paragraphs[i].style.width = box.offsetWidth + "px"; } }
위와같이 작성한다면 box의 offsetWidth에 접근한 뒤 paragraphs[i]의 너비로 설정하게 된다.
offsetWidth 속성에 접근할 때마다 강제로 레이아웃 계산을 시도하게 되므로 단일 paragraph마다 layout 계산이 일어나게 된다.
이는 다음과 같이 수정할 수 있다.
1 2 3 4 5 6 7
functionresizeAllParagraphsToMatchBlockWidth() { let width = box.offsetWidth; for (var i = 0; i < paragraphs.length; i++) { // Now write. paragraphs[i].style.width = width + "px"; } }
reflow를 강제로 발생시켜 애니메이션 실행하기
브라우저는 비슷한 style변화를 모아서 반영하기 때문에 원하는대로 애니메이션이 작동하지 않을 때가 있다. 이럴 때는 강제로 reflow를 발생시켜 해결할 수 있다.