자동 리드로우 시스템
Mithril.js는 빠른 렌더링을 위해 가상 DOM diffing 시스템을 구현하며, 애플리케이션 렌더링을 정밀하게 제어할 수 있는 다양한 메커니즘을 제공합니다.
Mithril.js는 일반적으로 데이터 레이어의 변경 사항이 발생할 때마다 DOM을 동기화하는 자동 리드로우 시스템을 사용합니다. 자동 리드로우 시스템은 m.mount
또는 m.route
호출 시 활성화되지만, 앱이 m.render
호출로만 초기화되는 경우에는 비활성화됩니다.
자동 리드로우 시스템은 특정 함수가 완료된 후 백그라운드에서 리렌더링 함수를 트리거하는 방식으로 작동합니다.
이벤트 핸들러 이후
Mithril.js는 Mithril.js 뷰에 정의된 DOM 이벤트 핸들러가 실행된 후 자동으로 리드로우합니다.
var MyComponent = {
view: function () {
return m('div', { onclick: doSomething });
},
};
function doSomething() {
// 이 함수 실행 후 동기적으로 리드로우가 발생합니다.
}
m.mount(document.body, MyComponent);
e.redraw
를 false
로 설정하여 특정 이벤트에 대한 자동 리드로우를 비활성화할 수 있습니다.
var MyComponent = {
view: function () {
return m('div', { onclick: doSomething });
},
};
function doSomething(e) {
e.redraw = false;
// div를 클릭해도 더 이상 리드로우가 트리거되지 않습니다.
}
m.mount(document.body, MyComponent);
m.request 이후
Mithril.js는 m.request
가 완료된 후 자동으로 리드로우합니다.
m.request('/api/v1/users').then(function () {
// 이 함수 실행 후 리드로우가 발생합니다.
});
background
옵션을 true
로 설정하여 특정 요청에 대한 자동 리드로우를 비활성화할 수 있습니다.
m.request('/api/v1/users', { background: true }).then(function () {
// 리렌더링이 발생하지 않습니다.
});
경로 변경 이후
Mithril.js는 m.route.set()
호출 후, 그리고 m.route.Link
를 통해 경로가 변경된 후 자동으로 리드로우합니다.
var RoutedComponent = {
view: function () {
return [
// 경로 변경 후 비동기적으로 리드로우가 발생합니다.
m(m.route.Link, { href: '/' }),
m('div', {
onclick: function () {
m.route.set('/');
},
}),
];
},
};
m.route(document.body, '/', {
'/': RoutedComponent,
});
Mithril.js가 리드로우하지 않는 경우
Mithril.js는 setTimeout
, setInterval
, requestAnimationFrame
, 원시 Promise
의 resolve, 그리고 타사 라이브러리 이벤트 핸들러 (예: Socket.io 콜백) 이후에는 자동으로 리드로우하지 않습니다. 이러한 경우에는 m.redraw()
를 수동으로 호출해야 합니다.
Mithril.js는 또한 컴포넌트의 생명주기 메서드 실행 후에는 리렌더링하지 않습니다. UI의 일부는 oninit
핸들러 이후 리드로우될 수 있지만, 다른 부분은 해당 oninit
핸들러가 실행될 때 이미 리드로우되었을 수도 있습니다. oncreate
및 onupdate
와 같은 핸들러는 UI가 다시 그려진 후에 실행됩니다.
라이프사이클 메서드 내에서 리드로우를 명시적으로 트리거해야 하는 경우 m.redraw()
를 호출해야 하며, 이는 비동기 리드로우를 트리거합니다.
function StableComponent() {
var height = 0;
return {
oncreate: function (vnode) {
height = vnode.dom.offsetHeight;
m.redraw();
},
view: function () {
return m('div', 'This component is ' + height + 'px tall');
},
};
}
Mithril.js는 m.render
를 통해 렌더링되는 vnode 트리를 자동으로 리드로우하지 않습니다. 즉, m.render
를 통해 렌더링된 템플릿에 대한 이벤트 변경 및 m.request
호출 이후에는 리드로우가 발생하지 않습니다. 따라서 아키텍처 상 렌더링 시점을 수동으로 제어해야 하는 경우 (Redux와 같은 라이브러리 사용 시 종종 발생) m.mount
대신 m.render
를 사용해야 합니다.
m.render
는 vnode 트리를 인자로 받고, m.mount
는 컴포넌트를 인자로 받는다는 점을 기억하십시오.
// m.render를 위해 컴포넌트를 m() 호출로 래핑합니다.
m.render(document.body, m(MyComponent));
// m.mount를 위해 컴포넌트를 래핑하지 않습니다.
m.mount(document.body, MyComponent);
Mithril.js는 요청된 리드로우 빈도가 하나의 애니메이션 프레임 (일반적으로 약 16ms)보다 높은 경우 자동 리드로우를 최적화하기 위해 리드로우를 건너뛸 수 있습니다. 즉, 예를 들어 onresize
또는 onscroll
과 같이 빠르게 발생하는 이벤트(fast-firing events)를 사용할 때 Mithril.js는 성능 저하를 방지하기 위해 리드로우 횟수를 자동으로 조절합니다 (throttle).