Пошаговый алгоритм создания архитектуры PHP-сайта / Habr
Дисклеймер: этот текст меня заставило написать практически полное отсутствие вменяемых материалов по данной теме на русском языке. Этому плохо учат в вузах, об этом молчат самоучители PHP и официальный мануал, хотя это самый важный момент при разработке программы — создание архитектуры. Плохая архитектура может убить ваш проект, так что он никогда не увидит свет. Хорошая архитектура даже при плохом коде, а кто из новичков пишет хороший код, способна творить чудеса.Разработка архитектуры должна начинаться в тот момент, когда вам в голову пришла идея «хочу сайт такой-то» или кто-то вложил идею «нужен сайт такой-то». К сожалению, большинство разработчиков сразу приступают к написанию кода, причём даже не того, какого нужно.
Прежде чем писать код, вооружитесь листочком с ручкой, вордпадом, вордом, райтером или даже вашим редактором кода и выполните пару шагов.
Шаг 1. Постановка главной задачи
Архитектура разрабатывается сверху вниз. Что это значит? Это значит, что сперва вы продумываете самые главные подсистемы, прежде чем приступить к обслуживающим их или более техническим.
Многие программисты начинают разработку сайтов с роутеров, подключения к БД, обработки ошибок, что приводит к необходимости переписывания их кода в будущем или обильной вставке в код костылей, как только они натыкаются на то, что не смогли предусмотреть.
Всё предусмотреть невозможно, для этого и нужно разрабатывать систему сверху вниз. Наличие работающих высокоуровневых классов практически автоматически определяет все необходимые требования к обслуге.
Это не единственный метод, но по опыт знаю, что самый оптимальный для тех, кто не чувствует себя, как рыба в воде среди паттернов проектирования или даже совсем про них не знает.
Итак, вам нужен блог, интернет-магазин, сайт стоматологической клиники.
Определитесь, что на вашем сайте самое главное, ради чего всё затевается.
Для блога — это, очевидно, записи. Для магазина — товары. Для сайта поликлиники — услуги.
Уже можем написать немного кода, с которого и начнётся разработка сайта:
class записи
{
}
или class товары {}, или class услуги{}
Это ваша главная подсистема. Сразу же можно написать, чем именно она будет управлять.
class запись
{
}
или class товар {}, или class услуга{}
Шаг 2. Определить, что ваша система умеет делать
Мы создали главную подсистему «записи». Следующий шаг: определить, что она будет уметь, чему мы хотим научить наш сайт.
Очевидно, она должна уметь создавать записи, удалять записи и получать записи.
Забудьте, что вы пишите код сайта, забудьте про пользователей, url-адреса, оформление страниц. Работайте с голыми данными: строками, числами, массивами, объектами.
Пишем код:
class записи
{
public function создать_запись() {}
punlic function удалить_запись() {}
public function получить_запись() {}
}
Шаг 3. Понять, с чем имеем дело
Что такое запись? Что такое услуга? Что такое товар? Для вас, как программиста — это просто совокупность данных. В третьем шаге определяем, что это за совокупность.
Не стремитесь предусмотреть всё, что понадобится когда-то в будущем. Берите самый-самый минимальный набор. Для этого мы и строим архитектуру приложения, чтобы в будущем её было легко нарастить.
Очевидно, запись — это заголовок и текст записи. Услуга и товар — название, описание и цена.
Компьютер — не очень умное создание, по сравнению с человеком, вы не сможете сказать ему: «а покажи-ка мне запись, ту, где про зелёного котёнка написано», поэтому ему всегда необходим какой-то уникальный код, чтобы он среди множества записей узнал именно ту, которую вы хотите.
Это либо порядковый номер (id), уникальный для каждой записи или некое, столь же уникальное, строковое значение.
Значит наша запись — это идентификатор записи (id), заголовок, текст.
Больше нам ничего не нужно.
Шаг 4. Определение необходимых знаний
Теперь для каждого действия системы нам нужно понять, что системе нужно знать, чтобы это действие выполнить.
Для действия «создать_запись» нужно знать заголовок и текст записи. Внутренний идентификатор нужен только компьютеру, поэтому пусть сам его и придумывает.
Для действий «удалить_запись» и «получить_запись» нужно знать только тот самый идентификатор записи, который был ей присвоен компьютером при создании.
class записи
{
public function создать_запись($заголовок, $текст) {}
punlic function удалить_запись($идентификатор) {}
public function получить_запись($идентификатор) {}
}
То, что получилось называется интерфейсом вашего класса/модуля/подсистемы.
Шаг 5. Определение результатов
Также, как мы узнали необходимые знания для выполнения того или иного действия, нужно понять, чем эти действия будут оканчиваться.
Если у компьютера всё получилось, то
- создать_запись: будет создана новая запись, а мы получим её идентификатор.
- удалить_запись: будет удалена конкретная запись, а мы получим сообщение ‘готово’
- получить_запись: получим нужную запись
Если у компьютера чего-то не получилось, то
- создать_запись: будет выброшено исключение.
- удалить_запись: будет выброшено исключение
- получить_запись: будет выброшено исключение
Для всех ситуаций, когда что-то не получилось поведение программы должно быть одинаковым во всех модулях/классах/подсистемах вашей системы. PHP предоставляет всего два варианта: trigger_error и throw new Exception. Можете придумать свой, но не стоит изобретать велосипеды, пока вы не научились ездить на существующих. throw new Exception — самый оптимальный вариант.
Читайте раздел «исключения» в официальном мануале.
Шаг 6. Снова с начала
В шаге первом, кроме создания системы управления записями, мы создали ещё класс и самой записи: class запись {}
Для неё нужно сделать тоже самое, что и для главной, те же самые шаги с 1 по 5.
Если вы всё сделали правильно, то у вас должно получиться что-то похожее.
class запись
{
public function получить_идентификатор() {}
public function получить_заголовок() {}
punlic function получить_текст() {}
public function изменить_заголовок($новый_заголовок) {}
public function изменить_текст($новый_текст) {}
}
Шаг 7. Пишем код
Теперь, когда всё создано можно приступать к кодированию. Если вы знакомы с PHP никаких проблем у вас не возникнет.
Сколько затратили времени? Совсем чуть-чуть, и ещё ощутите в будущем всюпользу от произошедшего.
То, что у вас получится в итоге скрывается под буквой M в страшной аббревиатуре MVC.
Заключение
Я не учёл много нюансов, их хватит на десять таких же статей, но базис для вашей разработки уже есть. Это — самые основы и это в любом случае лучше, чем мешать PHP с HTML в одном файле или плодить кучу функций по мере написания кода.
C M разобрались. Что касается V и C. Это тема для других статей. Поэтому вкратце. Если вы достаточно сообразительны, то другие статьи вам и не понадобятся.
C — это место, в котором система реагирует на действия пользователя. Вот там и нужно думать, что будет делать пользователь. Захотел пользователь создать запись в блоге, заполнил форму создания, а у вас уже всё готово, чтобы выполнить его команду. Захотел, прочитать запись и снова вы выполняете его просьбу в одну строчку. Там главная задача (шаг 1) — понять, что хочет пользователь.
V — изучите любой шаблонизатор: Smarty или Twig. Много споров ведётся про то использовать шаблонизаторы или нет, много убедительных доводов с той и с другой стороны. Правда в том, что для web-разработчика непростительно не уметь работать с шаблонизаторами. Поэтому осваивайте их, а потом уже откажетесь, если не понравится.
Как уже было отмечено выше, на русском языке почти нет достойный литературы на эту тему.
Единственную книгу, которую могу посоветовать прочитать: Стив МакКоннелл «Совершенный код».
Если кто-то знает другие материалы киньте в меня ссылочкой. С удовольствием прочитаю и буду рекомендовать новичкам.
Веб-разработка – с чего начать? / Habr
Недавно на сайте stack overflow увидел вопрос, в котором программист C++ спрашивал, что нужно начать изучать для того чтобы впоследствии стать веб-разработчиком. С его слов он начал с изучения php, но по совету знакомых переключился на яву, в какой-то момент открыл для себя ангуляр, в итоге в голове у него образовалась каша, и понимания в какую сторону двигаться не было. Именно для людей, которые только что пришли в веб я и решил поделиться это статьей, чтобы у них было примерное понимание, что тут есть.Любое веб приложение состоит из двух частей: бекенд и фронтэнд. Соответственно и программистов делят также, по сути это две несвязанные между собой касты разработчиков.
Бекэнд
Бекэнд — серверная часть приложения, которая не видна пользователям. Сюда относится: авторизация, хранение и обработка данных, email рассылки и тому подобное. Скажем так бекэнд это то, что под капотом. Языков программирования тут множество, вот самые распространенные из них:
• Php
• Asp net
• Java
• Python
• Ruby
• Node js
Советую выбрать один единственный, потому что с текущими требованиями к программистам для достижения уровня middle пройдет не менее нескольких лет. При выборе можно ознакомиться с вакансиями в вашем городе, посмотреть какие больше подходят, где больше платят и смотря из того какой язык в них требуется его и выбрать.
Сервер во многом используется для работы с данными. Поэтому нужно будет выучить как минимум бы одну из реляционных баз данных:
• Oracle
• MSSQL
• MYSQL
• Postgres
По сложности это примерно тоже, что и освоить язык программирования. Во всех перечисленных БД есть часть, которая одинакова везде – так называемый sql (язык запросов), а так же процедурный язык который в каждой базе свой. Так как sql все-таки един, а он основа всему, что связано с обработкой данных, то переход на другую базу данных, не является такой уж и проблемой. Поэтому выбрать для начала можно любую, но и тут бы я пошел по принципу анализа вакансий.
Лично я ставлю плюс в сторону изучения бекенда, так как навыки тут более статичны и изучив, что-то единожды вы сможете проработать на этом длительное время.
Фронтэнд
Фронтэнд – часть, работающая в браузере с которой непосредственно взаимодействует пользователь. Это динамические интерфейсы, меню, события по действию пользователя обмен данными с серверной частью, в общем, то, что происходит на клиенте.
Язык программирования тут один javascript. С одной стороны это несомненный плюс, так как после его изучения вам будут открыты все компании в вашем городе, которые занимаются веб разработкой, а сейчас этим занимаются многие. С другой стороны есть нюансы.
JavaScript на текущий момент времени имеет два стандарта, которые широко используются: ECMAScript 5 и ECMAScript 6. Разница между ними состоит в том, что в ECMAScript 5 отсутствует полноценное ОПП. В ECMAScript 6 оно есть, но поскольку этот стандарт появился относительно недавно, уже большая часть приложений написана на ECMAScript 5, в результате чего нужно будет освоить оба стандарта и как следствие два разных подхода к разработке.
Еще один момент, который нужно учитывать это то что один и тот же код, написанный на javascript может по- разному отрабатывать в разных браузерах и на разных ОС. С текущими требованиями к приложениям как правильно нужно будет писать так называемый кроссбраузерный код, то есть код, результат выполнения которого будет давать везде один и тот же результат. Конкретного манула по написанию такого кода нет, в этом случае в помощь вам форумы и окей гугл.
Описанные мною проблемные моменты решены в современных js фреймворках (например в таких как ангуляр и реакт). Но в проектах, которые написаны без использования фреймворков эти моменты остаются.
Лично для меня еще большим минусом является то, что здесь идет очень быстрое развитие трендов. Постоянно обновляются версии фреймворков, выходят новые библиотеки, и все сразу хотят начать их использовать. В общем, за сообществом не угнаться.
Фулстек
Уже из названия должно быть понятно, что данный тип разработчиков занимается разработкой обоих частей. Пытаться стать таким разработчиком не советую, поскольку выучить все мозгов не хватит в любом случае, да и большинство компаний уже пошли по пути разделения труда. Однако фулстек это то с чего нужно начать, чтобы сделать шаг в сторону бекенда или фронэнда. Разработав пару небольших приложений, вы поймете между ними разницу (а она действительно есть) и сможете определиться, какая из сторон вам ближе.
Я в свое время, чтобы определиться прочитал книгу «Создаем динамические веб-сайты», автор «Робин Никсон». Книга небольшая всего 500 страниц, но благодаря ней у меня сложилось общее представление о веб-разработке и я смело сделал выбор в сторону бекенда о чем до сих пор не жалею. Эту книгу я привел в качестве примера, можно взять любую другую это не принципиально.
Вот в принципе и все чем я хотел поделиться, желаю всем пришедшим в веб удачи и скорейшего освоения.
10 вещей, которые вы должны знать как веб-разработчик / Habr
Привет, Хабр! Представляю вашему вниманию перевод статьи «10 Things You Should Know As a Web Developer» автора Anuupadhyay.Написание тысячи строк кода и превращение в веб-сайт — одна из творческих и сложных вещей для веб-разработчиков. Если вы в этом деле новичок, увидели множество красивых веб-сайтов и подумали попробовать силы в этом, нам необходимо открыть глаза и рассказать о некоторых вещах, нужных веб-разработчику. Создание веб-сайта, который привлекает внимание пользователей, — это не только изучение различных языков программирования, это также изучение других концепций, таких как DevTools, форматы данных, тестирование, API-интерфейсы, аутентификация и многое другое. Здесь рассказывается о некоторых вещах, которыми должен овладеть веб-разработчик.
1. HTML / CSS / JS
Важным навыком, который каждый разработчик должен изучить в первую очередь, является знание этих трех основных строительных блоков, то есть HTML, CSS и JavaScript. Вы будете использовать HTML и CSS во «фронтенде» для интерфейсов. Щелкните правой кнопкой мыши на веб-браузере и выберите вариант просмотра источника страницы. Вы найдете структуру вашего сайта, где много HTML-тегов используются для различных целей.
CSS также используется в веб-интерфейсе, который определяет стиль, дизайн, макет и то, как элементы HTML должны отображаться на экране.
В настоящее время Javascript пользуется большим спросом и в отвечает за то, чтобы сделать ваши HTML-страницы динамичными. Javascript также поставляется с различными языками, такими как PHP, Python, ASP.Net, чтобы сделать ваш сайт более интерактивным. Если вы собираетесь специализироваться на Javascript, таком как MEAN Stack или MERN stack, вам следует углубиться в этот язык, потому что он будет вашим внешним и внутренним языком.
2. Git и Github
Git — одна из самых популярных систем контроля версий, которая используется в большинстве организаций. Скорее всего, вам нужно работать над этим контролем версий, если вы получите работу в качестве веб-разработчика. По этой причине следует потратить некоторое время на изучение Git и некоторых базовых команд, таких как клонирование, отправка в репозитории, создание запроса на извлечение, объединение веток и т. д.
Github — это сервис, где можно использовать свои репозитории Git для размещения кода. Github используется для совместной работы или, можно сказать, разрешает разработчикам работать вместе над их проектами.
3. Development Tools
Вы можете сделать много вещей, используя Development Tools, такие как отладка, редактирование элементов HTML, редактирование свойств CSS, проверка устройства, отслеживание ошибок JavaScript и т. д. Каждый разработчик должен знать об использовании различных вкладок (элементов, консоли, сети и многое другое) В DevTools, чтобы сделать их работу проще и быстрее. В зависимости браузера можно использовать любые DevTools, такие как Chrome DevTools, Firefox DevTools или другой браузер, который используете. Люди предпочитают использовать Chrome DevTools для разработки, тестирования и отладки веб-приложения, но опять-таки это выбор разработчика, какой браузер используется для разработки веб-сайта.
4. API (интерфейс прикладного программирования)
В веб-разработке придется много работать с API, которые в имеют дело с данными сторонних разработчиков. Это разрешает разработчикам использовать некоторые функции без совместного использования кода. Существует потрясающий Github-репозиторий API-интерфейсов, который можно использовать для разных целей, и он также дает множество идей для проектов. Вы можете проверить ссылку Public API и изучить ее.
Рекомендуется узнать об использовании API-интерфейсов Rest, методов HTTP-запросов (GET, POST, PUT, PATCH и DELETE), создании API-интерфейсов Rest, операции CRUD (Create, Read, Update, Delete), другой код состояния, формат данных (JSON, HTML или XML), используемый в запросе и т. д.
5. Аутентификация
Существует большая вероятность того, что вы будете иметь дело с аутентификацией пользователей, чтобы отслеживать пользователей на определенном веб-сайте. Например, предоставлять пользователям возможности входить в систему, выходить из нее или создавать некоторые ресурсы из личной учетной записи, отслеживать, какой ресурс какой пользователь создал, или блокировать некоторые страницы для тех пользователей, которые не вошли в систему. Безопасность учетной записи пользователя в значительной степени зависит от проверки подлинности. Поэтому важно знать, как работать с такими функциями в вашем веб-приложении.
Существует множество способов реализации аутентификации для пользователей, и это зависит от того, какой язык программирования или технология используется. Если используется React на веб-интерфейсе и Node с Express в серверной части, может использоваться JWT (JSON Web Tokens) для аутентификации, если вы используете Php, вам придется работать с сессией и файлами cookie, также можете использовать такие сторонние организации, как Google или Twitter для входа. Таким образом, есть несколько режимов работы с аутентификацией, но для веб-разработки важно изучить и внедрить ее.
6. MVC (модель, вид, контроллер)
MVC — это шаблон проектирования, который экономит много времени разработчиков, разделяя приложение на три разных раздела. Работа с шаблоном MVC делает разработку быстрее и проще. Многие высокоуровневые фреймворки, такие как Laravel, Django (на основе MVT, близких к MVC), Angular созданы на основе паттернов MVC. В MVC модель связана с взаимодействием с базой данных, представление отвечает за все, что пользователь видит на экране, а контроллер выступает в качестве интерфейса между моделью и представлением. Изучение MVC поможет легко понять основы для любого языка программирования.
7. Языки программирования
Компьютеры не понимают человеческие языки, и поэтому необходимо общаться с системой на языках программирования. В веб-разработке не только языки программирования обязательны для изучения, но и алгоритмы, которые вы можете применять, используя широкий спектр языков программирования. Веб-разработчики используют различные языки, такие как PHP, Python, Java, Ruby и, в последнее время, Javascript, который составляет им конкуренцию. Как веб-разработчик, вы должны знать хотя бы один язык программирования для создания веб-приложения.
8. Поиск и решение проблем
Если вы хотите стать веб-разработчиком, у вас должны быть естественные навыки поиска проблем и их решений. Этот навык можно развивать с помощью некоторых проектов, с помощью структур данных и алгоритмов, решения некоторых задач, головоломок и тому подобного, но вам нужно продолжать практиковать все, что вы выберете.
Независимо от того, новичок вы или опытный, в роли веб-разработчика придется искать информацию, синтаксис или решение некоторых проблем при создании приложения. Вы наверняка столкнетесь с некоторыми странными ошибками, о которых не подозреваете, и вам нужно обратиться за помощью к сообществам Google или stackoverflow, чтобы решить эту проблему.
9. Написание тестов
Многие разработчики считают это бесполезной и пустой тратой времени. Для небольшого приложения вы можете игнорировать написание тестов, но если создается большое приложение, рекомендуется писать тесты, такие как модульные тесты и другие типы тестов, потому что это помогает сделать процесс надежным и облегчить отладку. Вначале вы будете чувствовать, что напрасно тратите время, но позже поймете, что это на самом деле экономит время, поэтому возьмите за правило писать тесты при создании приложения.
10. DevOps и развертывание
И последнее, но не менее важное: как веб-разработчик, вы должны обладать знаниями по обслуживанию, масштабированию, миграции и развертыванию кода на различных платформах, таких как Google Cloud, AWS, Heroku, Netlify и т. д. Существует множество вариантов, поэтому потратьте некоторое время на изучение этих платформ, как эти службы работают и как развернуть или поддерживать код на этих платформах.
Семь принципов создания современных веб-приложений / Habr
Эта статья основана на моей презентации с конференции BrazilJS в августе 2014 года. Она базируется на идеях, о которых я писал в блоге недавно, в основном, в связи с UX и производительностью.Я хочу представить 7 действенных принципов для веб-сайтов, которые хотят применить JavaScript для управления UI. Эти принципы являются результатом моей работы как веб-дизайнера, но также как давнего пользователя WWW.
JavaScript бесспорно стал незаменимым инструментом для разработчиков фронтенда. Сейчас сфера его применения расширяется на другие области, такие как серверы и микроконтроллеры. Этот язык программирования выбрали престижные университеты, чтобы обучать студентов основам информатики.
В то же время существует ряд вопросов относительно его роли и конкретного использования, на которые многие затрудняются ответить, в том числе авторы фреймворков и библиотек.
- Должен ли JavaScript использоваться как замена функциям браузера: история, навигация, рендеринг?
- Умирает ли бэкенд? Нужно ли вообще рендерить HTML?
- Правда ли, что будущее за приложениями на одной странице (Single Page Applications, SPA)?
- Должен ли JS генерировать страницы на веб-сайте и рендерить страницы в веб-приложениях?
- Нужно ли использовать техники вроде PJAX или TurboLinks?
- Каково точное отличие между веб-сайтом и веб-приложением? Должно ли остаться что-то одно?
Далее последуют мои попытки ответить на эти вопросы. Я попытался исследовать, как использовать JavaScript с точки зрения пользователя (UX). В частности, уделил особое внимание идее минимизации времени, которое требуется пользователю для получения интересующих его данных. Начиная с основ сетевых технологий и заканчивая предсказанием будущего поведения юзера.
1. Рендеринг страниц на сервере
tl;DR: Рендеринг на сервере осуществляется не ради SEO, а для производительности. Принимайте в расчёт дополнительные запросы для получения скриптов, стилей и последующие запросы к API. В будущем, принимайте в расчёт использование метода HTTP 2.0 Push.
Прежде всего, я вынужден обратить внимание на общепринятую ошибку разделять «приложения с рендерингом на сервере» и «одностраничные приложения». Если мы хотим добиться наилучшего восприятия с точки зрения пользователя, то не должны ограничивать себя такими рамками и отказываться от одной альтернативы в пользу другой.
Причины вполне очевидны. Страницы передаются по интернету, у которого есть физические ограничения, что незабвенно проиллюстрировал Стюарт Чешир в знаменитом эссе «Это latency, дурачок»:
Расстояние между Стэнфордом и Бостоном 4320 км.
Скорость света в вакууме 300 x 10^6 м/с.
Скорость света в оптоволокне составляет примерно 66% скорости света в вакууме.
Скорость света в оптоволокне 300 x 10^6 м/c * 0,66 = 200 x 10^6 м/c.
Односторонняя задержка при передаче в Бостон 4320 км / 200 x 10^6 м/c = 21,6 мc.
Задержка при передаче туда и обратно 43,2 мc.
Пинг из Стэнфорда в Бостон в интернете современного образца около 85 мс (…)
Итак, современное оборудование интернета передаёт сигнал со скоростью 0,5 от скорости света.
Указанный результат 85 мс можно улучшить (и уже сейчас он чуть лучше), но важно понять, что существует физическое ограничение на задержку при передаче информации через интернет, как бы не увеличивалась полоса пропускания на компьютерах пользователей.
Это особенно важно в связи с ростом популярности JavaScript-приложений, которые обычно содержат только разметку <script> и <link> рядом с пустым полем <body>. Так называемые одностраничные приложения (Single Page Applications, SPA) — сервер возвращает одну страницу, а всё остальное вызывается кодом на клиентской стороне.
Представьте сценарий, когда пользователь напрямую заходит по адресу аpp.com/orders
. К моменту, когда ваше приложение получает и обрабатывает этот запрос, у него уже есть важная информация о том, что нужно показывать на странице. Оно может, например, подгрузить заказ из базы данных и добавить его в ответ. А вот большинство SPA в такой ситуации возвращает пустую страницу и тег <script>. Потом придётся ещё раз обменяться запросами для получения содержимого скрипта, и ещё раз — для получения контента.
Анализ HTML, отправляемого сервером для каждой страницы SPA
Многие разработчики сознательно идут на такую жертву. Они стараются гарантировать, что дополнительные сетевые хопы для пользователя произойдут только один раз, отправляя правильные заголовки для кеширования в ответах со скриптами и CSS. Общепринятое мнение состоит в том, что это приемлемая сделка, потому что после загрузки всех файлов на компьютер большинство действий пользователя (как переходы в другие разделы) осуществляются без запросов дополнительных страниц или скриптов.
Однако, даже с учётом кеша, имеется определённый проигрыш в производительности, если учесть время на парсинг и выполнение скрипта. В статье «jQuery слишком большой для мобильника?» говорится, как один только jQuery может тормозить некоторые мобильные браузеры на сотни миллисекунд.
Что ещё хуже, обычно пользователь не получает никакого фидбека в то время, как загружаются скрипты. Результат — чистая страница на экране, которая потом внезапно превращается в полностью загруженную страницу.
Самое главное, мы обычно забываем, что наиболее распространённые транспорт для передачи интернет-данных (TCP) стартует медленно. Это почти наверняка гарантирует, что большинство комплектов со скриптами не будут переданы за один раз, делая вышеописанную ситуацию ещё хуже.
TCP-соединение начинается с обмена пакетами для рукопожатия. Если вы используете SSL, что важно для безопасной передачи скриптов, происходит два дополнительных обмена пакетами (один, если клиент восстанавливает сессию). Только после этого сервер может начать отправку данных, но практика показывает, что он делает это медленно и порционно.
Механизм контроля заторов под названием Slow Start встроен в протокол TCP, чтобы отправлять данные, постепенно наращивая количество сегментов. Это имеет два серьёзных вывода для SPA:
1. Большие скрипты загружаются гораздо дольше, чем кажется. Как объясняется в книге «High Performance Browser Networking» Ильи Григорика, требуется «четыре обмена пакетами (…) и сотни миллисекунд задержки, чтобы выйти на 64 КБ обмена данными между клиентом и сервером». Например, в случае быстрого интернет-соединения между Лондоном и Нью-Йорком, требуется 225 мс, прежде чем TCP сможет выйти на максимальный размер пакета.
2. Поскольку это правило действует также для первоначальной загрузки страницы, то очень важно, какой контент грузится для рендеринга на странице в первую очередь. Как заключает Пол Ириш в своей презентации «Доставка товаров», критически важны первые 14 КБ. Это понятно, если посмотреть на график с указанием объёмов передачи между клиентом и сервером на первых этапах установки соединения.
Сколько КБ сервер может отправить на каждом этапе соединения, по сегментам
Веб-сайты, которым удаётся доставить контент (пусть даже базовую разметку без данных) в этом окне, кажутся исключительно отзывчивыми. На самом деле, многие авторы быстрых серверных приложений воспринимают JavaScript как нечто ненужное или что нужно использовать с большой осторожностью. Такое отношение ещё больше усиливается, если у приложения быстрые бэкенд и база данных, а его серверы находятся возле пользователей (CDN).
Роль сервера в ускорении представления контента напрямую зависит от веб-приложения. Решение не всегда сводится к «рендерингу целых страниц на сервере».
В некоторых случаях, неактуальную в данный момент для пользователя часть страницы лучше исключить из первоначального ответа и оставить на потом. Некоторые приложения, например, предпочитают осуществить рендеринг только «ядра» страницы для обеспечения немедленного отклика. Затем они запрашивают разные части страницы параллельно. Это обеспечивает лучшую отзывчивость даже в ситуации с медленным устаревшим бэкендом. Для некоторых страниц хорошим вариантом будет рендеринг только видимой части страницы.
Исключительно важна качественная оценка скриптов и стилей с учётом информации, которая у сервера есть о сессии, клиенте и URL. Скрипты, которые осуществляют сортировку заказов, очевидно будут важнее для /orders
, чем логика страницы настроек. Может быть, не настолько очевидная, но есть разница в загрузке «структурного CSS» и «CSS для оформления». Первый может понадобиться для кода JavaScript, так что требуется блокировка, а второй загружается асинхронно.
Хороший пример SPA, которое не приводит к излишнему обмену пакетами, — концептуальный клон StackOverflow в 4096 байтах, он теоретически может загружаться с первым же пакетом после рукопожатия на TCP-соединении! Автор умудрился добиться такого за счёт отказа от кеширования, используя inline для всех ресурсов в ответе с сервера. Применив SPDY или HTTP/2 server push, теоретически возможно передать весь кешируемый клиентский код за один хоп. Ну а в настоящее время, рендеринг частей или всей страницы на стороне сервера остаётся самым популярным способом избавиться от лишних раундов обмена пакетами.
Proof-of-concept SPA с использованием inline для CSS и JS, чтобы избавиться от лишних roundtrip’ов
Достаточно гибкая система, которая разделяет рендеринг между браузером и сервером и предоставляет инструменты для постепенной загрузки скриптов и стилей, вполне может стереть грань между веб-сайтами и веб-приложениями. И то, и другое использует URL’ы, навигацию, демонстрирует данные пользователю. Даже приложение с электронными таблицами, которое традиционно полагается на функциональность с клиентской стороны, сначала должно показать клиенту информацию, которую требуется редактировать. И сделать это за наименьшее количество roundtrip’ов первостепенно важно.
С моей точки зрения, самый большой недостаток производительности во многих популярных системах в наше время объясняется прогрессивным накоплением сложности в стеке. Со временем добавлялись технологии вроде JavaScript и CSS. Их популярность тоже постепенно росла. Только сейчас мы можем оценить, как их можно использовать по-другому. Речь идёт и об улучшении протоколов (это показывает нынешний прогресс SPDY и QUIC), но наибольшую выгоду несёт всё-таки оптимизация приложений.
Полезно будет вспомнить некоторые исторические дискуссии вокруг дизайна ранних версий HTML и WWW. Например, этот список рассылки от 1997 года предлагает добавить тег <img> в HTML. Марк Андрессен повторяет, насколько важно быстро доставлять информацию:
«Если документ нужно составлять в единое целое на лету, то это может быть сколь угодно сложным, и даже если сложность ограничить, у нас всё равно возникнут крупные проблемы с производительностью из-за структуризации документов подобным способом. Прежде всего, это сразу нарушает принцип одного хопа в WWW (ну, IMG тоже его нарушает, но по очень специфической причине и в очень ограниченном смысле) — уверены ли мы, что хотим этого?»
2. Немедленный ответ на действия пользователя
tl;DR: JavaScript позволяет вообще спрятать сетевую задержку. Используя это как принцип дизайна, мы можем даже убрать из приложения почти все индикаторы загрузки и сообщения “loading”. PJAX или TurboLinks упускают возможности по увеличению субъективной скорости интерфейса.
Наша задача состоит в максимальном ускорении реакции на действия пользователя. Сколько бы усилий мы не вкладывали в уменьшение числа хопов при работе с веб-приложением, но есть вещи вне нашего контроля. Это теоретический предел скорости света и минимальный пинг между клиентом и сервером.
Важный фактор — непредсказуемое качество связи между клиентом и сервером. Если качество связи плохое, то будет происходить повторная передача пакетов. Там, где контент должен загружаться за пару roundtrip’ов, может понадобиться гораздо больше.
В этом главное преимущество JavaScript для улучшения UX. Если на клиентской стороне интерфейс управляется с помощью скриптов, мы можем спрятать сетевую задержку. Мы можем создать впечатление высокой скорости. Мы можем искусственно достигнуть нулевой задержки.
Предположим снова, что перед нами обычный HTML. Документы соединяются гиперссылками или тегами <a>. Если нажать на любой из них, то браузер осуществит сетевой запрос, что занимает непредсказуемо долгое время, потом получает и обрабатывает полученные данные и наконец переходит в новое состояние.
JavaScript позволяет реагировать немедленно и оптимистично на действия пользователя. Нажатие на ссылку или кнопку приводит к немедленной реакции, без обращения в Сеть. Известный пример — это интерфейс Gmail (или Google Inbox), в котором архивация почтового сообщения происходит немедленно, тогда как соответствующий запрос к серверу отправляется и обрабатывается асинхронно.
В случае с формой, вместо ожидания какого-то кода HTML в качестве ответа на её заполнение, мы можем реагировать сразу, как только пользователь нажал “Enter”. Или даже лучше, как делает поиск Google, мы можем реагировать ещё раньше, готовя разметку для новой страницы заблаговременно.
Такое поведение — пример того, что я называю адаптацией разметки. Основная идея состоит в том, что страница «знает» свою будущую разметку, так что может переключиться на неё тогда, когда ещё нет данных для указания на это. Это «оптимистичное» поведение, потому что всё ещё остаётся риск, что данные никогда не поступят, и придётся выводить сообщение об ошибке, но это, очевидно, случается редко.
Заглавная страница Google вполне подходит в качестве примера, потому что она очень чётко демонстрирует первые два принципа из нашей статьи.
Во-первых, пакетный дамп TCP-соединения с www.google.com
показывает, что они специально стараются отправить всю страницу целиком сразу после получения запроса. Весь обмен пакетами, включая закрытие соединения, занимает 64 мс для меня в Сан-Франциско. Вероятно, это было актуально для них с самого начала.
В конце 2004 года, компания Google стала пионером в использовании JavaScript для выдачи подсказок в реальном времени в процессе набора поискового запроса (интересно, что эту функцию сотрудник разработал в свободные от основной работы 20% времени, так же как и Gmail). Это даже стало фундаментом для появления Ajax:
Посмотрите на Google Suggest. Наблюдайте, как обновляются поисковые термины по мере набора текста, практически мгновенно… без задержки на перезагрузку страницы. Google Suggest и Google Maps — это два примера нового подхода к созданию веб-приложений, которые мы в Adaptive Path назвали “Ajax”
И в 2010 они представили Instant Search, в котором JS играет центральную роль, вообще исключая обновление страницы вручную и переключаясь на разметку «поисковые результаты» при первом же нажатии клавиши, как видно на иллюстрации вверху.
Другой видный пример адаптации разметки, возможно, лежит у вас в кармане. С первых же дней iPhone OS требовала от авторов приложений предоставить картинку default.png, которое можно сразу вывести на экран во время загрузки самого приложения.
iPhone OS принудительно загружает default.png перед запуском приложения
В этом случае операционная система компенсирует не сетевую задержку, а CPU. Это было важно, учитывая производительность раннего оборудования. Правда, в некоторых случаях такой подход давал сбой. Например, если картинка не соответствовала экрану ввода пароля. Подробный анализ результатов публиковал Марко Армент в 2010 году.
Другим типом действий, кроме кликов и отправки форм, которые отлично улучшаются с помощью JavaScript, является рендеринг загрузки файла.
Мы можем зарегистрировать попытку пользователя загрузить файл разными способами: drag-n-drop, вставка из буфера, выбор файла. Затем, благодаря новым HTML5 APIs, мы можем отобразить контент, как будто он уже загружен. Пример такого рода интерфейса — наша работа с загрузками в Cloudup. Обратите внимание, как миниатюра изображения генерируется и рендерится мгновенно:
Изображение рендерится и отображается до окончания загрузки
Во всех этих случаях мы улучшаем восприятие скорости. К счастью, существует много доказательств полезности такого подхода. Взять хотя бы пример, как увеличение расстояния до багажного конвейера в Хьюстонском аэропорту уменьшило количество жалоб на потерянный багаж, без необходимости ускорять обработку багажа.
Эта идея должна серьёзно повлиять на UI наших приложений. Я считаю, что индикаторы загрузки должны стать редкостью, особенно если мы переходим на приложения с информацией в реальном времени, которые описываются в следующем разделе.
Есть ситуации, когда иллюзия мгновенного действия в реальности оказывает вредный эффект на UX. Это может быть форма платежа или окончания сессии на сайте. Применяя здесь оптимистичный подход, де-факто обманывая пользователя, мы рискуем вызвать у него раздражение.
Но даже в этих случаях, отображение на экране спиннеров или индикаторов загрузки следует прекратить. Их нужно отображать только после того, как пользователь считатиает отклик не мгновенным. В соответствии с часто цитируемым исследованием Nielsen:
Базовый совет по времени отклика остаётся неизменным уже тридцать лет Miller 1968; Card et al. 1991:
* 0,1 секундs является лимитом, чтобы пользователь воспринимал отклик как немедленный, здесь не требуется отображение никакой дополнительной информации, кроме результата операции.
* 1,0 секунды является лимитом на непрерывность потока мысли у пользователя, даже хотя он заметит задержку. Обычно, не требуется никакой дополнительной индикации при задержки более 0,1 секунды, но менее 1,0 секунды, но у пользователя пропадает ощущение прямой работы с данными.
* 10 секунд является лимитом удерживания внимания пользователя на диалоге. При большей задержке пользователи захотят выполнить другую задачу, ожидая отклика от компьютера.
Техники вроде PJAX или TurboLinks, к сожалению, упускают большинство возможностей, описанных в данном разделе. Код на клиентской стороне не «знает» о будущем состоянии страницы до тех пор, пока не состоится обмен данными с сервером.
3. Реакция на изменение данных
tl;DR: Когда на сервере обновляются данные, клиента следует уведомлять без задержки. Это такая форма повышения производительности, когда пользователя освобождают от необходимости совершать дополнительные действия (нажимать F5, обновлять страницу). Новые проблемы: управление (повторным) соединением, восстановление состояния.
Третий принцип относится к реагированию UI на изменение данных в источнике, обычно, в одном или нескольких серверах баз данных.
Уходит в прошлое модель передачи по HTML данных, которые остаются статичными до тех пор, пока пользователь не обновит страницу (традиционные веб-сайты) или не взаимодействует с ней (Ajax).
Ваш UI должен обновляться автоматически.
Это критически важно в мире с нарастающим потоком информации из разных источников, включая часы, телефоны, планшеты и носимые устройства, которые появятся в будущем.
Представьте новостную ленту Facebook сразу после её появления, когда информацию публиковали, в основном, с персональных компьютеров пользователей. Статичный рендеринг нельзя было назвать оптимальным, но он имел смысл для людей, которые обновляли ленту, скажем, раз в день.
Сейчас мы живём в мире, когда ты загружаешь фотографию — и почти немедленно получаешь лайки и комментарии от друзей и знакомых. Необходимость в мгновенном отклике стала естественной необходимостью в конкурентном окружении других приложений.
Было бы неверным, однако, предположить, что преимущества мгновенного обновления UI ограничиваются только многопользовательскими приложениями. Вот почему я люблю говорить о согласованных дата-поинтах, вместо пользователей. Возьмём типичный сценарий синхронизации фотографии между телефоном и ваши собственным ноутбуком:
Однопользовательское приложение тоже может получить пользу от «реактивности»
Полезно представлять всю информацию, которая отправляется пользователю как «реактивную». Синхронизация сессии и состояния авторизации — один из примеров универсального подхода. Если у пользователей вашего приложения одновременно открыто несколько вкладок, то окончание рабочей сессии на одной из них должно сразу деактивировать авторизацию на всех остальных. Это неизбежно ведёт к улучшению безопасности и лучшей защите конфиденциальной информации, особенно в ситуациях, когда несколько человек имеют доступ к одному устройству.
Каждая страница реагирует на состоянии сессии и статус авторизации
Как только вы установили правило, что информация на экране обновляется автоматически, важно поработать над новой задачей: восстановление состояния.
При отправке запросов и получении атомарных обновлений легко забыть, что ваше приложение должно нормально обновляться даже после долгого отсутствия связи. Представьте, что вы закрываете крышку ноутбука и открываете её через несколько дней. Как будет вести себя приложение?
Пример того, что происходит в случае некорректного обновления связи
Способность приложения нормально восстанавливать связь взаимодействует с принципом № 1. Если вы выбрали отправлять данные при первой же загрузке страницы, вы должны учитывать и время, которое прошло перед загрузкой скриптов. Это время, по существу, эквивалентно времени дисконнекта, так что первоначальное подключение ваших скриптов является возобновлением сессии.
4. Контроль обмена данными с сервером
tl;DR: Теперь мы можем тонко настраивать обмен данными с сервером. Убедитесь в обработке ошибок, повторных запросах в пользу клиента, синхронизации данных в фоновом режиме и сохранении кеша в офлайне.
Когда появился веб, обмен данными между клиентом и сервером был ограничен несколькими способами:
- Нажатие на ссылку отправит
GET
для получения новой страницы и её рендеринга. - Отправка формы отправит POST или GET с последующим рендерингом новой страницы.
- Внедрение изображения или объекта отправит GET асинхронно с последующим рендерингом.
Простота такой модели очень привлекательна, и сейчас всё определённо усложнилось, когда речь идёт о понимании, как получать и отправлять информацию.
Главные ограничения касаются второго пункта. Невозможность отправить данные без обязательной загрузки новой страницы было недостатком с точки зрения производительности. Но самое главное, что это полностью ломало кнопку «Назад»:
Вероятно, самый раздражающий артефакт старого веба
Именно поэтому веб как платформа для приложений оставался неполноценным без JavaScript. Ajax представлял собой огромный скачок вперед с точки зрения удобства в части публикации информации пользователем.
Сейчас у нас есть множество API (XMLHttpRequest, WebSocket, EventSource, это лишь некоторые из них), которые дают полный и чёткий контроль над потоком данных. Кроме возможности публиковать пользовательские данные через форму, у нас появились новые возможности по улучшению UX.
Прямое отношение к предыдущему принципу имеет показ состояния соединения. Если мы ожидаем, что данные будут обновляться автоматически, то обязаны информировать пользователя о фактах потери связи и попытках её восстановления.
При обнаружении дисконнекта, полезно сохранить данные в памяти (а ещё лучше, в localStorage), так что их можно отправить позднее. Это особенно важно в свете будущего использования ServiceWorker, который позволяет приложениям JavaScript работать в фоновом режиме. Если ваше приложение не открыто, вы всё ещё можете продолжать попытки синхронизировать данные с сервером в фоновом режиме.
Учитывайте возможность таймаутов и ошибок при отправке данных, такие ситуации должны решаться в пользу клиента. Если соединение восстановлено, пробуйте отправить данные снова. В случае постоянной ошибки, сообщите об этом пользователю.
Некоторые ошибки нужно обрабатывать особенно внимательно. Например, неожиданная 403 может означать, что пользовательская сессия признана недействительной. В таких случаях, есть возможность восстановить сеанс, если показать пользователю окно для ввода логина и пароля.
Важно ещё убедиться, что пользователь случайно не прервёт поток данных. Это может случиться в двух ситуациях. Первый и самый очевидный случай — закрытие браузера или вкладки, что мы пытаемся предотвратить обработчиком beforeunload
.
Предупреждение beforeunload
Другой (и менее очевидный) случай — попытка перехода на другую страницу, например, нажатие на ссылку. В этом случае приложение может остановить юзера иными методами, на усмотрение разработчика.
5. Не ломай историю, улучшай её
tl;DR: Если браузер не будет управлять URL’ами и историей, у нас возникнут новые проблемы. Убедитесь, что вы соответствуете ожидаемому поведению в отношении прокрутки. Сохраняйте собственный кеш для быстрого фидбека.
Если не считать отправки форм, то при использовании в веб-приложении одних только гиперссылок у нас будет полностью функциональная навигация «Вперёд/Назад» в браузере.
К примеру, типичную «бесконечную» страницу обычно делают с помощью кнопки на JavaScript, которая запрашивает дополнительные данные/HTML и вставляет их. К сожалению, немногие при этом помнят о необходимости вызова history.pushState
или replaceState
как обязательного шага.
Вот почему я использую слово «ломать». С простой моделью первоначального веба такая ситуация была невозможна. Каждое изменение состояния основывалось на изменении URL.
Но есть и обратная сторона медали — возможность улучшать историю сёрфинга, которую мы теперь контролируем средствами JavaScript.
Одну такую возможность Дэниел Пипиус назвал Fast Back:
Кнопка «Назад» должна работать быстро; пользователи не ожидают слишком большого изменения данных.
Это как рассматривать кнопку «Назад» в качестве кнопки из веб-приложения и применить к ней принцип № 2: немедленно реагировать на действие пользователя. Главное, что у вас есть возможность решить, как организовать кеширование предыдущей страницы и мгновенно вывести её на экран. Вы можете затем применить принцип № 3, а потом информировать пользователя о поступлении новых данных на эту страницу.
Всё ещё остаётся несколько ситуаций, когда вы не можете контролировать поведение кеша. Например, если вы отрендерили страницу, затем ушли на сторонний сайт, а потом пользователь нажал «Назад». Этому маленькому багу особенно подвержены приложения, которые рендерят HTML на стороне сервера, а потом модифицируют его на стороне клиента:
Некорректная работа кнопки «Назад»
Ещё один способ сломать навигацию — игнорирование памяти о состоянии прокрутки. Ещё раз, страницы, которые не используют JS и ручное управление историей, скорее всего, не будут иметь тут проблем. Но динамические страницы будут. Я протестировал две самые популярные новостные ленты на основе JavaScript в интернете: Twitter и Facebook. У обоих обнаружилась амнезия на прокрутку.
Бесконечное листание страниц — обычно, признак скроллинг-амнезии
В конце концов, опасайтесь таких изменений состояния, которые релевантны только при просмотре истории. Например, этот случай с изменением состояния поддеревьев с комментариями.
Изменение вида комментариев нужно сохранять в истории
Если страница была заново отрисована после нажатия ссылки внутри приложения, пользователь может ожидать, что все комментарии будут развёрнуты. При изменении состояния его нужно сохранить в истории.
6. Обновление кода через push-сообщения
tl;DR: Недостаточно отправлять через push-сообщения только данные, нужно ещё и код. Избегайте ошибок API и повышайте производительность. Используйте stateless DOM для безболезненной перелицовки приложения.
Исключительно важно, чтобы ваше приложение реагировало на изменения в коде.
Во-первых, это уменьшает количество возможных ошибок и повышает надёжность. Если вы сделали важное изменение в API бэкенда, то должны обновить код клиентских программ. В противном случае, клиенты могут не воспринять новые данные или могут прислать данные в несовместимом формате.
Не менее важной причиной является соблюдение принципа № 3. Если ваш интерфейс обновляется сам, то у пользователей мало причин обращаться к ручной перезагрузке страницы.
Имейте в виду, что у обычного сайта обновление страницы инициирует две вещи: перезагрузка данных и перезагрузка кода. Организация системы с push-обновлениями данных без push-обновлений кода неполноценна, особенно в мире, где одна вкладка (сессия) может оставаться открытой очень долгое время.
Если серверный push-канал работает, то пользователю можно выслать уведомление о доступности нового кода. Если нет, то номер версии можно добавить в заголовок исходящих HTTP-запросов. Сервер может сравнить его с последней известной версией, согласиться на обработку запроса или нет, и выдать задание для клиента.
После этого некоторые веб-приложения принудительно перезагружают страницу от имени пользователя. Например, если страница не находится в видимой области экрана и на ней нет заполненных форм для ввода.
Ещё лучший подход — «горячая» замена кода. Это значит, что не придётся осуществлять полную перезагрузку страницы. Вместо этого, определённые модули заменяются на лету, а их код повторно отправляется на выполнение.
Во многих существующих приложениях довольно сложно осуществить «горячую» замену кода. Для этого нужно изначально придерживаться архитектуры, которая разделяет поведение (код) от данных (состояние). Такое разделение позволит нам довольно быстро накатывать много разных патчей.
Например, в нашем веб-приложении есть модуль, который устанавливает шину для передачи event’ов (как socket.io). Когда событие наступает, состояние определённого компонента меняется и это отражается в DOM. Затем вы изменяете поведение этого компонента, например, так, что он генерирует разные разметки DOM для существующего и нового состояний.
В идеале у нас должна быть возможность менять код помодульно. Не нужно будет заново устанавливать соединение с сокетом, например, если есть возможность просто обновить код нужного компонента. Идеальная архитектура для push-обновлений кода, таким образом, является модульной.
Но сразу возникает проблема с тем, как оценить модули без нежелательных побочных эффектов. Здесь лучше всего подходит архитектура вроде той, которую предлагает React. Если код компонента обновляется, его логика может быть просто повторно исполнена, и DOM обновляется. Объяснение этой концепции от Дэна Абрамова читай здесь.
По существу, идея заключается в том, что вы обновляете DOM (или перекрашиваете его), что существенно помогает в замене кода. Если состояние сохранено в DOM или обработчики event’ов установлены приложением, то обновление кода может стать намного более сложной задачей.
7. Предсказание поведения
tl;DR: Отрицательная задержка.
У современного JavaScript-приложения могут быть механизмы для предсказания действий пользователя.
Наиболее очевидным применением этой идеи является заблаговременное скачивание данных с сервера, прежде чем пользователь их запросил. Скачивать веб-страницу, когда над ней появился курсор мыши, так что по нажатию на ссылки она отображается мгновенно, — это простой пример.
Немного более продвинутый метод мониторинга отслеживания движения мыши анализирует её траекторию на предмет будущего «столкновения» с интерактивными элементами, как кнопки. Пример на jQuery:
Плагин jQuery предугадывает траекторию мыши
Заключение
Веб остаётся самой многогранной средой передачи информации. Мы продолжаем добавлять динамику на наши страницы и перед их внедрением должны убедиться, что сохраним важные принципы веба, доставшиеся нам в наследство.
Страницы, связанные между собой гиперссылками, — хорошие строительные блоки для любого приложения. Поступательная загрузка кода, стилей и разметки по мере действий пользователя гарантирует отличную производительность без отказа от интерактивности.
Новые уникальные возможности предоставляет JavaScript. Если эти технологии будут повсеместно использоваться, то обеспечат наилучший опыт работы для пользователей самой свободной платформы из существующих — WWW.
Эффективный подход к нетиповой разработке сайтов / Habr
Мы несколько лет занимаемся разработкой сайтов разной степени сложности. За 5 лет сделали более 300 проектов. В своей работе мы не используем шаблоны, дизайн уникальный и разрабатывается под нужды клиента. Не берем готовую CMS и не пытаемся привести задачи клиента к типовому решению, используем Django Framework и разрабатываем такой сайт, который максимально подходит под задачу. В общем, стараемся сделать максимально качественный сайт, на который способны. Как при этом не сломать спину, добиться результата и заработать денег, чтобы развиваться дальше?
В то время, как мы думаем о качестве продукта, клиент хочет получить результат как можно быстрее, сайт сразу должен стабильно работать, дизайн и интерфейс должны соответствовать ожиданиям клиента, а то и быть выше этих самых ожиданий.
Для достижения максимальной эффективности мы убедились, что нужно менять подход к разработке. Стандартный вариант с последовательной организацией этапов проекта нам не подходит. Поэтому в этой статье я бы хотел поделиться нашим опытом и соображениями о максимально эффективной системе.
Основные проблемы обычного подхода, которые мешают нам работать эффективно
Непонятные согласования. Мы вынуждены согласовывать дизайн сайта без взаимного понимания всей структуры проекта. Техническое задание полного видения не дает.
Многократная постановка задачи. Сразу всем (программисту и дизайнеру) поставить задачу не получится, так как программист начинает работу после согласования дизайна сайта. В результате упускаются некоторые моменты и детали.
Дорогие ошибки этапа дизайна. Дизайнер может ошибиться или что-то упустить, что останется незамеченным до работы программиста. Дизайнер вынужден исправлять недочеты, когда он уже погружен в другой проект. Это сказывается на качестве продукта.
Слабая коммуникация команды. При последовательной работе не формируется единой команды и каждый работает в отдельности над своим этапом.
Ожидание информации от клиента. Клиент порой долго готовит всю необходимую информацию для сайта, чтобы мы могли ее обработать и привести в соответствие с общими ожиданиями. С ней тоже нужно еще работать, а рабочая группа уже занята другими проектами.
Как я писал выше, мы не используем готовых шаблонов и уделяем много времени дизайну сайта. Для нас это ответственный и важный процесс, поэтому он занимает больше времени чем хотелось бы. Иногда клиент хочет странного и тут мы еще тратим время на долгие согласования макетов, иногда мы сами не можем найти сразу подходящее решение.
В результате все сроки плывут, клиент начинает торопить с результатом. Нет времени на детальное тестирование и на работу над мелкими приятными мелочами (красивые модальные окна, приятная валидация форм без перезагрузки страницы, удобные фильтры, оформление писем для уведомлений и многое другое). Сайт выглядит как-то так:
Такой результат вряд ли кого устроит, да и потом будет много проблем в поддержке проекта и дальнейшей работе с клиентом.
Эффективное решение
Очевидное решение в этой ситуации — это начать этап программирования параллельно с дизайном.
Разработка сайта — это не строительство дома, мы всегда можем что-то изменить и поправить. Главное начать и все проблемы быстрее дадут о себе знать, а часть из них решиться дизайном или ранним обсуждением с клиентом.
Появляется лишний, на первый взгляд, дополнительный этап проектирования, но это совсем не так. С подробным техническим заданием сложно работать, так как это получается довольно объемный документ. Текстовая информация оставляет много места для воображения, поэтому конечный результат все участники процесса представляют несколько по разному. Да и человек, который принимает решение со стороны клиента, редко вычитывает большой и объемный документ. Намного легче посмотреть прототип и принять решение. Прототип позволяет лучше «разглядеть» структуру будущего сайта и поэтому будет меньше проблем при занесении информации клиента, да и по прототипу ее значительно легче готовить, так как уже есть видение проекта.
Благодаря прототипу мы не тратим время на написание подробного ТЗ, но можем начать программировать параллельно с дизайном сайта. С дизайнера снимается дополнительная задача по проектированию всей структуры сайта и он может сосредоточиться на визуальной составляющей.
У нас может быть готова и согласована графическая концепция сайта. Все макеты еще не готовы, но уже точно понятно какая требуется информация для сайта и как она должна выглядеть. Так как мы используем Django framework, то по готовым моделям программист может быстро развернуть простую систему управления и параллельно с программированием бизнес-логики и доработки макетов мы уже можем заносить информацию для будущего сайта.
Как только мы получим согласованный дизайн, технолог начинает верстать шаблоны для сайта и сводить с готовым кодом от программиста. Пока дизайнер далеко не ушел и не отвлекся на другие проекты, мы можем доработать приятные мелочи и если потребуется скорректировать какие-то решения.
В результате, мы получаем работающий и приятный сайт, который решает проблемы клиента, да и времени на разработку с таким подходом уходит значительно меньше. Конечно, у нас накопилось достаточно много своих наработок, которые тоже помогают нам в работе. Мы стараемся сделать и развить нашу платформу для разработки, чтобы оптимизировать уже все внутренние процессы. Конечно, мы не планируем и не хотим написать свою новую очередную CMS, это совсем другой бизнес и для этого процессы должны быть устроены совсем по-другому. В дальнейшем мы расскажем о нашей работе более детально, если это будет интересно. Некоторые сайты, которые мы разработали по этой схеме можно посмотреть на студийном сайте.
Хотел еще отметить, что в обычном последовательном подходе можно организовать получение качественного и достойного результата, но это будет не быстро и в рабочей группе по проекту будет не 4-5 человек, а значительно больше.
Лекции Технотрека. Основы веб-разработки (весна 2016) / Mail.ru Group corporate blog / Habr
Продолжаем публикацию наших образовательных материалов. Этот курс посвящен разработке web-приложений среднего масштаба (иначе говоря, сайтов уровня личного блога). Курс является обзорным и знакомит будущих web-разработчиков с широким спектром технологий и общими принципами работы web-приложений. По сути, курс нужен для того, чтобы «погрузить» студентов в тему и позволить в дальнейшем сконцентрироваться на конкретных технологиях, не теряя из вида общую архитектуру.
Цель курса — всестороннее изучение устройства и принципов работы современных web-приложений и сети интернет в целом, а также получение практических навыков web-разработки. Акцент в курсе сделан на backend-разработку. На каждом из лекционных занятий студентам выдается задание, в ходе выполнения которых шаг за шагом формируется конечный проект, готовый к тому, чтобы стать первым в портфолио будущего web-разработчика.
В качестве инструментария студенты в ходе курса обзорно знакомятся с администрированием nginx, MySQL и Redis, разработкой на Django и использованием таких библиотек и продуктов, как Centrifugo, Gunicorn, Celery, Elasticsearch. Кроме того, разбираются основы верстки и работы CSS-фреймворками и JS-компонентами. Курс ведут Илья Стыценко (разработчик в подразделении внутренней информационной разработки) и Денис Исаев (руководитель группы программистов C/C++ в Почте Mail.Ru). Более подробно — под катом.
В первой лекции рассказывается, кому и зачем действительно нужна web-разработка, как строится проект (от наличия ТЗ и до выкладки на боевые сервера). Рассматриваются назначение и принципы работы сети в целом и сетевых протоколов (DNS, IP, TCP, HTTP/HTTPS).
В основе этого занятия несколько тем: основы UNIX-систем, способы серверной работы с сокетами, схема устройства работы web-серверов (и обработки сетевых соединений), администрирование nginx как web-сервера и использование gunicorn как сервера приложений.
Представляем студентам понятие web-фреймворка. Рассказываем о том, какие они бывают и чем отличаются друг от друга. Разбираем парадигму MVC и её применение в Django. Изучаем базовые особенности django и каждого из компонентов, начинаем строить модели данных и readonly-часть будущего проекта.
Посмотрим, как сделать так, чтобы пользователь мог создавать и изменять контент на сайте: как происходит получение данных от пользователя, валидация данных со стороны сервера, создание и редактирование объектов. Касаемся темы авторизации.
Рассматриваем верстку. Простая тема о принципах рендера в современных браузерах, студенты знакомятся с HTML, CSS, DOM-моделью. Даем самые основы применения JavaScript и jQuery.
Агрегирование данных в БД, AJAX-запросы и JSON, generic-связи между моделями, management-команды Django.
Лекция посвящена обзорным темам о том, что и почему мы делаем в web-разработке: архитектуре серверов, real-time в web-приложениях (применяем websockets, используя Centrifugo), очередям (используем Celery), поиску по сайту (Elasticsearch, Sphinx, Haystack, вот это всё). Рассматриваем вопрос кеширования в Django и в web-проектах в целом.
Заключительная лекция. Вы узнаете, как мы выкатываем сайты на продакшн: выбираем домен, имя и сервер; работаем с сервером (SSH/терминал, мониторинг, логи, backup, безопасность и т.д.). И чуть-чуть о SEO. Просто так, на десерт.
По завершению курса вы научитесь использовать MVC-фреймворки, получите опыт верстки HTML-страниц как “голышом”, так и с использованием CSS-фреймворков вроде Bootstrap. Помимо разработки наши студенты учатся устанавливать и настраивать web-сервера, проектировать модель данных, получают навык отладки web-приложений на всех этапах исполнения.
Плейлист всех лекций находится по ссылке. Напомним, что актуальные лекции и мастер-классы о программировании от наших IT-специалистов в проектах Технопарк, Техносфера и Технотрек по-прежнему публикуются на канале Технострим.
Илья Стыценко зарегистрирован на Хабре как sat2707 и, если у вас есть вопросы, сможет ответить в комментариях.