SlideShare a Scribd company logo
@maxmaxmaxmaxМАКСИМ КЛИМИШИН
CTO ZAKAZ.UA
GVMachines Inc.
Изоморфный
JavaScript
Обомне
‣ 11+ летопытавебразработки,5летJavaScript,
6летPython
‣ Работалв oDesk,Helios,42cc.
‣ Со-организаторконференцийPyConUkraine,
KyivJS
‣ 3годаработаютехническимдиректоромв
ZAKAZ.UA
Что такое
изоморфный код?
isomorphic
Возможностьиспользовать
одини тотжекод
какнаклиентетакинасервере
ISOMORPHIC
СЕЙЧАС
CLIENT
API
SERVER
изоморфный код
Зачем этонадо?
Проблемыonepageapps
Зачем это надо?
‣ Производительность-загрузкаданных,
задержкапри старте
‣ Тяжелаяоперацияпорендерингуисозданию
DOM-дерева
‣ Недружелюбныедлякраулеров(hashbang)
Проблемыархитектуры
Зачем это надо?
‣ Двойнаявалидациявходныхданных
‣ Поддержкасложнойбизнес-логики
одновременнонаклиентеинасервере
‣ Зависимость отсерверавмобильных
приложениях
ИзоморфныйJavaScript
может
решитьэти проблемы
Зачем это надо?
ПочемуJavaScript?
Зачем это надо?
‣ Браузерыполноценноподдерживают
только JavaScript
‣ Все.
Проблема
JavaScript
Основныепреграды
JavaScript
‣ Несовместимыесcommon.jsбиблиотеки
‣ Плохаясовместимостьмодулей(backward
compatibility)
‣ Малоинструментовдляконтроля
асинхронногокода
‣ Глобальноесостояниеимутабельность
объектов
Чтоужеесть?
JavaScript
‣ React
‣ Meteor
‣ Derby
‣ Lazojs
‣ …
КУДА ДВИЖЕТСЯ
CLIENT
API
SERVER
изоморфный код
DATABASE CACHE
React Native
теперьможносоздавать
мобильныеприложения
МОБИЛЬНЫЕ
КУДА ДВИЖЕТСЯ
CLIENT
API
SERVER
изоморфный код
DATABASE CACHE
MOBILE
Такое заинтересует кого угодно
Такое заинтересует кого угодно
AST,LLVM
Естьвариантырешитьэту
проблемупо другому
Abstractsyntaxtree
AST
‣ pyjamasи другие-анализируетдерево python
кодаисоздаеткоднаfront-end
‣ проблемастем,чтонужнодобавлять runtime
языка,которыйиспользуется
‣ можноограничитьruntime,нос
неполноценнойподдержкойтрудно
AST
PYTHON
RUBY
…
AST JAVASCRIPT
RUNTIME
LLVM– Low LevelVirtualMachine
LLVM
‣ emscripten–тулзадляпреобразования LLVM в
JavaScript
‣ Онпортирруетстекит.д.
‣ Ноеслииспользоватьвместес Clojure
Compiler,токодбудетхорошо
оптимизированным
‣ Python,Rubyи всеязыкиLLVMвJavaScript
LLVM
PYTHON
RUBY
…
LLVM INTERMEDIATE JAVASCRIPT
RELOOPER ALGO
#include <stdio.h>
int main()
{
int sum = 0;
for (int i = 1; i <= 100; i++)
sum += i;
printf("1+...+100=%dn", sum);
return 0;
}
C
@.str = private constant [14 x
i8]
c"1+...+100=%d0A00"
define i32 @main() {
%1 = alloca i32, align 4
%sum = alloca i32, align 4
%i = alloca i32, align 4
store i32 0, i32* %1
store i32 0, i32* %sum, align 4
store i32 1, i32* %i, align 4
br label %2
; <label>:2
%3 = load i32* %i, align 4
%4 = icmp sle i32 %3, 100
br i1 %4, label %5, label %12
; <label>:5
%6 = load i32* %i, align 4
%7 = load i32* %sum, align 4
%8 = add nsw i32 %7, %6
store i32 %8, i32* %sum, align
4
br label %9
; <label>:9
%10 = load i32* %i, align 4
%11 = add nsw i32 %10, 1
store i32 %11, i32* %i, align 4
br label %2
; <label>:12
%13 = load i32* %sum, align 4
%14 = call i32 (i8*, ...)*
@printf(i8* getelementptr
inbounds
([14 x i8]* @.str, i32
0, i32 0),
i32 %13)
ret i32 0 }
LLVMassembly
function _main() {
var __label__;
var $1;
var $sum;
var $i;
$1 = 0;
$sum = 0;
$i = 0;
$2$2: while(1) {
var $3 = $i;
var $4 = $3 <= 100;
if (!($4))
{ __label__ = 2; break
$2$2; }
var $6 = $i;
var $7 = $sum;
var $8 = $7 + $6;
$sum = $8;
var $10 = $i;
var $11 = $10 + 1;
$i = $11;
__label__ = 0;
continue $2$2;
}
var $13 = $sum;
var $14 =
_printf(__str, $13);
return 0;
}
Low-levelJavaScript
function K() {
var a, b;
b = a = 0;
a:for(;;) {
if(!(b <= 100)) {
break a
}

a += b; b += 1;
}
_printf(J, a);
return 0;
}
+ClosureCompiler
Уподходов естьобщаяпроблема–
 debugging
