jQuery UI 탭 패널을 위해 필요한 HTML 코드
<div id="tabs">
<ul>
<li><a href="#fragment-1">One</a></li>
<li><a href="#fragment-2">Two</a></li>
<li><a href="#fragment-3">Three</a></li>
</ul>
<div id="fragment-1">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-2">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-3">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
</div>
웹은 이
많은 컴
조합입
HTML
태그는 충분한가요?
웹은 이
많은 컴
조합입
HTMLjQuery UI 탭 패널을 만들 때 필요한 HTML 코드
<div id="tabs">
<ul>
<li><a href="#fragment-1">One</a></li>
<li><a href="#fragment-2">Two</a></li>
<li><a href="#fragment-3">Three</a></li>
</ul>
<div id="fragment-1">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-2">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-3">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
</div>
웹은 이
많은 컴
조합입
HTML
<div id="tabs">
<ul>
<li><a href="#fragment-1">One</a></li>
<li><a href="#fragment-2">Two</a></li>
<li><a href="#fragment-3">Three</a></li>
</ul>
<div id="fragment-1">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-2">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-3">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
</div>
<li><
ListItem이지만 사실은 탭
<div
Division이지만 사실은 탭 패널
의미가 맞지 않는 태그를 컴포넌트로 사용심지어 기능을 정의/사용하는 코드(JS)는 별도 파일에 작성
웹은 이
많은 컴
조합입
HTML
<div id="tabs">
<ul>
<li><a href="#fragment-1">One</a></li>
<li><a href="#fragment-2">Two</a></li>
<li><a href="#fragment-3">Three</a></li>
</ul>
<div id="fragment-1">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-2">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-3">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
</div>
<li><
ListItem이지만 사실은 탭
<div
Division이지만 사실은 탭 패널
의미가 맞지 않는 태그를 컴포넌트로 사용
심지어 기능을 정의/사용하는 코드(JS)는 별도 파일에 작성
웹은 이
많은 컴
조합입
HTML
<div id="tabs">
<ul>
<li><a href="#fragment-1">One</a></li>
<li><a href="#fragment-2">Two</a></li>
<li><a href="#fragment-3">Three</a></li>
</ul>
<div id="fragment-1">
Lorem ipsum dolor sit amet, consectetuer adipiscing
elit, sed diam nonummy nibh euismod tincidunt ut
laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-2">
Lorem ipsum dolor sit amet, consectetuer adipiscing
elit, sed diam nonummy nibh euismod tincidunt ut
laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-3">
Lorem ipsum dolor sit amet, consectetuer adipiscing
elit, sed diam nonummy nibh euismod tincidunt ut
laoreet dolore magna aliquam erat volutpat.
</div>
</div>
<script>
jQuery(function($) {
$( "#tabs" ).tabs({
active: 1
});
});
</script>
의미가 더 명확한 쪽은?
<Tabs selectedIndex={1}>
<TabList>
<Tab>One</Tab>
<Tab>Two</Tab>
<Tab>Three</Tab>
</TabList>
<TabPanel>
Lorem ipsum dolor sit amet, consectetuer adipiscing
elit, sed diam nonummy nibh euismod tincidunt ut
laoreet dolore magna aliquam erat volutpat.
</TabPanel>
<TabPanel>
Lorem ipsum dolor sit amet, consectetuer adipiscing
elit, sed diam nonummy nibh euismod tincidunt ut
laoreet dolore magna aliquam erat volutpat.
</TabPanel>
<TabPanel>
Lorem ipsum dolor sit amet, consectetuer adipiscing
elit, sed diam nonummy nibh euismod tincidunt ut
laoreet dolore magna aliquam erat volutpat.
</TabPanel>
</Tabs>
가상 DOM JSX 문법 단방향 데이터 흐름
• 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교
• 메모리에 가상의 DOM 트리를 구축
Before After
가상 DOM JSX 문법 단방향 데이터 흐름
• 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교
• 메모리에 가상의 DOM 트리를 구축
• 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영
Before After
가상 DOM JSX 문법 단방향 데이터 흐름
• 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교
• 메모리에 가상의 DOM 트리를 구축
• 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영
• 임의의 두 트리를 비교하는 최소 횟수는 O(n^3),
React에서는 같은 레벨의 트리만 비교하여 O(n)으로 최적화
Before After
가상 DOM JSX 문법 단방향 데이터 흐름
• 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교
• 메모리에 가상의 DOM 트리를 구축
• 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영
• 임의의 두 트리를 비교하는 최소 횟수는 O(n^3),
React에서는 같은 레벨의 트리만 비교하여 O(n)으로 최적화
• 그 밖에도 목록 항목의 키 비교, 컴포넌트 비교, 배치 잡,
자동 이벤트 위임, 선택적 하위 트리 렌더링 등을 통해
노력 대비 꽤 나은 성능 보장
Before After
가상 DOM JSX 문법 단방향 데이터 흐름
• 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교
• 메모리에 가상의 DOM 트리를 구축
• 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영
• 임의의 두 트리를 비교하는 최소 횟수는 O(n^3),
React에서는 같은 레벨의 트리만 비교하여 O(n)으로 최적화
• 그 밖에도 목록 항목의 키 비교, 컴포넌트 비교, 배치 잡,
자동 이벤트 위임, 선택적 하위 트리 렌더링 등을 통해
노력 대비 꽤 나은 성능 보장
React.js Conf 2015 - Hype! | http://youtu.be/z5e7kWSHWTg?t=4m10s
Angular ReactEmber
가상 DOM JSX 문법 단방향 데이터 흐름
• 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교
• 메모리에 가상의 DOM 트리를 구축
• 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영
• 임의의 두 트리를 비교하는 최소 횟수는 O(n^3),
React에서는 같은 레벨의 트리만 비교하여 O(n)으로 최적화
• 그 밖에도 목록 항목의 키 비교, 컴포넌트 비교, 배치 잡,
자동 이벤트 위임, 선택적 하위 트리 렌더링 등을 통해
노력 대비 꽤 나은 성능 보장
• Google은 2015년 7월에 Incremental DOM이라는
Virtual DOM 라이브러리 발표
• Ember는 Glimmer라는 Virtual DOM 기술 적용
Virtual DOM != Silver Bullet
Angular 2 alpha 버전은 Virtual DOM 없이 더 나은 성능을 구현
그래도 꽤 나은 선택
http://goo.gl/k4pYbH
가상 DOM JSX 문법 단방향 데이터 흐름
• 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교
• 메모리에 가상의 DOM 트리를 구축
• 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영
• 임의의 두 트리를 비교하는 최소 횟수는 O(n^3),
React에서는 같은 레벨의 트리만 비교하여 O(n)으로 최적화
• 그 밖에도 목록 항목의 키 비교, 컴포넌트 비교, 배치 잡,
자동 이벤트 위임, 선택적 하위 트리 렌더링 등을 통해
노력 대비 꽤 나은 성능 보장
가상 DOM JSX 문법 단방향 데이터 흐름
• 자바스크립트 안에 XML을 표현하는 문법
var app = <Nav color="blur" />;
• 자바스크립트 코드로 변환해서 사용
var app = React.createElement(Nav, {color:"blue"});
• 속성 표현을 통해 문자열은 물론 자바스크립트 값을 그대로 전달
var app = <Nav color="blur" checked={true} name={name||"!"} />;
• 필수는 아니지만 거의 모든 React 프로젝트가 사용 중
가상 DOM JSX 문법 단방향 데이터 흐름
• 데이터는 상위 컴포넌트에서 하위 컴포넌트로만 흐름
• 상위에서 전달받은 값(props)은 수정 불가(immutable)
• 상위 컴포넌트는 하위 컴포넌트의 이벤트를 전달받아 업데이트
• 컴포넌트 내부의 상태는 스테이트(state)에 저장
• Flux: 애플리케이션 수준에서 적용한 단방향 데이터 흐름
성능
페이지 로딩 + 자바스크립트 로딩 + 렌더링 =
초기 구동 속도가 느리다
검색 엔진 최적화
자바스크립트를 실행하지 못하는 크롤러는
페이지의 콘텐츠를 수집하지 못한다
클라이언트 렌더링의
성능
매번 전체 페이지를 다시 읽는 것보다 빠름
사용자 경험
자연스럽게 연결되는 사용자 경험 가능
코드의 일관성
렌더링 책임은 한 쪽에만 주는 편이 일관성 유지가 쉬움
장점 단점
성능
페이지 로딩 + JS 로딩 + 렌더링 (+ 데이터 로딩)=
초기 구동 속도가 느림
검색 엔진 최적화
자바스크립트를 실행하지 못하는 크롤러는
페이지의 콘텐츠를 수집하지 못함
단점클라이언트 렌더링의
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class App extends Component {
render() {
return <h1>Hello, world!</h1>;
}
}
ReactDOM.render(
<App list={[1, 2, 3]} />,
document.getElementById('example')
);
앞서 살펴 본 클라이언트 코드
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class App extends Component {
render() {
return <h1>Hello, world!</h1>;
}
}
ReactDOM.render(
<App list={[1, 2, 3]} />,
document.getElementById('example')
);
ReactDOM은 브라우저 환경에만 해당
import ReactDOM from 'react-dom';
ReactDOM.render
import ReactDOM from 'react-dom';
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class App extends Component {
render() {
return <h1>Hello, world!</h1>;
}
}
ReactDOM.render(
<App list={[1, 2, 3]} />,
document.getElementById('example')
);
DOM 관련 부분만 별도 파일로 분리
import ReactDOM from 'react-dom';
ReactDOM.render
import React, { Component } from 'react';
ReactDOM.render(
<App list={[1, 2, 3]} />,
document.getElementById('example')
);
class App extends Component {
render() {
return <h1>Hello, world!</h1>;
}
}
import ReactDOM from 'react-dom';
DOM 관련 부분만 별도 파일로 분리
import React, { Component } from 'react';
ReactDOM.render(
<App list={[1, 2, 3]} />,
document.getElementById('example')
);
export default App;
import App from './App';
browser.js
App.js
class App extends Component {
render() {
return <h1>Hello, world!</h1>;
}
}
import ReactDOM from 'react-dom';
DOM 관련 부분만 별도 파일로 분리
import React, { Component } from 'react';
class App extends Component {
render() {
return <h1>Hello, world!</h1>;
}
}
ReactDOM.render(
<App list={[1, 2, 3]} />,
document.getElementById('example')
);
export default App;
import App from './App';
browser.js
App.js
import ReactServer from 'react-dom/server';
서버 렌더링은 react-dom/server 사용
import React, { Component } from 'react';
class App extends Component {
render() {
return <h1>Hello, world!</h1>;
}
}
var result = ReactServer.renderToString(
<App list={[1, 2, 3]} />
);
export default App;
import App from './App';
server.js
App.js
import ReactServer from 'react-dom/server';
결과물을 HTML 페이지에 출력
<body>
<div id="example">
{{result}}
</div>
</body>
var result = ReactServer.renderToString(
<App list={[1, 2, 3]} />
);
import App from './App';
server.js
index.html
import ReactServer from 'react-dom/server';
결과물을 HTML 페이지에 출력
<body>
<div id="example">
{{result}}
</div>
</body>
var result = ReactServer.renderToString(
<App list={[1, 2, 3]} />
);
import App from './App';
server.js
index.html
{{result}}
result
네이티브 컴포넌트
비동기 실행
Flexbox 레이아웃
폴리필(Polyfill)
간편한 네이티브 확장
• 자바스크립트는 네이티브보다 훨씬 느리기 때문에 동기 실행시
네이티브 UI와 자바스크립트 간의 병목 현상 발생
• 네이티브와 자바스크립트 사이에 메시지 큐를 두어 비동기 실행
JS VM Native
Java/C++/ObjC/Switft
비동기 실행
Flexbox 레이아웃
폴리필(Polyfill)
간편한 네이티브 확장
• CSS와 구조가 비슷한 StyleSheet 객체 사용
• CSS3 Flexbox와 비슷한 방식으로 레이아웃 스타일링
var ReactNative = React.createClass({
render: function() {
return (
<View style={styles.row}>
<View style={styles.text}>
<Text style={styles.title}>React Native</Text>
<Text style={styles.subtitle}>Build mobile apps using React</Text>
</View>
</View>
);
},
});
var styles = StyleSheet.create({
row: { flexDirection: 'row', margin: 40 },
text: { flex: 1, justifyContent: 'center'},
title: { fontSize: 11, fontWeight: 'bold' },
subtitle: { fontSize: 10 },
});
xbox 레이아웃
폴리필(Polyfill)
간편한 네이티브 확장
• XHR, requestAnimationFrame, navigator.geolocation 등
익숙한 자바스크립트 기능 제공
var GeoInfo = React.createClass({
getInitialState: function() {
return { position: 'unknown' };
},
componentDidMount: function() {
navigator.geolocation.getCurrentPosition(
(position) => this.setState({position}),
(error) => console.error(error)
);
},
render: function() {
return (
<Text>
Position: {JSON.stringify(this.state.position)}
</Text>
);
},
});
리필(Polyfill)
간편한 네이티브 확장
• Java(Android), ObjectiveC/Swift (iOS)로 작성된
네이티브 모듈을 손쉽게 자바스크립트 모듈로 바인딩
// Java
public class MyCustomModule extends ReactContextBaseJavaModule {
// Available as NativeModules.MyCustomModule.processString
@ReactMethod
public void processString(String input, Callback callback) {
callback.invoke(input.replace("Goodbye", "Hello"));
}
}
// JavaScript
...
componentDidMount() {
NativeModules.MyCustomModule.processString(this.state.text, (text) => {
this.setState({text});
});
},
...
$ brew install node watchman
$ node install -g react-native-cli
필요한 패키지 설치 (Xcode 및 안드로이드 SDK 필수)
프로젝트 생성
$ react-native init HelloWorld
프로젝트 오픈 후 컴파일
$ cd HellWorld
$ open ios/HelloWorld.xcodeproj (iOS)
$ react-native run-android (Android)
코드는 index.{ios, android}.js 파일 수정
React Native를
포크한 프로젝트라
사용법도 비슷합니다
예제 실행방법
$ git clone https://github.com/ptmt/react-native-desktop
$ cd react-native-desktop && npm install
Examples 아래의 원하는 폴더로 가서 .xcodeproj 파일을 XCode에서 열고 컴파일
Hello World 앱 크기 비교
React Native Desktop
3.5MB
105.3MB
(OS X 빌드 기준)
Credits
Twitter and Wordpress icons are made by Freepik from www.flaticon.com
All images without any notes are published under Creative Commons zero.
All videos are published under Creative Commons zero.