Проводка

Какие виды слесарных подкладок есть. Словарь профессиональных терминов (основы технологии слесарных работ)

Какие виды слесарных подкладок есть. Словарь профессиональных терминов (основы технологии слесарных работ)
  • Перевод

В 2009-м платформа Node.js сделала свои скромные первые шаги в бескрайнем мире разработки бэкендов. Это была была первая состоявшаяся попытка использования JavaScript в серверных приложениях. Сегодня будет крайне затруднительно найти веб-разработчика, который не слышал о Node. Но нельзя сказать, что существование Node было безоблачным. Эта платформа пережила раскол сообщества, была предметом форумных войн и многих довела до отчаяния.

Возможно, вы думаете, что подобные заявления звучат слишком уж напыщенно. Однако, попробуйте поискать в Google, и вы столкнётесь с неистощимым источником бесконечных споров . Среди рассуждений не в пользу Node, которые могут вам встретиться, есть, например, такие, которые, вопрошая о том, что случилось с аксиомой об использовании лучшего из имеющихся инструментов для решения некоей задачи, указывают, что JS и рядом не стоял с правильным серверным инструментарием. критические замечания о JS, вроде «Callback hell is real», призывающие поверить в реальность ада коллбэков, звучат как строчки из стихотворения. Некоторые из критиков Node выражаются более прямо и однозначно: «Node - это раковая опухоль».

Полагаю, настало время восстановить истинное положение вещей, расставить все точки над «i» в том, что касается платформы Node.js и JavaScript в роли языка серверной разработки. Сегодня мы поговорим о современном состоянии и развитии Node.js, о наиболее удачных вариантах использования этой платформы, о её ограничениях, и о технологиях, созданных на её основе.

Современное состояние Node.js как серверной платформы Прежде чем говорить о том, как выглядит сегодня серверная платформа Node , вспомним о том, что это такое.

А именно, это среда выполнения JavaScript, построенная на базе JS-движка V8 , разработанного Google и применяемого в Google Chrome. Node.js использует неблокирующую модель ввода-вывода, управляемую событиями, которая делает эту платформу простой и эффективной.

В начале этого материала Node показан как прямо-таки кошмар программиста. Однако, эта платформа не случайно стала весьма популярной. Тут мы не станем опираться на голословные утверждения. Лучше взглянем на факты. А именно, свежее исследование Stack Overflow показывает, что Node.js - это, на сегодняшний момент, самая популярная среди разработчиков технология.


Кроме того, JS - это язык, популярность которого за последние пять лет растёт быстрее, чем у других языков, при том, что C# и PHP теряют позиции. Распространённость JavaScript, если даже не говорить исключительно о Node, идёт вверх.


Как можно объяснить то, что JavaScript, в роли серверного языка, был столь быстро и широко принят сообществом разработчиков? Проще говоря, Node пережил стадию, в которой воспринимался как некая забава, и вошёл в фазу стабильности и зрелости. Вокруг него сформировалось мощное сообщество, размер которого неуклонно растёт. Экосистема Node также достойна упоминания, так как, например, менеджер пакетов Node, npm , в настоящий момент представлен самым большим реестром ПО в интернете.

Node.js не только совершил революцию в серверной разработке, но благодаря ему сделан вклад и в производительность клиентских приложений, так как к развитию V8 были привлечены серьёзные силы. Кроме того, он играет заметную роль в расширении всей экосистемы JavaScript и в совершенствовании современных JS-фреймворков, таких, как Angular , React или Vue .

С течением времени Node смог опровергнуть предрассудки ранних дней. Вот некоторые из них.

JavaScript-код для Node.js печально известен сложностью отладки.

Для отладки серверных JS-приложений можно использовать те же самые методики, которые применяются для отладки клиентского кода, применяя node-inspector , где собраны средства инструментов разработчика Chrome.

Node нельзя использовать для разработки серверных приложений корпоративного класса.

Это утверждение тоже не соответствует действительности. На базе Node можно создавать корпоративные системы. Сложность заключается лишь в том, что в нём имеется не особенно много встроенных средств, упрощающих создание подобных систем. Однако, заметные игроки IT-рынка используют Node в качестве корпоративной веб-платформы. Среди них - Netflix. PayPal, Yahoo!, Walmart.

JavaScript - это динамический язык, поэтому, работая на нём, нельзя использовать нечто вроде статической проверки типов при компиляции.

Это правда. Однако, в экосистеме JS появились средства вроде TypeScript и Flow, которые нацелены на работу с типами в JS, что позволяет повысить стабильность и предсказуемость программ, упростить отладку. В этой сфере можно воспользоваться и возможностями Closure Compiler от Google.

JavaScript не создавался как язык для серверной разработки.

Тут можно лишь сказать, что JS уже мог работать на серверах , тогда же, когда Netscape встроила поддержку этого языка в свой браузер. А было это аж в 1995-м. JS обычно называют языком клиентской веб-разработки лишь потому, что он полностью захватил эту сферу.

На самом деле, этот список можно продолжать и продолжать.

Теперь поговорим о сценариях использования Node.js и о его ограничениях для того, чтобы лучше понять место этой технологии в современном мире.