Clojure&ClojureScript
Clojure
‣ КомпилируетсявJavaScript (какивлюбой
другойязык)потому синтаксисотсутствует
‣ SourceMaps+полноценнаяимплементация
рантайманаJavaScript– легкодебажить
‣ Неизменяемые структуры данных
ClojureScript
CLOJURESCRIPT JAVASCRIPT
CLOJURE RUNTIME
Lisp
Syntax free
Следствиемотсутствиясинтаксиса–
~35трансляторов/компиляторов/
интерпретаторовlisp-оподобныхязыков
OM
ClojureScript+OM
(defn- render-fn* []
(let [js (doto (.getEngineByName (ScriptEngineManager.) "nashorn")
; React requires either "window" or "global" to be defined.
(.eval "var global = this")
(.eval (-> "public/assets/scripts/main.js"
io/resource
io/reader)))
view (.eval js "omelette.view")
render-to-string (fn [edn]
(.invokeMethod
^Invocable js
view
"render_to_string"
(-> edn
list
object-array)))]
(fn render [title state-edn]
(html5
[:head
[:meta {:charset "utf-8"}]
[:meta {:http-equiv "X-UA-Compatible" :content "IE=edge,chrome=1"}]
Изоморфный JSкак
отдельныйсервис
Апочему-быне сделать
отдельныйсервис,который
рендеритJavaScriptгденадо
Service
Service
‣ Синхронныйсервис
‣ Очередь задач,асинхронно
Дваварианта
Service
приложение
database cache node.js
rendered rendered
task1
запрос2
state
серверзадачnode.js
запрос1
state
task2
cache
Выводы
Выводы
‣ Увеличиваетсяколичествоsharedкода,
уменьшаетсярассеивание бизнеслогики
междуразнымиплатформами(клиент,сервер,
мобильные)
‣ УлучшаетсяUX– засчет пререндеринга
пользовательполучаеткартинкунаэкране
быстрее
‣ Улучшаетсявидимостьвпоисковыхсистемах
‣ НенужновсепереписыватьнаJavaScript
Ктовтеме
Выводы
‣ Facebook
‣ Instagram
‣ Yahoo!Mail
‣ Walmart
‣ Airbnb
‣ Netflix
iForum 2015
@maxmaxmaxmax

More Related Content

Изоморфный JavaScript (iForum 2015)