43
@maxmaxmaxmax МАКСИМ КЛИМИШИН CTO ZAKAZ.UA GVMachines Inc. Изоморфный JavaScript

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

Embed Size (px)

Citation preview

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

@maxmaxmaxmaxМАКСИМ КЛИМИШИНCTO ZAKAZ.UA

GVMachines Inc.

Изоморфный JavaScript

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

Обо мне

‣ 11+ лет опыта веб разработки, 5 лет JavaScript, 6 лет Python

‣ Работал в oDesk, Helios, 42cc.

‣ Со-организатор конференций PyCon Ukraine, KyivJS

‣ 3 года работаю техническим директором в ZAKAZ.UA

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

Что такое изоморфный код?

isomorphic

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

Возможность использовать один и тот же код

как на клиенте так и на сервере

ISOMORPHIC

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

СЕЙЧАС

CLIENT

API

SERVER

изоморфный код

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

Зачем это надо?

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

Проблемы one page apps

Зачем это надо?

‣ Производительность - загрузка данных, задержка при старте

‣ Тяжелая операция по рендерингу и созданию DOM-дерева

‣ Недружелюбные для краулеров (hashbang)

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

Проблемы архитектуры

Зачем это надо?

‣ Двойная валидация входных данных

‣ Поддержка сложной бизнес-логики одновременно на клиенте и на сервере

‣ Зависимость от сервера в мобильных приложениях

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

Изоморфный JavaScript может

решить эти проблемы

Зачем это надо?

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

Почему JavaScript?

Зачем это надо?

‣ Браузеры полноценно поддерживают только JavaScript

‣ Все.

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

Проблема

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

JavaScript

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

Основные преградыJavaScript

‣ Несовместимые с common.js библиотеки

‣ Плохая совместимость модулей (backward compatibility)

‣ Мало инструментов для контроля асинхронного кода

‣ Глобальное состояние и мутабельность объектов

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

Что уже есть?JavaScript

‣ React

‣ Meteor

‣ Derby

‣ Lazojs

‣ …

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

КУДА ДВИЖЕТСЯ

CLI

ENT

API

SERV

ER

изоморфный код

DATABASE CACHE

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

React Native теперь можно создавать мобильные приложения

МОБИЛЬНЫЕ

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

КУДА ДВИЖЕТСЯ

CLI

ENT

API

SERV

ERизоморфный код

DATABASE CACHE

MOBILE

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

Такое заинтересует кого угодно

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

Такое заинтересует кого угодно

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

AST, LLVM

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

Есть варианты решить эту проблему по другому

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

Abstract syntax treeAST

‣ pyjamas и другие - анализирует дерево python кода и создает код на front-end

‣ проблема с тем, что нужно добавлять runtime языка, который используется

‣ можно ограничить runtime, но с неполноценной поддержкой трудно

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

AST

PYTHON

RUBY

AST JAVASCRIPT

RUNTIME

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

LLVM – Low Level Virtual MachineLLVM

‣ emscripten – тулза для преобразования LLVM в JavaScript

‣ Он портиррует стек и т.д.

‣ Но если использовать вместе с Clojure Compiler, то код будет хорошо оптимизированным

‣ Python, Ruby и все языки LLVM в JavaScript

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

LLVM

PYTHON

RUBY

LLVM INTERMEDIATE JAVASCRIPT

RELOOPER ALGO

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

#include <stdio.h>int main(){ int sum = 0; for (int i = 1; i <= 100; i++) sum += i; printf("1+...+100=%d\n", sum); return 0;}

C

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

@.str = private constant [14 x i8] c"1+...+100=%d\0A\00"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 }

LLVM assembly

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

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-level JavaScript

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

function K() { var a, b; b = a = 0; a:for(;;) { if(!(b <= 100)) { break a } a += b; b += 1; } _printf(J, a); return 0; }

+ Closure Compiler

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

У подходов есть общая проблема – debugging

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

Clojure & ClojureScriptClojure

‣ Компилируется в JavaScript (как и в любой другой язык) потому синтаксис отсутствует

‣ Source Maps + полноценная имплементация рантайма на JavaScript – легко дебажить

‣ Неизменяемые структуры данных

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

ClojureScript

CLOJURESCRIPT JAVASCRIPT

CLOJURE RUNTIME

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

LispSyntax free

Следствием отсутствия синтаксиса – ~35 трансляторов/компиляторов/

интерпретаторов lisp-о подобных языков

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

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"}]

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

Изоморфный JS как отдельный сервис

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

А почему-бы не сделать отдельный сервис, который рендерит JavaScript где надо

Service

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

Service

‣ Синхронный сервис

‣ Очередь задач, асинхронно

Два варианта

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

Service

приложение

database cache node.js

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

rendered rendered

task 1

запрос 2

state

сервер задач node.js

запрос 1

state

task 2

cache

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

Выводы

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

Выводы

‣ Увеличивается количество shared кода, уменьшается рассеивание бизнес логики между разными платформами (клиент, сервер, мобильные)

‣ Улучшается UX – за счет пререндеринга пользователь получает картинку на экране быстрее

‣ Улучшается видимость в поисковых системах

‣ Не нужно все переписывать на JavaScript

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

Кто в темеВыводы

‣ Facebook

‣ Instagram

‣ Yahoo! Mail

‣ Walmart

‣ Airbnb

‣ Netflix

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

iForum 2015

@maxmaxmaxmax