Сценарии применения Node Итак, зачем вообще рассматривать Node.js как средство серверной разработки в применяемом вами стеке технологий?▍Преимущества и общие характеристики Позвольте мне в двух словах обозначить самое важное:
  • Весьма вероятно, что клиентские части ваших веб-приложений написаны на JavaScript. В этом случае универсальность кода в применяемом стеке технологий - это важный плюс использования JS и на сервере, о котором стоит помнить.
  • Инструменты вроде webpack помогают в повторном использовании кода и на клиенте, и на сервере, что ведёт к его единообразию на всех уровнях системы.
  • Применяя JS на клиенте и на сервере , можно создавать веб-приложения, которые могут рендериться и в браузере, и на сервере . При этом такие системы обычно работают весьма чётко и понятно. Полагаю, это - просто потрясающе.
  • Появление в Node конструкции async/await полностью изменило подход к написанию асинхронного кода. Теперь такой код напоминает обычный синхронный код, и по внешнему виду, и по поведению. Механизм async/await поддерживается в Node начиная с версии 7.6 . Он, в частности, является решением печально известной проблемы ада коллбэков .
Некоторые видят в сближении кодовой базы клиента и сервера минус Node.js, говоря о том, что он принуждает разработчика к использованию JavaScript. Однако, это не совсем так. При необходимости из Node-приложений можно обращаться к сторонним специализированным библиотекам.

Скажем, вам нужны инструменты для кодирования видео. Для того, чтобы оснастить ими свой проект, написанный на JavaScript, вам не придётся искать какие-то малораспространённые таинственные библиотеки для Node. Вы вполне сможете воспользоваться проверенными инструментами, наладив взаимодействие с ними из Node. Или, например, если имеется некая библиотека на Python, выполняющая необходимые вам сложные вычисления, специально для работы с ней можно запустить микросервис и обращаться к соответствующим функциям этой библиотеки через REST API.

Учитывая всё вышесказанное, можно выделить следующие варианты использования Node.js, в которых он в полной мере раскрывает свои сильные стороны.

▍Сценарий №1. Приложения реального времени Приложения для совместной работы (такие, как Trello и Google Docs), интерактивные чаты, системы мгновенного обмена сообщениями и онлайн-игры - это примеры приложений реального времени, при разработке которых особенности архитектуры Node.js могут сослужить вам хорошую службу.

Время, необходимое этим приложениям для выполнения тех или иных действий, можно охарактеризовать, с точки зрения пользователя, словами «немедленно» и «сейчас» . Для нормальной работы таких приложений система, на которой они основаны, должна обеспечивать очень высокую скорость отклика на действия пользователя и низкий уровень задержек. Node отвечает этим требованиям.

Node облегчает обработку множества запросов от клиентов, его архитектура способствует эффективному использованию библиотек, он обеспечивает очень быструю синхронизацию данных между клиентом и сервером.

▍Сценарий №2. Одностраничные приложения Одностраничное приложение - это приложение, которое представлено единственной загружаемой в браузер веб-страницей, содержимое которой динамически обновляется в ходе взаимодействия с ней пользователя. Большая часть нагрузки при работе таких приложений ложится на клиентскую часть системы, написанную на JavaScript.

Даже хотя одностраничные приложения - это значительный шаг в эволюции веб-разработки, есть у них и проблемы, которые, например, касаются рендеринга. В частности, это может плохо повлиять на поисковую оптимизацию страниц. Популярное решение этих проблем заключается в серверном рендеринге средствами Node.js.

▍Сценарий №3. Масштабируемость Сервер на Node никогда не окажется гораздо мощнее, чем нужно. Красота архитектуры Node заключается в её минималистичности, в том, что серверную часть приложений можно масштабировать в зависимости от потребностей проекта. Секрет тут кроется в правильном отношении к производительности.

Даже название предмета нашего разговора, «node» акцентирует внимание на возможности построения систем из множества небольших распределённых вычислительных узлов, которые могут обмениваться друг с другом данными.

Модульность Node позволяет создавать маленькие приложения, не сталкиваясь при этом с необходимостью поддержки огромной инфраструктуры, многие части которой в некоем конкретном случае окажутся незадействованными. При разработке Node-приложений программист выбирает именно то, что ему нужно, и, при необходимости, расширяет решение.

Однако, надо отметить, что подобным возможностям масштабирования сопутствуют и определённые сложности. И, если потерять бдительность, Node.js может стать… опасным.

Ограничения Node.js Если говорить честно, то Node позволяет разработчику, что называется, «выстрелить себе в ногу». В этом мире за всё надо платить, в том числе - и за широкие возможности по настройке системы и по подгонке её под свои нужды. Если работать с Node, не имея достаточного опыта или регулярно пуская дело на самотёк - можно столкнуться с серьёзными проблемами вроде потери клиентов.

В противовес более традиционным подходам, жёстко регламентирующим те или иные архитектурные особенности систем, структуру, которая поддерживает серверную часть вашего приложения, создаёте именно вы. В результате, тут приходится принимать множество решений, то есть, разработчику необходимо точно знать - чем именно он занимается, и что будет с проектом, если его потребуется расширить.

В случае с другими языками, вроде Ruby, и широко известного фреймворка Ruby on Rails, например, в ходу идея, которая заключается в преимуществе соглашений над конфигурированием системы. Эти традиционные фреймворки буквально ведут разработчика за руку, показывая ему правильный, безопасный путь решения типичных задач.

