Разбираем основные способы организации веб-приложения и чем они отличаются.
Время чтения: 9 мин
Открыть/закрыть навигацию по статье
- Кратко
- Многостраничные приложения
- Готовые веб-страницы
- Динамическая генерация HTML
- Client Side Rendering (CSR)
- Server side rendering (SSR)
- Static site generation (SSG)
Обновлено 14 октября 2022
Кратко
Все веб-приложения делаются с помощью одних и тех же технологий: HTML, CSS и JavaScript. Однако есть много способов организации работы приложения. Выбор способа зависит от цели приложения и пользовательского опыта, которого мы хотим добиться. Хотя основных подхода всего два: многостраничные приложения и Single Page Applications, каждый из них делится на подвиды.
Статические многостраничные приложения состоят из набора статичных страниц. Их просто разрабатывать, но если страниц становится много (сотни и тысячи), или данные на странице меняются, то придётся генерировать их на лету. Для этого нужно подключать сервер и писать дополнительный код. На каждый переход нужно генерировать и загружать новую страницу, а это занимает время.
Одностраничные приложения (SPA) дают возможность разрабатывать клиентские приложения со сложной логикой с помощью JavaScript. В этом подходе отрисовкой содержимого на странице управляет JavaScript. Переходы между экранами будут мгновенными, и пользователь сразу увидит результат своих действий. Однако такой подход создаёт новые проблемы. Как не загружать в браузер слишком много кода?
Как обеспечить хорошую производительность? Где рендерить приложение: только на клиенте или на сервере?
Разработка таких приложений часто сложнее, так как может потребовать знания различных инструментов и фреймворков.
Многостраничные приложения
Многостраничные приложения – это набор статичных веб-страниц, которые связаны между собой с помощью ссылок. При клике на ссылки происходит переход между страницами, что ведёт к полному обновлению страницы в браузере. Это одно из наиболее значимых отличий от SPA, о нем поговорим отдельно.
Для начала выделим два основных вида многостраничных приложений:
- Набор готовых свёрстанных страниц, которые лежат на сервере и вместе с ними находятся и другие статичные файлы (CSS, JavaScript и картинки). Сервер отдаёт эти файлы по заранее настроенным путям.
- Динамическая генерация HTML на сервере. Чаще всего такое решение можно встретить на языках программирования PHP, Python и Ruby. При каждом запросе сервер запускает скрипт генерации HTML-страницы. Скрипт может взять данные из базы данных, произвести вычисления и собрать готовый HTML-код страницы.
Готовые веб-страницы
Подходят, если нужно собрать несколько связанных страниц, которые, по большей части, будут содержать статичную информацию, с которой пользователь может мало взаимодействовать. Например, лендинг – это веб-сайт, который представляет информацию о компании, товарах или продукте.
первая программа на с++
Разработка при таком подходе обычно самая простая. Рядом складываются несколько html-файлов, в которых содержится вся необходимая вёрстка и дополнительные CSS/JavaScript файлы, подключённые к странице. В продвинутом варианте можно переиспользовать части кода с помощью шаблонизаторов (например, Pug) и собрать сайт по кусочкам используя сборщики (Gulp, Rollup, Webpack и др.). В результате на сервер попадёт набор статичных файлов, которые будут раздаваться с помощью веб-сервера (Nginx, Apache).
Преимущество такого подхода — это отличная производительность. Статичные страницы и файлы легко кэшировать с помощью браузера, CDN или Service Worker.
Динамическая генерация HTML
Динамическая генерация HTML страницы часто использовалась до изобретения Single Page подхода. Так до сих пор работает большинство форумов, интернет-магазинов, а так же большие приложения, как Facebook или ВКонтакте.
Особенность этого подхода в использовании серверных языков программирования (например, PHP или Ruby), чтобы генерировать итоговый HTML страницы, собирая его из разных частей и обогащая данными.
Например, пользователь перешёл на страничку со списком друзей:
- Сервер получает запрос.
- Идёт в базу данных, выбирает список друзей и вспомогательные данные.
- По шаблону собирает HTML.
- Отправляет HTML в виде ответа на запрос.
Пользователь сразу получает сгенерированную страницу со списком друзей. Если добавить новых друзей и зайти на страничку ещё раз, то результат будет другой, ведь список друзей изменился.
Использование сервера для генерации содержимого позволяет не нагружать клиентский код сложной логикой, а значит итоговый размер страницы будет меньше. При этом статичные части приложения и целые куски страниц можно так же легко кэшировать.
При всех плюсах многостраничных приложений, все они страдают от одного главного недостатка: при переходе между страницами браузер полностью обновляет содержимое, из-за чего нельзя создать полноценный опыт взаимодействия «как в приложении»: незакэшированным страницам нужно время для загрузки, а значит не будет мгновенного перехода; будет сбиваться положение полосы прокрутки и т.д.
В стремлении решить эти проблемы и создать полноценный опыт приложений веб-разработчики изобрели одностраничные приложения.
Single page applications (SPA)
Одностраничные приложения (сокращённо SPA) состоят из одной страницы, а всю остальную работу (создание содержимого, переход между экранами и получение данных) выполняет JavaScript. Такой подход позволяет создать полноценный опыт приложения: переходы между экранами происходят мгновенно, можно давать пользователю визуальный ответ, пока данные загружаются асинхронно с помощью API.
Разработка одностраничных приложений имеет богатую экосистему: фреймворки и библиотеки для создания интерфейсов, подходы к разработке, архитектурные паттерны. Одностраничные приложения делятся по месту начальной отрисовки страницы: в браузере (client side rendering) или на сервере (server side rendering).
Client Side Rendering (CSR)
В таком приложении вся отрисовка содержимого страницы, включая первую, происходит в браузере. Пользователь должен сначала загрузить весь JavaScript, и только после этого что-то сможет отрисоваться. До этого момента страница будет либо пустой, либо будет содержать статическую заглушку-лоадер.
Это самым простой способ отображения SPA. Он подходит для небольших приложений, так как оно быстро загружается и запускается. Если кода много и приложение получается большим, пользователи со слабыми устройствами или медленным интернетом могут не дождаться загрузки и уйти.
SPA не работает без JavaScript. Если по какой-то причине пользователь отключил его в своём браузере, то одностраничное приложение не запустится вовсе.
Это требование особенно важно в контексте того, как поисковые сервисы индексируют SPA. Раньше поисковики не умели выполнять JavaScript и потому одностраничные приложения не попадали в результаты поиска. Сейчас ситуация изменилась, поисковые сервисы умеют исполнять JavaScript, но статические сайты до сих пор индексируются лучше.
Server side rendering (SSR)
Чтобы пользователь не смотрел на пустую страницу в ожидании загрузки приложения, можно отдавать ему сгенерированный сервером HTML. Таким образом пользователь сразу получит ожидаемую страничку и начнёт её просматривать, пока основное приложение загружается и запускается.
Такой подход называется серверным рендерингом. Он помогает улучшить и пользовательский опыт, и позицию сайта в поисковиках. Поиск Google и Яндекса умеет исполнять JavaScript, но сайтам со статическим контентом отдаётся предпочтение.
Главное отличие такого подхода от рендеринга на клиенте — это сервер, который занимается рендерингом. Чаще всего это готовое решение на базе Node.js. Многие SPA-фреймворки имеют проверенные решения для быстрого старта приложения с серверным рендерингом. Например, Next.js для React или Nuxt для Vue.
Своё решение для SSR — непростая задача. Приходится учитывать множество факторов: как и куда сходить за данными, как правильно отрисовать приложение и много других деталей.
Дополнительная серверная часть может потребовать и дополнительной инфраструктуры, из-за чего разработка приложения с server side rendering будет сложнее.
Static site generation (SSG)
Статические генераторы сайтов позволяют создать приложение, используя статические данные и шаблонизатор. На выходе получается многостраничный сайт. Отличие от классического многостраничного сайта в том, что большинство инструментов для статической генерации поддерживают SPA-фреймворки. Это позволяет объединить плюсы статического и SPA мира.
Самый распространённый пример SSG — это персональный блог. У нас есть тексты статей, а с помощью шаблонизатора эти статьи превращаются в готовые html-странички. Эта страничка и сама Дока, которую вы сейчас читаете, разработана с помощью статической генерации.
Когда говорят об SSG, то часто упоминают Jamstack. Слово Jamstack — это объединение первых букв от слов JavaScript, API, Markdown и слова stack, что в данном случае означает «набор технологий». Технически Jamstack это подход к разработке сайтов и приложений основанный на перечисленных технологиях. Источником данных выступает Markdown (например текст статей блога), JavaScript вместе с React «оживляет» приложение, а с помощью API можно запрашивать наши данные.
Jamstack хорошо подходит для создания сайтов, наполненных статичным контентом, а SPA-фреймворки помогают создать хороший пользовательский опыт, получая при этом плюсы статических сайтов.
Progressive Web Applications (PWA)
PWA это набор технологий, который позволяет превратить сайт в полноценное приложение. Такое приложение можно установить из браузера себе на компьютер или на телефон. Эта трансформация позволяет веб-приложениям функционировать почти как нативные, например, работать в офлайне или присылать уведомления.
В PWA можно превратить практически любой сайт, главное чтобы он соответствовал требованиям и поддерживал необходимые технологии (Service Worker, HTTPS и так далее).
Конечно такое приложение нельзя считать полноценно нативным, здесь имеются все те же ограничения в веб-технологиях, но это отличная возможность превратить свой сайт в устанавливаемое приложение.
Заключение
Как спроектировать и написать полноценную программу
«Мне кажется, что понимаю функциональное программирование на базовом уровне, и я даже писал простые программы, но как мне создать полноценное приложение, с реальными данными, с обработкой ошибок и прочим?»
- Я буду описывать только один сценарий, а не всё приложение. Надеюсь, будет очевидно как расширить код при необходимости.
- Это намеренно очень простая инструкция без особых ухищрений и продвинутой техники, ориентированная на поточную обработку данных. Но если вы начинающий, я думаю, вам будет полезно иметь последовательность простых шагов, которые вы сможете повторить и получить ожидаемый результат. Я не утверждаю, что это единственный верный способ. Различные сценарии будут требовать различных подходов, и конечно с ростом собственной экспертизы вы можете обнаружить, что эта инструкция слишком простая и ограниченная.
- Чтобы облегчить переход с объектно-ориентированного проектирования, я постараюсь использовать знакомые концепции такие как «шаблоны», «сервисы», «внедрение зависимости» и т.д., а также объяснять как они соотносятся с функциональным подходом.
- Инструкция также намеренно сделана в некоторой степени императивной, т.е. используется явный пошаговый процесс. Я надеюсь, этот подход облегчит переход от ООП к ФП.
- Для простоты (и возможности использовать F# script) я установлю заглушку на всю инфраструктуру и уклонюсь от взаимодействия с UI напрямую.
Обзор
- Преобразование сценария в функцию. В первой статье мы рассмотрим простой сценарий и увидим как он может быть реализован с помощью функционального подхода.
- Объединение небольших функций. В следующей статье, мы обсудим простую метафору об объединении небольших функций в более крупные.
- Проектирование с помощью типов и типы ошибки. В третьей статье мы создадим необходимые для сценария типы и обсудим специальные типы для обработки ошибок.
- Настройка и управление зависимостями. В этой статье мы поговорим о том, как связать все функции.
- Валидация. В этой статье мы обсудим различные пути реализации проверок и преобразование из опасного внешнего мира в теплый пушистый мир типобезопасности.
- Инфраструктура. В этой статье мы обсудим различные компоненты инфраструктуры, такие как журналирование, работа с внешним кодом и т.д.
- Предметный уровень. В этой статье мы обсудим, как предметно-ориентированное проектирование работает в функциональном мире.
- Уровень представления. В этой статье мы обсудим, как вывести в UI результаты и ошибки.
- Работа с изменяющимися требованиями. В этой статье мы обсудим, что делать с изменяющимися требованиями и как они влияют на код.
Приступим
Давайте возьмем очень простой пример, а именно обновление некоторой информации о клиенте через веб-сервис.
- Пользователь отправляет некоторые данные (идентификатор пользователя, имя и адрес почтового ящика).
- Мы проверяем корректность имени и адреса ящика.
- В базе данных в соответствующей пользовательской записи обновляются имя и адрес почтового ящика.
- Если адрес почтового ящика изменен, отправляем на этот адрес проверочное письмо.
- Выводим пользователю результат операции.
Вот диаграмма составных частей процесса:
Но это описание только успешного варианта событий. Реальность никогда не бывает столь простой! Что произойдёт, если идентификатор пользователя не найдется в базе данных, или почтовый адрес будет некорректный, или в базе данных есть ошибка?
Давайте изменим диаграмму и отметим всё, что может пойти не так.
Как видим, на каждом шаге сценария могут возникнуть ошибки по различным причинам. Одна из целей серии этих статей — объяснить как элегантно управлять ошибками.
Функциональное мышление
Теперь, когда мы разобрались с этапами нашего сценария, как его реализовать с помощью функционального подхода?
Сначала обратимся к различиям между исходным сценарием и функциональным мышлением.
В сценарии мы обычно подразумеваем модель запрос-ответ. Отправляется запрос, обратно приходит ответ. Если что-то пошло не так, то поток действий завершается и ответ приходит «досрочно» (прим. переводчика: Речь исключительно о процессе, не о затраченном времени.).
Что я имею ввиду, можно увидеть на диаграмме упрощенной версии сценария.
Но в функциональной модели, функция — это черный ящик с входом и выходом, как здесь:
Как мы можем приспособить наш сценарий к такой модели?
Однонаправленный поток
Во-первых, вы должны осознать, что функциональный поток данных распространяется только вперед. Вы не можете вернуться «досрочно».
В нашем случае, это означает, что все ошибки должны передаваться до окончания сценария по альтернативному пути.
Как только мы это сделаем, у нас появится возможность превратить весь поток в единственную функцию — чёрный ящик:
Конечно, если вы загляните внутрь этой большой функции, то обнаружите, что она сделана из («является композицией» в терминах функциональной методологии) меньших функций, по одной на каждый этап сценария, соединенных последовательно друг за другом.
Управление ошибками
На последней диаграмме изображены один успешный выход и три выхода для ошибок. Это проблема, так как функции могут иметь только один выход, а не четыре!
Что мы можем с этим сделать?
Ответ в том, чтобы использовать тип Объединение, где каждый вариант представляет один из возможных выходов. Тогда у функции действительно будет только один выход.
Вот пример возможного определения типа для вывода результата:
type UseCaseResult = | Success | ValidationError | UpdateError | SmtpError
И вот переделанная диаграмма, на которой изображён единственный выход с четырьмя различными вариантами, включёнными в него:
Упрощение управления ошибками
Это решает проблему, но наличие ошибки для каждого шага — это хрупкая и мало пригодная для повторного использования конструкция. Можем ли мы сделать лучше?
Да! Нам в действительности нужны только два метода. Один для успешного случая и другой для всех ошибочных:
type UseCaseResult = | Success | Failure
Этот тип очень универсальный и будет работать с любым процессом! Собственно вы скоро увидите, что для работы с этим типом мы можем сделать хорошую библиотеку полезных функций, которая подойдет для любых сценариев.
Ещё один момент — в результате, который возвращает функция, совсем нет данных, только статус успех/неудача. Нам потребуется кое-что поправить, чтобы результат функции содержал фактический успешный или сбойный объект. Мы объявим успешный и сбойный типы как универсальные (с помощью параметров типов).
Наконец, наша итоговая, универсальная версия:
type Result = | Success of ‘TSuccess | Failure of ‘TFailure
На самом деле, в библиотеке F# уже есть подобный тип. Он называется Choice. Для ясности я всё же продолжу использовать в этой и последующих статьях созданный ранее тип Result. Мы вернемся к этому вопросу, когда подойдём к более серьезным задачам.
Теперь, снова взглянув на сценарий с отдельными шагами, мы увидим, что должны соединить ошибки каждого шага в единый «сбойный» путь.
Как это сделать — тема следующей статьи.
Итог и методические указания
Итак, у нас есть следующие положения к инструкции:
- Каждый сценарий равносилен элементарной функции.
- Возвращаемый тип сценарной функции — объединение с двумя вариантами: Success и Failure.
- Сценарная функция строится из ряда небольших функций, которые представляют отдельные шаги в потоке данных.
- Ошибки всех этапов объединяются в единый путь ошибок.
- functional programming
- функциональное программирование
- проектирование
- f#
Источник: habr.com
Превращаем смартфон в пульт управления роботом с приложением RoboCam
Во всех предыдущих статьях про приложение RoboCam я описывал, как с его помощью управлять роботом от первого лица. Но иногда управление от первого лица нам не нужно, а нужно лишь превратить смартфон в пульт управления. В последней версии приложения RoboCam появилась такая возможность.
Делаем управление Arduino-роботом от первого лица
Последняя версия приложения RoboCam позволяет управлять не только роботами EV3, но и роботами, построенными на таких платформах, как Arduino, Raspberry Pi и других аналогичных, где имеется возможность напрямую работать с данными поступающими и отправляемыми через Bluetooth. Теперь команды приложения RoboCam, вы сможете обрабатывать так, как пожелаете.
Создание блоков для LEGO Mindstorms EV3
С помощью дополнительных блоков можно существенно расширить возможности своей программы, созданной в среде разработке LEGO Mindstorms EV3. Читая эту статью вы изучите анатомию блока и научитесь создавать свои собственные блоки.
RoboCam – управляем роботом от первого лица с клавиатуры компьютера
В новой версии приложения RoboCam добавлена поддержка физической клавиатуры, то есть теперь у вас появилась возможность управлять роботом LEGO Mindstorms EV3 от первого лица со стационарного компьютера или ноутбука. В этой статье я опишу, как настроить приложение RoboCam, чтобы использовать новую возможность, а также напишу, что ещё появилось в новой версии.
Импорт, экспорт, копирование и отправка настроек роботов в приложении RoboCam
В прошлой статье, посвящённой программе RoboCam, было описано, как управлять роботом EV3 от первого лица. Но конструкции роботов и механизмов могут быть разными и для каждого необходимо своё уникальное управление. Если вы разработали нового робота, то встаёт вопрос, как поделиться сделанными настройками с другими людьми, перенести их на другой смартфон или просто копировать? Решение есть. В новой версии приложения RoboCam добавлены функции импорта, экспорта, копирования и отправки настроек роботов.
Управление роботом LEGO Mindstorms EV3 от первого лица
Роботом, собранным из конструктора LEGO Mindstorms EV3, вы легко можете управлять дистанционно от первого лица. Для этого вам дополнительно понадобится два смартфона, с установленным приложением RoboCam на один из них. Давайте познакомимся подробнее с приложением RoboCam и научимся им пользоваться.
Open Roberta Lab – новый способ Scratch-подобного программирования роботов Lego Mindstorms EV3
Open Roberta Lab или открытая лаборатория Роберты, робо-леди, которую вы видите на картинке – это облачная среда программирования роботов Lego Mindstorms EV3 очень похожая на Scratch 2, но не требующая установки на компьютер. Ваши готовые программы вы можете протестировать здесь же на симуляторе. Для программирования и использования симулятора вам достаточно иметь браузер и доступ в интернет.
Защита приложений Windows от копирования и уменьшение размера с помощью ASProtect и ASPack
При распространении приложений перед разработчиками часто встают вопросы о защите кода программы от взлома и анализа, об уменьшении дистрибутива при распространении через Интернет, о том с помощью чего делать ключи для платно распространяемых программ. В статье мы рассмотрим возможности инструментов ASPack и ASProtect, которые помогут вам решить эти вопросы.
Программируем робота LEGO Mindstorms EV3 на Java
С помощью чего только не программируются роботы LEGO Mindstorms EV3. Поддерживается большое количество языков программирования на любой вкус. Но сегодня я хочу рассказать вам, о самом, на мой взгляд, удобном и богатом, в плане возможностей, способе программирования роботов LEGO Mindstorms EV3. Удобный, потому что разрабатывать можно в среде разработки Eclipse на языке Java, а богатый, потому, что виртуальная машина Java для EV3, которая называется leJOS, поддерживает не только стандартные возможности EV3, но даёт и гораздо больше.
Программирование робота Lego Mindstorms EV3 с помощью Scratch 2.0
Если вам нравится графическая среда программирования Scratch 2.0, то вам необязательно отказываться от неё для программирования роботов Lego Mindstorms EV3. Достаточно лишь установить и настроить нужное программное обеспечение, о чём и будет написано в этой статье.
Создание дистрибутива Windows приложения в Inno Setup
Для удобства установки ваших программ на компьютеры пользователей вам понадобится создание дистрибутива. Сегодня я хочу рассказать об очень мощном и бесплатном инструменте для создания дистрибутивов для ОС Windows – Inno Setup.
Как сделать пошаговую инструкцию LEGO (создание инструкции в LPub)?
В первой статье мы научились создавать виртуальную модель с помощью программ MLCad и LSynth. В этой второй статье мы рассмотрим, как создать полноценную пошаговую инструкцию по сборке робота LEGO Mindstorms Education EV3 с помощью программы LPub.
Как сделать пошаговую инструкцию LEGO (создание модели в MLCad + LSynth)?
Для создания пошаговых инструкций для сбора моделей из конструктора LEGO любой линейки можно воспользоваться программами LDraw. Всего будет две статьи, посвящённых программам LDraw, где я опишу, как создать полноценную инструкцию по сборке робота LEGO Mindstorms Education EV3. В этой первой статье, вы познакомитесь с программами MLCad и LSynth и научитесь создавать виртуальную копию вашей модели.
Тестирование веб сервисов или как пользоваться SoapUI
Допустим, вы интегрируете системы, используя веб-сервисы, или ваши клиентские приложения взаимодействуют с сервером посредством веб-сервисов, в этом случае вам просто необходимо использовать инструмент SoapUI для тестирования веб-сервисов и клиентов. Работа с программой SoapUI очень проста и позволяет воочию увидеть передаваемые и получаемые данные. Кроме того вы сможете провести нагрузочное тестирование вашего веб-сервиса и симулировать работу веб-сервиса.
Тест производительности программы в Delphi XE3
При разработке приложений часто возникает потребность оптимизировать код таким образом, чтобы он работа быстрее. Чтобы это сделать, зачастую мало внимательно изучить код. Ведь медленно работать может сторонняя библиотека или компонент. Да и программный код может быть очень объёмным. Давайте разберёмся, как можно проанализировать производительность программы в Delphi XE3.
Программа FormatFactory или как конвертировать видео и аудио
Периодически каждому из нас приходится копировать или передавать аудио и видео файлы на разные устройства. При этом размер и качество изображения или звука играют значение. Чтобы подготовить видео или аудио для определённого девайса или поменять кодек, есть отличное средство – программа FormatFactory.
Подключение к рабочему столу Windows через VPN-подключение
В статье рассматривается настройка клиентского компьютера под управлением Windows 7, с которого должно быть установлено подключение к удалённому рабочему столу Windows. Здесь не рассмотрены настройки сервера и компьютера, к которому будет устанавливаться подключение.
Программа Unlocker
Довольно часто возникает ситуация, когда невозможно удалить или переместить файл из-за того, что он используется каким-то приложением. Разобраться с тем, какое именно это приложение или программа бывает подчас очень сложно, но и оставлять лишний мусор на компьютере также нежелательно. В таких ситуациях придёт на помощь маленькая утилита – Unlocker.
Как сделать загрузочную флешку Windows 7 или Windows 8
На сайте Microsoft была отличная статья о том, как сделать загрузочную флешку с дистрибутивом Windows 7, но к сожалению она пропала. Здесь я попытался восстановить эту статью. Кстати, аналогичным образом мне удалось сделать загрузочную флешку с дистрибутивом Windows 8. Для создания загрузочной флешки вам понадобится только установочный диск Windows 7 или Windows 8 или образ диска, компьютер под управлением Windows и, собственно, флешка подходящего размера (размер должен быть больше размера установочного диска).
Создаем прокси-сервер (socks)
Если вам нужен прокси, то ниже вы найдёте, по моему мнению, лучший способ создания прокси. Для чего нужен прокси-сервер? Очень просто, вот несколько возможных ответов на этот вопрос:
Источник: www.proghouse.ru