Node переворачивает всё, так сказать, с ног на голову. Разработчику даётся больше свободы, но путь к реализации задуманного может оказаться полным опасностей, если в ходе работы будут приняты неверные решения. Тут уместно будет вспомнить о пресловутом «аде коллбэков», который вдруг окажется совершенно реальным.


Это не означает, что на Node нельзя создавать большие серверные приложения, но вышесказанное стоит постоянно держать в голове.

Даже создатель Node.js, Райан Даль , в итоге, перед переходом к другим проектам, осознал ограничения системы. Он высказался на этот счёт весьма однозначно:

«Думаю, Node - это не лучшая система для создания крупномасштабных серверных проектов. Я бы использовал для этого . И, честно говоря, именно поэтому я и оставляю работу над Node. Я однажды понял, что, на самом деле, это вовсе не самая лучшая система для серверной разработки ».

Ранее упомянутые предубеждения, касающиеся Node, были справедливы до определённого момента не такого уж и длинного жизненного пути Node, и они, до некоторой степени, всё ещё - не пустой звук. Node достаточно повзрослел и вырос, его слабые стороны, при необходимости и наличии времени, вполне можно обойти. А инструменты, разработанные сообществом, позволяют создать на базе Node.js практически всё, что угодно.

Популярные вспомогательные средства для серверной разработки на JS Не слишком давно, если некто задумывался о том, чтобы создавать все части своей системы на JS, в голову тут же приходила мысль о стеке MEAN (MongoDB, Express, Angular и Node).

Этот набор инструментов и в наши дни не потерял актуальности, однако, в настоящее время в экосистеме JS имеется гораздо больше интересных инструментов как для клиентской, так и для серверной разработки, поэтому не стоит ограничиваться MEAN.

Вот несколько популярных современных серверных JS-фреймворков:

  • Express.js был и всё ещё является самым популярным Node.js-фреймворком . Он быстр, компактен, не навязывает разработчику жёстких архитектурных решений. В основе его стремительного развития лежит простота и понятность. Возможно, он идеологически ближе всех остальных инструментов к идеям, лежащим в основе, Node, следуя которым он представляет собой легковесную модульную систему.
  • Meteor , с другой стороны, использует чистый JavaScript и Node.js внутри довольно-таки масштабной конструкции. Meteor и сам по себе - это целая экосистема, которая может подойти для разработки более сложных серверных приложений. Однако, использование Meteor может усложниться, если нужно что-то, что не встроено в систему.
  • Sails.js - это MVC-фреймворк реального времени. Он был разработал для имитации шаблона MVC на платформе Ruby on Rails, но при этом подразумевал поддержку требований современных веб-приложений. Работает это всё благодаря API, которые управляются данными, при наличии масштабируемой, сервис-ориентированной архитектуры.

    Полагаю, самое главное, что мне хотелось сделать - так это показать, что между безапеляционными «да» и «нет», которые можно встретить во многих рассуждениях о Node и о JS как о серверном языке, если обширная область «может быть».

    И, нравится это кому-нибудь или нет, интерес к Node постоянно растёт.


    В завершение этого материала мне хотелось бы сказать, что не стоит относиться к любому фреймворку как к палочке-выручалочке, которая волшебным образом решит все проблемы. Node.js - это просто один из инструментов в колоссальной вселенной веб-разработки. В некоторых ситуациях он решает поставленные перед ним задачи исключительно хорошо, а в других работа с ним может превратиться в кошмар.

    В задачи каждого разработчика входит тщательный подбор технологий , подходящих для реализации любого нового проекта. При этом важно учитывать все возможности и не отбрасывать сходу имеющиеся альтернативы.

    Например, в компании Snipcart, где я работаю, используется архитектура.NET, о которой можно наговорить много всего нелицеприятного. Почему выбрана именно она? Да просто потому, что в конкретный момент она оказалась наилучшим инструментом для решения поставленной перед нами задачи.

    Надеюсь, мой рассказ о Node поможет вам принять правильное решение при выборе серверной платформы для вашего очередного проекта.

    Теги: Добавить метки

Клиентский JavaScript расширяет ядро языка за счёт объектов, управляющих браузером (Navigator или другой подобный web-браузер) и его Document Object Model (DOM). Например, клиентские расширения позволяют приложению размещать элементы на HTML-форме и отвечать на пользовательские события, такие как щелчок мышью, ввод данных в форму и навигация по страницам.
  • Серверный JavaScript расширяет ядро языка за счёт объектов, имеющих отношение к работе JavaScript на сервере. Например, серверные расширения позволяют подключиться к реляционной БД, поддерживать непрерывность информации между вызовами приложения или работать с файлами на сервере.
  • JavaScript даёт Вам возможность создавать приложения, работающие в Internet. Клиентские приложения работают в браузере, таком как Netscape Navigator, а серверные приложения запускаются на сервере, таком как Netscape Enterprise Server. Используя JavaScript, Вы можете создавать динамические HTML-страницы, которые обрабатывают пользовательский ввод и работают с данными через использование специальных объектов, файлов и реляционных баз данных.

    С помощью функциональности LiveConnect Вы можете дать возможность коду Java и JavaScript взаимодействовать. Из JavaScript Вы можете инстанциировать Java-объекты и получить доступ к их public-методам и полям. Из Java Вы можете иметь доступ к объекта, методам и свойствам JavaScript.

    Netscape изобрела JavaScript, и JavaScript впервые был использован в браузерах Netscape.

    Ядро, клиентский и серверный JavaScript

    Компоненты JavaScript показаны на этом рисунке.

    Рисунок 1.1 Язык JavaScript

    Следующие разделы являются введением в JavaScript на клиенте и на сервере.

    Ядро JavaScript

    Клиентский и серверный JavaScript имеют следующие общие элементы:

    • Ключевые слова
    • Синтаксис и грамматику операторов
    • Требования к выражениям, переменным и литералам
    • Объектную модель (хотя клиентский и серверный JavaScript имеют разные наборы предопределённых объектов)
    • Предопределённые объекты и функции, такие как Array , Date и Math
    Клиентский JavaScript

    Web-браузеры, такие как Navigator (2.0 и более поздние версии), могут интерпретировать операторы клиентского JavaScript, внедрённые в HTML-страницу. Если браузер (или клиент ) запрашивает такую страницу, сервер высылает полное содержимое документа, включая HTML и операторы JavaScript, клиенту по сети. Браузер читает страницу сверху вниз, отображая результирующий HTML и выполняя операторы JavaScript по мере из обнаружения. Этот процесс, показанный на следующем рисунке, выдает пользователю конечный результат.

    Рисунок 1.2 Клиентский JavaScript

    Операторы клиентского JavaScript, внедрённые в HTML-страницу, могут реагировать на пользовательские события, такие как щелчок мыши, ввод данных в форму и навигация по странице. Например, Вы можете написать функцию JavaScript для проверки правильности введённой пользователем в форму информации - номера телефона или zip-кода. Без передачи по сети, JavaScript, внедрённый на HTML-страницу, может проверить введённые данные и вывести диалоговое окно, если пользователь ввёл неправильные данные.

    Разные версии JavaScript работают с конкретными версиями Navigator" а. Например, JavaScript 1.2 предназначен для Navigator 4.0. Некоторые возможности JavaScript 1.2 недоступны в JavaScript 1.1 и, следовательно, недоступны в Navigator 3.0. О версиях JavaScript и Navigator см. "Версии JavaScript" .

    Серверный JavaScript

    Серверный JavaScript также встраивается в HTML-страницы. Серверные операторы могут подключать к реляционным БД разных производителей, предоставлять информацию в совместное использование несколькими потребителями, давать доступ к файловой системе сервера или взаимодействовать с другими приложениями через LiveConnect и Java. HTML-страницы с серверным JavaScript могут также содержать клиентский JavaScript.

    В отличие от страниц, написанных на чисто клиентском JavaScript, HTML-страницы с серверным JavaScript компилируются в байт-код исполняемых файлов. Эти исполняемые файлы запускаются web-сервером, имеющим машину выполнения JavaScript. Поэтому создание приложений JavaScript это процесс из двух этапов.

    На первом этапе, показанном на , Вы создаёте HTML-страницы (которые могут содержать операторы клиентского и серверного JavaScript) и JavaScript-файлы. Затем Вы компилируете все эти файлы в единый исполняемый файл.

    Рисунок 1.3 Серверный JavaScript в процессе разработки

    На втором этапе, показанном на , страница приложения запрашивается клиентским браузером. Машина выполнения использует исполняемый файл приложения для поиска исходной страницы и динамически генерирует возвращаемую клиенту HTML-страницу. Машина запускает на выполнение операторы серверного JavaScript, найденные на странице. В результате этого на HTML-страницу могут быть добавлены новый HTML или операторы JavaScript. Машина выполнения высылает результирующую страницу по сети Navigator" у-клиенту, который запускает на выполнение клиентский JavaScript и выводит результаты.

    Рисунок 1.4 Серверный JavaScript на этапе прогона

    В отличие от стандартных программ Common Gateway Interface (CGI), весь исходный JavaScript интегрируется непосредственно в HTML-страницы, ускоряя разработку и облегчая обслуживание. Служба Session Management Service серверного JavaScript содержит объекты, которые Вы можете использовать для обслуживания данных, существующих в промежутке между клиентскими запросами, нескольких клиентов и нескольких приложений. Служба LiveWire Database Service серверного JavaScript предоставляет объекты для доступа к БД, являясь интерфейсом для Structured Query Language (SQL)-серверов БД.

    JavaScript и Java

    JavaScript и Java похожи, но имеют фундаментальные отличия. Язык JavaScript напоминает Java, но не имеет статической типизации и строгой проверки типов Java. JavaScript в основном поддерживает синтаксис выражений Java и базовые конструкции управления потоком.

    В отличие от системы времени компиляции классов Java, построенной на объявлениях, JavaScript поддерживает систему времени прогона, базирующуюся на небольшом количестве типов данных: числовых, Булевых и строковых значениях. JavaScript имеет объектную модель на основе прототипов, а не более распространённую модель на основе классов. Модель на прототипах предоставляет возможность динамического наследования; то есть то, что наследуется, может варьироваться для разных объектов. JavaScript также поддерживает функции без специальных требований к объявлению. Функции могут быть свойствами объектов, выполняясь как слабо типизированные методы.

    JavaScript намного более свободен по форме по сравнению с Java. Вы не должны объявлять все переменные, классы и методы. Вы не должны учитывать, какие методы являются public, private или protected и Вы не должны реализовывать интерфейсы. Возвращаемые значения переменных, параметров и функций не являются явно типизированными.

    Java это язык программирования на основе классов, созданный для быстрого выполнения и строгой проверки типов. Строгая проверка типов означает, к примеру, что Вы не можете привести/cast целое число Java к ссылке на объект или получить доступ к private-памяти, нарушив байт-коды Java. Модель классов Java означает, что программы состоят исключительно из классов и их методов. Наследование классов Java и строгая типизация обычно требуют плотно выстроенной иерархии объектов. Эти требования делают программирование на Java более сложным, чем авторизация в JavaScript.

    JavaScript по духу происходит от небольших, динамически типизируемых языков, таких как HyperTalk и dBASE. Эти языки программирования являются утилитами программирования для широкой аудитории, так как имеют упрощённый синтаксис, специализированную встроенную функциональность и минимальные требования при создании объектов.

    Таблица 1.1 JavaScript в сравнении с Java JavaScript Java

    Интерпретируется (не компилируется) клиентом.

    Скомпилированные байт-коды загружаются с сервера, выполняются на клиенте.

    Объектно-ориентированный. Нет отличий в типах объектов. Наследование идёт через механизм прототипов, а свойства и методы могут динамически добавляться к любому объекту.

    На основе классов. Объекты делятся на классы и экземпляры с наследованием по всей цепи иерархии классов. Классы и экземпляры не могут иметь свойства или методы, добавляемые динамически.

    Код, интегрированный с и внедрённый в HTML.

    Аплеты отличаются от HTML (при доступе из HTML-страниц).

    Тип данных переменной не объявляется (динамическая типизация).

    Тип данных переменной обязан быть объявлен (статическая типизация).

    Не может автоматически записывать на жёсткий диск.

    Не может автоматически записывать на жёсткий диск.

    Отладка в JavaScript

    JavaScript позволяет создавать сложные компьютерные программы. Как и в других языках, Вы можете ошибаться при написании скриптов. Отладчик Netscape JavaScript Debugger позволяет отлаживать Ваши скрипты. Об использовании Отладчика/Debugger см. следующие документы:

    • Netscape JavaScript Debugger 1.1 - введение в Debugger.
    • Вы можете загрузить Debugger с указанного URL. Загружаемый файл это SmartUpdate .jar. Для установки Debugger загрузите этот.jar-файл в Navigator: используйте процедуру, описанную в вышеуказанном URL, или введите URL к.jar-файлу в поле location (адресную строку).

    • Getting Started with Netscape JavaScript Debugger объясняет, как пользоваться Отладчиком.
    Visual JavaScript

    Netscape Visual JavaScript это утилита визуальной разработки на базе компонентов для платформы Netscape Open Network Environment (ONE). Она предназначена в основном для использования разработчиками, которые хотят создавать платформонезависимые web-приложения на основе стандартов из готовых к использованию компонентов с минимальными затратами на программирование. Эти приложения основаны на HTML, JavaScript и Java.

    JavaScript и спецификация ECMA

    Корпорация Netscape изобрела JavaScript, и JavaScript впервые был использован в Netscape-браузерах. Одновременно Netscape работает совместно с ECMA (European Computer Manufacturers Association) над созданием стандартизованного международного языка программирования на основе ядра JavaScript. ECMA это международная ассоциация стандартов для информационных и коммуникационных систем. эта стандартизованная версия JavaScript, называемая ECMAScript, работает совершенно одинаково во всех приложениях, поддерживающих данный стандарт. Компании могут использовать этот открытый стандартный язык для разработки своих реализаций JavaScript. Первая версия стандарта ECMA документирована в спецификации ECMA-262.

    Стандарт ECMA-262 одобрен также ISO (International Organization for Standards) как ISO-16262. Вы можете найти PDF-версию ECMA-262 на сайте Netscape DevEdge Online. Вы можете также найти эту спецификацию на web-сайте ECMA . Спецификация ECMA не описывает Document Object Model (DOM), которая стандартизована консорциумом World Wide Web Consortium (W3C) . DOM определяет способ, которым HTML-объекты документа экспонируются Вашему скрипту.

    Соотношение версий JavaScript и ECMA

    Netscape тесно сотрудничает с ECMA для создания ECMA-спецификации. В таблице показано соотношение между версиями JavaScript и ECMA.

    Вопрос “Зачем?” - самый главный при принятии любого решения. В нашем случае причин было несколько.

    Во-первых, люди. Текущий шаблонизатор обрабатывался Си. Все вопросы о его изменениях решались не быстро. А самое главное, что писали шаблонизатор одни люди, а использовали совсем другие.

    Вообще это частая и, на мой взгляд, не очень хорошая практика написания инструментов для верстальщиков. Понятно, что им нужны инструменты, но реализуют эти инструменты люди, которые весьма отдаленно себе представляют ежедневные задачи верстальщиков. Скорее наоборот, часто принимаются решения плана «дадим им писать условия и циклы, а больше на верстке ничего понадобится не может». Возможно, это вина самих верстальщиков и их квалификации.

    Но в Mail.Ru Group есть целая команда высококвалифицированных людей, знающих JS, способных самостоятельно написать инструмент, а самое главное - они же им и будут пользоваться.

    Во-вторых, задачи. Возьмем проект Почта@Mail.ru. Мы не можем отказаться от шаблонизации на сервере – нам нужна быстрая загрузка при первом входе. Мы не можем отказаться от шаблонизации на клиенте – люди должны видеть высокую скорость реакции на их действия, а значит, обязателен AJAX и шаблонизация на клиенте.

    Проблема очевидна: два набора совершенно разных шаблонов на сервере и на клиенте. А самое обидное, что решают они одну и ту же задачу. Дублирование логики нас просто измотало.

    V8 - это интерпретатор JavaScript, а значит, мы можем получить один шаблон, который работает как на сервере, так и на клиенте.

    В-третьих, скорость. Прочитав много статей, в которых хвалят скорость v8, решили, что надо проверить их справедливость. Но сначала нужно было понять, каким мы хотим видеть новый шаблонизатор.

    Что нужно

    Скажу сразу, мы очень сильно ограничены по серверному времени на трансформацию, поэтому реализовывать нечто очень функциональное возможности не было. Однако и оставлять старый функционал с единственной разницей в добавлении прослойки из v8 - странная идея.

    Я давно и много использую для трансформации XSLT (не самый быстрый вариант трансформации), хотя, если его правильно использовать, он показывает хорошие цифры (я говорю про libxslt). Но у XSLT есть очень мощный инструмент шаблонизации – переопределение шаблонов. Мы решили реализовать нечто похожее, но намного проще.

    /head.xml … Mail.ru /mail.xml … Почта Mail.ru

    Странно было бы использовать v8 и не дать в шаблонах доступ к JavaScript.

    var text = “mail.ru” text

    И еще много чего по мелочи, помимо стандартных условий и циклов.

    В качестве синтаксиса для шаблонизатора мы взяли XML.

    Поддержка базового функционала в IDE. Сто процентов популярных IDE знают, что такое XML. Расстановку переносов, подсветку, базовое автодополнение вы получаете бесплатно.

    Валидация на уровне IDE. Валидный HTML получается за счет валидных шаблонов. Опять же, все IDE умеют валидировать xml как таковой.

    Модульность из коробки (name spaces). Базовые возможности шаблонизатора очень быстро захочется расширить. Например, добавить тег, который позволяет делать проекты на нескольких языках. Система Name Spaces позволяет легко это сделать.

    Широкий набор готовых инструментов. За много лет скопилось множество инструментов для обработки XML, например, библиотеки по обработке XML посредством XSL или целый класс SAX парсеров, XSD и DTD схемы для валидации и т.п.

    Совпадение синтаксиса обрабатывающих конструкций и результирующих конструкций. Другими словами, создавать XML на XML удобно, fest-шаблоны легко читать. Плюс решены все вопросы экранирования данных.

    Реализация

    Ковбойство. Я сам недавно узнал, что есть такой термин.

    До этого я был уверен, что самый надежный способ выполнения задачи - парное программирование и тесты. Тесты, как всегда, себя оправдали, а вот парному программированию нашлись альтернативы.

    Отличие этой задачи от типичной: был известен шаблон и результирующий HTML, который этот шаблон должен выдавать. Мы с Костей (Frontend разработчик почты) начали писать свои реализации. Раз в неделю мы сравнивали замеры скорости трансформации.

    Мы выбрали два разных подхода: он компилировал шаблон в функцию, а я - в структуру. Пример самой простой структуры:

    ...", 04 {action:"value"}, 05 "json.value" 06 ]

    Вторая строка означает начало шаблона. Третью надо просто отдать браузеру. Четвертая говорит, что пятую надо исполнить как JavaScript и результат исполнения отдать браузеру.

    01 [ 02 {action:"template"}, 03 "....”, 04 {action:"if"}, 05 "json.value", 06 "true", 07 "false" 08 ]

    Вариант немного сложнее. Четвертая строчка означает, что пятую надо исполнить и если результат истина или ложь, то отдать шестую или седьмую строку соответственно.

    Вариант с функцией особо пояснять не надо.

    01 function template(json){ 02 var html = ""; 03 html += "…"; 04 html += json.value; 05 return html; 07 }

    Забегая вперед, скажу, что его вариант оказался быстрее. Некоторое время мы шли почти ровно, но вариант со структурой уперся в потолок намного раньше.

    Чтобы понимать, что дал такой подход: моя первая реализация выполняла задачу за 200ms. Когда мы выжали все, что можно, а потом соединили лучшее из двух наших программ, то получили 3ms.

    Если описать текущую реализацию кратко, то мы циклы транслируем в циклы, условные операторы в условные операторы и т.д.

    Fest:foreach for(i = 0; i < l; i++) {} fest:if if(value) {} fest:choose if(value) {} else {}

    Нет сужений контекста. Да, это ограничение, но зато нет накладных расходов на ограничение контекста, а самое главное, что, как только сужаешь контекст, сразу возникает задача достать что-то из глобального контекста или из контекста уровнем выше.

    Важно, что шаблоны транслируются в JS-функцию, которая работает в режиме strict mode. Это не дает верстальщикам шансов написать код, который приведет к утечкам памяти.

    Везде, где нужна логическая работа с данными, доступен JavaScript.

    _javascript_

    Все конструкции, которые предполагают исполнение JavaScript, оборачиваются в try catch.

    Все конструкции, которые предполагают вывод в HTML после выполнения JavaScript, по умолчанию проходят HTML escape.

    json.name
    try { html += __escape(json.name) } catch(e) {}

    С самого начала разработка шаблонизатора ведется в открытом виде.
    https://github.com/mailru/fest

    Возможности интеграции

    С одной стороны, v8 - это только библиотека, которая позволяет интерпретировать JavaScript. Сама по себе она кажется бесполезной – никакого доступа к системе. Но, с другой стороны, она легко прикручивается к другим языкам.

    Имея нулевой опыт программирования на Cи и Perl, я сделал тестовые примеры на обоих языках. Плюс на текущий момент у нас есть связка с Python.

    Ну и, конечно, NodeJS для прототипов и браузеры - среды, где JavaScript шаблоны работают из коробки.

    Условия, близкие к боевым

    Получив 3ms, я пошел к сервер-сайд программистам. На вопрос, сколько у меня есть времени на запрос, который отдает список писем пользователя, они сказали: не больше 4ms. У меня уже было 3ms на трансформацию, надо было пробовать.

    Список писем у нас отдает наш собственный http-сервер, написанный на Cи. Получение данных - операции, которые не конкурируют за процессор, поэтому их не замеряли. Остановились на подготовке данных к трансформации и на самой трансформации.

    По историческим причинам наш http сервер хранит данные в плоском хеше.

    Msg_length = 5 msg_1_title = “letter” msg_1_Unread = 1

    Так как мы говорим о JavaScript, то первое, что приходит на ум, - это JSON

    Msg = [ {title: “letter”, Unread: true} ]

    Мы взяли строку с плоским хешом, поместили ее в память и стали добиваться результата, когда при трансформации шаблона в v8 JavaScript оперировал с JSON.

    Вариантов перебрали много. Пробрасывать объект, пробрасывать строку и парсить ее на JavaScript, пробрасывать строку и пропускать ее через JSON.parse.

    Как ни странно, самым быстрым оказалось преобразовать плоский хеш в строку, которая совпадает с JSON, и в v8 отдать строку

    “template([ {title: \“letter\”, Unread: true} ])”

    Но, несмотря на все, мы уперлись в 6ms при трансформации 2ms. Все были готовы сдаться. Я все же решил взять исходные данные, строку с плоским хешом и, используя тот же скомпилированный шаблон, получить нужный HTML на NodeJS.

    Получил 4ms. Когда пришел с этой цифрой к нашим сишникам, честно говоря, ожидал фразы “Классно, но NodeJS писать у нас нет ресурсов” Но вместо этого услышал “Если NodeJS может за 4ms, значит мы тоже сможем!”.

    Именно в этот момент я понял - мы доведем это до продакшена. Появилось второе дыхание!

    Решение оказалось простым. Раз мы 67% времени теряем на подготовке данных, а данные в принципе у нас уже есть, надо выкинуть подготовку данных.

    Мы пробросили в v8 фукцию __get(‘key’). Таким образом, мы из v8 забирали данные напрямую из хеша нашего http сервера. Нет конвертации данных в нужный формат. Нет преобразования этой строки в объект внутри v8. Мы вышли на 3ms и имели запас 1ms.

    Почти продакшен

    Итак, выглядит все замечательно, но мы еще и близко не были на продакшене. Чешутся руки попробовать.

    Берем отдельный сервер, поднимаем на нем версию http сервера, который работает с v8, и дублируем реальные запросы на него. Оставляем на 30 часов одно ядро 2.2 ГГц Xeon.

    10 000 000+ хитов 1.6ms среднее время трансформации 992 422 10% между 2 и 5ms 208 464 2% между 5 и 10ms 39 649 0,4% больше 10ms

    Только 12% были больше 2ms. v8 стабильно ведет себя по памяти.

    Продакшен

    Я пришел с последними цифрами к заместителю технического директора, сказав, что v8 готов к продакшену, надо сделать отдельный небольшой проект, который, если что, можно и забыть в случае неудачи. В ответ получил «цифры хорошие, отдельный проект, провал которого не страшен, - это правильно, но ты правда хочешь запустить v8? Начни с главной страницы Mail.Ru». Вопрос поставлен правильно – либо мы делаем дело, либо развлекаемся в сторонке.

    Верстка главной страницы на fest заняла три дня. Выключили один сервер из балансера, залили туда версию с v8 и продублировали запросы. Все выкладки будут происходить в контексте одного демона/ядра.

    Всегда детально выясняйте, что показывают ваши графики. Мы пустили на тестовый сервер половину нагрузки. Потребление процессора было в три раза выше обычного. Выглядело как провал, проигрыш по ресурсам в шесть раз по сравнению с текущим шаблонизатором.

    Стали смотреть. Тут я немного расскажу про архитектуру главной. На ней собирается информация от разных проектов. Собирает ее внутренняя разработка, мы ее называем RB. Из 165кб, которые генерируются для отдачи главной, 100кб собирает RB. И происходит следующее: RB отдает куски HTML через http сервер в v8, v8 конкатенирует их со своими строками, а результат возвращает все это обратно в http-сервер.

    Налицо двойной проброс данных. Сделали оптимизацию. Теперь v8 вместо построения одной большой строки, включающей в себя данные от RB, отдает данные сразу в http-сервер.

    Push_string(‘foo’); __push_rb(id); __push_string(‘bar’);

    Как плюс, нет конкатенации строк на v8, нет двойного проброса RB из сервера в v8 и обратно, а самое главное, любой проброс данных - это конвертация из utf-8 в utf-16 и обратно. V8 все хранит в utf-16.

    Был профит, ресурсы потреблялись в два раза больше, чем обычно, а не в три. Т.е. мы все еще проигрывали в четыре раза, хотя вроде бы выжали все до капли.

    А теперь поучительная часть. Я интереса ради взял нагрузку, которую мы тестировали, умножил на два, на количество демонов на машине и на количество машин. Получил 440 000 000 хитов. При этом у нас в сутки 110 000 000 хитов. Закрались смутные сомнения.

    Пошли смотреть логии. Оказалось, что на каждый запрос с нагрузкой мы получали три запроса с отчетами в логи для статистики! Реальная нагрузка на один http-сервер в четыре раза ниже той, на которой тестируемся мы!

    На следующее утро мы раскатили версию главной страницы с v8.

    Данные на сегодня:
    Размер отдаваемого HTML, который генерирует v8 65кб.
    Время, работы v8 на запрос 1ms.
    В среднем v8 требует 40MB на контекст.

    Пара уточнений

    Все, кто думают про v8, натыкались на статью Игоря Сысоева

    Крэйга Батлера, "Станет ли когда-нибудь server-side Javascript модным среди разработчиков", лишний раз убеждаешься, что люди воспринимают JavaScript исключительно однотипно. Большинство девелоперов рассматривает его сугубо в контексте браузера. Во многом потому, что существует определённая путаница между самим языком и DOM’ом браузера. DOM интерфейс - это, собственно, и есть то место, где JavaScript девелоперы проводят большую часть своего рабочего времени. Там же можно найти подтверждение ещё одному факту - многие люди терпеть не могут JavaScript. Хотя я всё равно уверен, что те люди, которые ценят лучшие качества JavaScript и закрывают при этом глаза на его недостатки, вряд ли удивлены тому, что JavaScript собирается потихоньку перебираться на выполнение сервером. Скорее всего они еще и рады этому. И, поверьте, это только начало!

    Итак, где же серверный JavaScript можно найти сейчас? Jaxer – это фреймворк и сервер для разработки веб приложений на JavaScript. Серверный API не страдает от недостатка предоставляемых возможностей, включая доступ к файлам, базам данных и сетевым сокетам. Граница между применением серверных и пользовательских скриптов достаточно размыта, к примеру, с помощью тех же серверных скриптов можно манипулировать DOM’ом веб-странички. Такие скрипты придают вашему HTML коду толику ASP-стиля. var nme = document.createTextNode("Hello my name is Jaxer."); var para = document.getElementById("name"); para.appendChild(nme); В данном случае у атрибута Runat может быть три значения – server, both , и server-proxy . Если назначить значение server, скрипт выполняется ещё до отправки страницы браузеру. Иначе его обработка происходит уже на клиентской стороне. Если установлено значение server-proxy, функция может быть вызвана из client-side скриптов по имени, но будет проксироваться с помощью Ajax на свой server-side эквивалент. Helma - это еще один фреймворк для написания JavaScript скриптов, выполняемых на стороне сервера. Helma имеет шаблонную систему, которая помогает избежать смешивания server-side и client-side кода. Здесь, вместо того, чтобы прописывать действия JavaScript, которые затем рендерят темплейт, вы вводите данные в сам процесс рендеринга. Каждый HTTP запрос, таким образом, инициирует выполнение сконфигурированного действия. Вот пример шаблона, или, если использовать Helma-жаргон, "скина", названный "hello": А вот action, которые рендерит его: res.data.name = "Helma"; this.renderSkin("hello"); Судя по теме в Википедии, есть немало других примеров “серверного” JavaScript . Почти во всех из них используется Rhino или SpiderMonkey для выполнения скриптов. Серверный JavaScript. Насколько это всё серьёзно? Реализации выполнения скриптов JavaScript на сервере, как видим, уже начинают появляться, но, в любом случае, по популярности им, так или иначе, очень далеко до повсеместного использования PHP. Отметим, что это вполне справедливо, ведь server-side JavaScript в настоящее время ограничен своим фреймворком. Такие JavaScript скрипты, написанные в одной среде вряд ли могут быть портированы из-за отсутствия стандартного API. Впрочем работа над этой проблемой уже началась в рамках ServerJS Group . Да и проекты типа jslibs также должны посодействовать её решению. Отсутствие подходящего хостинга также является острым вопросом, хотя Jaxer и AppJet и представляют свои собственные хостинг-платформы, а Helma приложения можно разместить на любых поддерживающих Java хостинг-решениях. После того, как проблема создания стандартной библиотеки будет решена, я уверен, мы увидим, что хостинг-поддержка будет улучшаться и расширяться и вы сами будете требовать у вашего хостера "mod_javascript" поддержку. Наконец, JavaScript имеет более чем достаточно шероховатостей и недостатков, заставляющих многих разработчиков сомневаться о целесообразности его использовании в качестве server-side решения. Но я думаю, что выход ECMAScript 3.1 должен серьёзно поколебать их уверенность в этом. Нетрудно заметить, что поддержка JavaScript стала появляться во многих платформах – и веб и десктопных, локальных и серверных. Будет ли серверная JavaScript поддержка предлагаться в хостинговых планах также повсеместно, как и PHP? Я думаю, это неизбежно.