Привет, я Андрей Сидоренко, Lead Magento Developer в NIX. За 11 лет в IT-сфере я приобрел коммерческий опыт и продолжаю развиваться в этом направлении. Ранее также занимался разработками и оптимизациями на фрилансе. За это время у меня накопился багаж знаний и умений, которыми хочется поделиться с единомышленниками.
Эта статья будет полезна всем веб-разработчикам. Каждый сможет найти в ней что-то интересное для себя — и подходы к решению проблем, и удобные сервисы, которые пригодятся при выполнении ежедневных задач.
Когда мы слышим слово «реанимация», большинство людей представляет яркую медицинскую лампу над операционным столом и толпу врачей вокруг пациента. Все действуют быстро и слаженно, ведь от них зависит жизнь человека. Разработчики, конечно, не спасают человеческие жизни, но нервы пользователей уж точно могут поберечь. Подобными «операциями» ежедневно занимается наша команда — оптимизирует работу сайтов на Magento. По сути, это та же «реанимация»: специалисты восстанавливают резко нарушенные или утраченные жизненно важные функции системы. За годы практики мы сформировали чек-лист, который поможет разработчикам выполнять эту задачу быстрее, легче и качественнее.
Для исправления работы сайта наша команда использует базовый чек-лист. Мы смотрим, какие в нем есть проблемы и доводим его до рабочего состояния, чтобы людям было удобно пользоваться площадкой, а владельцу бизнеса — увеличивать количество довольных покупателей и развивать онлайн-торговлю.
Если мы видим проблемы в инфраструктуре, надо сперва решить их, прежде чем двигаться дальше. Без того, чтобы нормально настроить окружение сайта (операционную систему и все программы, обеспечивающие его работу), мы не сможем решить базовые проблемы сайта.
Операционка — это среда, в которой работает сайт, это основа его программного окружения. Это воздух, который снабжает весь организм. Не поместив сайт в удобное для него окружение, мы не сможем поддерживать его функции в нормальном состоянии. Устаревшая или убитая операционная система, которая уже не подлежит апгрейду — первый признак того, чтобы переносить сайт на новую инфраструктуру. Ведь проще настроить все заново на новом «железе» или на другом сервисе.
Если мы имеем дело с интернет-магазином на Magento, смотрим, на каком хостинге и сервере он развернут, какая используется операционная система, какой у него веб-сервер. Обязательно проверяется наличие SSL-сертификата, необходимого для HTTPS-подключения. Считайте, что если у вашего сайта нет HTTPS-подключения, то вас нет в интернете. Google просто игнорирует или выдает самый низкий рейтинг вашему ресурсу. Этот сертификат бесплатный. К тому же он настолько легко настраивается, что грех его не иметь. В интернете найдете множество статей по настройке SSL-сертификата. Наверное, только ленивый не подключит его на свой сайт.
Также нужно обращать внимание на то, как настроен сертификат. Он может работать, но внешние сервисы все равно будут на него ругаться, мол, сертификат не так настроен. Особенно это важно при работе с платежными сервисами. Существуют специальные сервисы, позволяющие проверить качество настройки сертификата.
В новой версии Magento TTFB может быть около секунды, в более старых — в районе двух секунд. Стоит отметить, что речь идет о страницах, которые не были закешированы. Если кеш правильно организован, то страница прилетает к нам примерно за 200–300 миллисекунд. Отчасти это может временно решить проблему с медленными страницами.
Кешируются страницы, на которых контент обычно меняется не сильно (главная страница, каталог, продукты, контакты). Когда загружается новая страница, она генерируется веб-сервером впервые — ее еще нет в кеше. Magento рендерит хедер с главным меню, затем — контент этой страницы, потом — футер. В нормальной ситуации, чтобы сгенерировать это все, Magento тратит 1–2 секунды. Если страница не изменяется, нет смысла заново генерировать ее при каждом следующем запросе. Можно положить уже сформированную страницу в кеш и выдавать посетителям готовую страницу.
К нам попадали сайты, на которых кеш был вообще выключен. Возможно, предыдущий разработчик не знал, как работать с Magento-кешом, и поэтому отключил его. Тогда мы разбираемся, что разработчик менял на сайте, что дописывал в коде, если нужно — исправляем, проверяем, как работает ресурс, и, естественно, включаем кеширование. Без него сайт не сможет «летать».
Иногда предыдущие разработчики оставляют свои наработки, которые ухудшают текущее состояние сайта. Программист написал что-то, запустил, вроде работает. Но он не учитывал, как все сложится в будущем, когда нагрузка на сайт вырастет. От его прошлых нововведений сегодня сайт может проседать. У нас была ситуация, когда на странице каталога неправильно организовали запросы в базу данных. Вместо 100–200 запросов для генерации всей страницы там было несколько тысяч. Это сильно нагружало сервер и тормозило страницы. Мы переписали одну небольшую часть кода, и сайт резко «взлетел».
После того как мы разобрались с кешом, убедились, что он включен и быстро открывает страницы, приступаем к анализу ошибок на сайте.
Иногда, исправляя что-то, мы открываем доступ к ранее неизвестному функционалу. Поэтому мой вам совет: прежде чем исправить баг, разберитесь, чем он был вызван, надо ли его сейчас чинить именно так. Возможно, это лишь следствие другой ошибки и исправлять надо в другом месте. Также бывает, что ошибка блокирует доступ к какому-то ужасному функционалу, который положил бы сервер и сайт. Так что это не баг, а фича, которая спасала сайт все это время.
А бывают и совершенно дикие баги. Помню, нам достался сайт, на котором домашняя страница не открывалась без указания языка в адресе. Язык дописали руками — ресурс заработал. Не понятно, как посетители добирались до продуктов, если при входе на первую же страницу появлялась ошибка.
Для оптимизации в Magento включается сборка всего JavaScript в бандлы. Вместо того чтобы скачивать каждый раз по 500 файлов, они все собираются в «пачки», и мы уже качаем с десяток файлов. Минус этого подхода в том, что каждый раз придется качать весь JavaScript. Однако, если правильно настроить браузерное кеширование, эти скрипты будут кешироваться в браузере, их нужно будет скачивать только раз. При следующем посещении сайта весь JavaScript будет загружаться из кеша браузера. Есть и другой, более сложный подход без этих проблем — Advanced Bundling.
При использовании браузерного кеширования стоит убедиться, что все настроено правильно. Представим, что мы зарелизили новую фичу. Для ее работы изменили CSS и JS. Соответственно, новой функцией на сайте смогут воспользоваться только те, кто заново скачает весь статический контент. Но для тех, у кого эти файлы сохранены в браузере, это произойдет только в том случае, если URL файлов будет изменен.
В Magento есть функция подписывания статического контента. В адрес статического файла дописывается строка (Unix Timestamp), которая обновляется вслед за каждым следующим деплойментом. Таким образом, когда мы будем «выливать» на сайт что-то новое, эта строка будет обновляться и на сайте появится новая ссылка на статические файлы. Браузер просто заново перекачает последнюю версию CSS и JS.
Бывают ситуации, когда внешний сервис привязан к IP-адресу текущего сервера. Если мы переносим сайт на новый сервер, у него изменится IP-адрес и автоматически заблокируется доступ к сервису, который оформляет заказы. Разработчикам надо быть заранее готовыми к такому сценарию: прописать новый IP-адрес в этом сервисе, чтобы не потерялась возможность оформлять заказы.
Владельцы сайтов с большим количеством продуктов обычно используют сторонние системы для управления стоком, так как зачастую эти данные надо собирать из нескольких источников. При любых изменениях на сайте важно не сломать работу этих систем, иначе сайт может начать продавать продукты, которых нет в наличии или наоборот — не показывать новые поступления. На старте нужно собрать как можно больше информации об этих интеграциях.
Хорошо, когда предыдущая команда оставляет документацию об интеграции с внешними сервисами, но такое бывает редко. Обычно мы ищем контакты прошлых разработчиков и пишем им напрямую, чтобы выяснить, с чем у сайта есть интеграции и как они работают. Либо собираем по крупицам информацию от владельца сайта, расспрашиваем его на звонках и анализируем доступный код и логи. После сбора данных и их анализа формируем документацию, по которой и нам проще работать, и клиенту видно состояние его сайта.
Одни сервисы могут мониторить состояние инфраструктуры: насколько хорошо работает сервер, хватает ли оперативной памяти, насколько загружен диск, когда истечет срок действия сертификата. А другие — контролировать работу самого приложения. Лучше использовать все. Например, случилась ошибка, вызванная нехваткой какого-то ресурса. Мы видим в одном мониторинге по ресурсам, что у нас переполнен диск, а в другом — что в приложении посыпались ошибки. Анализируя информацию с обоих сервисов, мы получаем полную картину происходящего, даже не заходя на сайт.
Также важно иметь удобную нотификацию из этих сервисов. По умолчанию везде уведомления отправляются на почту. Как показывает практика, иногда из-за большого количества писем важные уведомления могут потеряться, особенно это относится к мобильным почтовым клиентам. А вот за чатами, которые пишет бот, следить гораздо удобнее. Так вы быстрее сможете узнавать о проблемах на сайте и оперативно решать их.
Для мониторинга за инфраструктурой мы используем такие приложения:
Если вы владелец сайта и читаете эту статью, советую вам сразу обращаться к разработчикам. А девелоперам — стараться докапываться до сути проблемы. Если в ошибке сказано, что у вас нет какого-то параметра, не нужно просто так его дописывать. Разберитесь, нужен ли он там, нужна ли эта функциональность. Может, не стоит дописывать параметр, а лучше сделать исправление в другом месте, которое вызывает эту функцию.
Эта статья будет полезна всем веб-разработчикам. Каждый сможет найти в ней что-то интересное для себя — и подходы к решению проблем, и удобные сервисы, которые пригодятся при выполнении ежедневных задач.
Когда мы слышим слово «реанимация», большинство людей представляет яркую медицинскую лампу над операционным столом и толпу врачей вокруг пациента. Все действуют быстро и слаженно, ведь от них зависит жизнь человека. Разработчики, конечно, не спасают человеческие жизни, но нервы пользователей уж точно могут поберечь. Подобными «операциями» ежедневно занимается наша команда — оптимизирует работу сайтов на Magento. По сути, это та же «реанимация»: специалисты восстанавливают резко нарушенные или утраченные жизненно важные функции системы. За годы практики мы сформировали чек-лист, который поможет разработчикам выполнять эту задачу быстрее, легче и качественнее.
Почему Magento
Magento — одна из самых популярных открытых е-commerce систем для организации онлайн-торговли. Обычно сайты на Magento разрабатывают для крупных интернет-магазинов с десятками и сотнями тысяч товаров. Сегодня на базе этой CMS-платформы создано уже более 100 000 таких площадок. Открытый исходный код и множество готовых модулей помогают разработчикам воплотить любые бизнес-идеи. И всегда будут находиться владельцы бизнесов, которым надо будет продвигать сайты в Google. Поисковик оценивает работу сайта и по количеству ошибок. Если компании-конкуренты продают такой же продукт и их сайт работает лучше, то он будет в поисковой выдаче гораздо выше.Первые симптомы, или Когда на сайте что-то пошло не так
Зачастую никто не приходит с четким запросом: исправить определенную ошибку. В большинстве случаев клиенты говорят, что количество заказов уменьшилось или вовсе не растет с момента запуска сайта. Возможно, с ним что-то не так, и это нужно проверить. Заказов может быть мало не из-за того, что в магазине нечего купить или товар плохой, а потому что половина страниц не открываются, долго грузятся или по ходу оформления заказа на сайте происходят ошибки. И только удачливый и усидчивый покупатель сможет дойти до конца и отдать магазину свои деньги.Для исправления работы сайта наша команда использует базовый чек-лист. Мы смотрим, какие в нем есть проблемы и доводим его до рабочего состояния, чтобы людям было удобно пользоваться площадкой, а владельцу бизнеса — увеличивать количество довольных покупателей и развивать онлайн-торговлю.
Как мы оптимизируем работу сайтов на Magento
Шаг 1. Проверяем инфраструктуру
В первую очередь мы анализируем, какая у сайта инфраструктура: в какой среде выполняется код, насколько текущие настройки соотносятся с его ресурсами. Бывает, что он потребляет гораздо больше оперативной памяти, чем доступно. Два-три человека зашли на сайт, перегружают его, и уже для одного из них работает, а для другого — лежит. Тогда думаем, что можно сделать: оптимизировать работу или просто добавить оперативки, и на этом все решится.Если мы видим проблемы в инфраструктуре, надо сперва решить их, прежде чем двигаться дальше. Без того, чтобы нормально настроить окружение сайта (операционную систему и все программы, обеспечивающие его работу), мы не сможем решить базовые проблемы сайта.
Операционка — это среда, в которой работает сайт, это основа его программного окружения. Это воздух, который снабжает весь организм. Не поместив сайт в удобное для него окружение, мы не сможем поддерживать его функции в нормальном состоянии. Устаревшая или убитая операционная система, которая уже не подлежит апгрейду — первый признак того, чтобы переносить сайт на новую инфраструктуру. Ведь проще настроить все заново на новом «железе» или на другом сервисе.
Если мы имеем дело с интернет-магазином на Magento, смотрим, на каком хостинге и сервере он развернут, какая используется операционная система, какой у него веб-сервер. Обязательно проверяется наличие SSL-сертификата, необходимого для HTTPS-подключения. Считайте, что если у вашего сайта нет HTTPS-подключения, то вас нет в интернете. Google просто игнорирует или выдает самый низкий рейтинг вашему ресурсу. Этот сертификат бесплатный. К тому же он настолько легко настраивается, что грех его не иметь. В интернете найдете множество статей по настройке SSL-сертификата. Наверное, только ленивый не подключит его на свой сайт.
Также нужно обращать внимание на то, как настроен сертификат. Он может работать, но внешние сервисы все равно будут на него ругаться, мол, сертификат не так настроен. Особенно это важно при работе с платежными сервисами. Существуют специальные сервисы, позволяющие проверить качество настройки сертификата.
Шаг 2. Анализируем внешние сервисы
Кроме того, смотрим, с какими внешними сервисами взаимодействует сайт. Например, Google-карта выводится практически на всех сайтах, когда надо указать местонахождение магазина или склада. И здесь есть распространенная проблема. Несколько лет назад Google внедрил обязательное использование API-ключа для карты. Но к нам до сих пор приходят клиенты, у которых карта не открывается, просто потому что они не добавили этот ключ.Шаг 3. Проверяем нагрузку на сайт
Когда это сделано, выясняем, какая текущая нагрузка на сайт: сколько посетителей приходит за сутки и сколько заказов оформляется. Лучше всего зайти в Google Analytics — там есть все нужные нам графики по посещению ресурса. Исходя из этой информации мы понимаем, какая сейчас нагрузка и что будет с сайтом при возможном ее увеличении. Мы общаемся с клиентом и узнаем, что нового он планирует внедрять на платформе или когда ожидает приток клиентов в связи с распродажей. Во время массовых скидок и акций на сайте может быть взрывная нагрузка, и к этому стоит подготовиться.Шаг 4. Считаем параметр TTFB (Time to first byte)
Time to first byte — это время нашего ожидания до получения первого байта от сервера. Грубо говоря, сколько времени проходит с момента нажатия на ссылку в Google до того, как пропадет поисковая страница, вы увидите белый экран и сайт начнет загружаться. Этот процесс уже считается первоначальной нагрузкой. Мы анализируем, как изначально настроен сервер и насколько быстро поступает от него ответ. Если отклик от сервера по основным страницам сайта медленный, разбираемся, чем это вызвано.В новой версии Magento TTFB может быть около секунды, в более старых — в районе двух секунд. Стоит отметить, что речь идет о страницах, которые не были закешированы. Если кеш правильно организован, то страница прилетает к нам примерно за 200–300 миллисекунд. Отчасти это может временно решить проблему с медленными страницами.
Шаг 5. Включаем и настраиваем кеширование страниц
Затронем еще один важный аспект в анализе работы сайтов — кеширование страниц. Magento построена на кеше. Самая основная функция системы — кешировать все, что можно, и из кеша вытягивать нужные пользователю страницы. За счет этого сайты на Magento быстро работают.Кешируются страницы, на которых контент обычно меняется не сильно (главная страница, каталог, продукты, контакты). Когда загружается новая страница, она генерируется веб-сервером впервые — ее еще нет в кеше. Magento рендерит хедер с главным меню, затем — контент этой страницы, потом — футер. В нормальной ситуации, чтобы сгенерировать это все, Magento тратит 1–2 секунды. Если страница не изменяется, нет смысла заново генерировать ее при каждом следующем запросе. Можно положить уже сформированную страницу в кеш и выдавать посетителям готовую страницу.
К нам попадали сайты, на которых кеш был вообще выключен. Возможно, предыдущий разработчик не знал, как работать с Magento-кешом, и поэтому отключил его. Тогда мы разбираемся, что разработчик менял на сайте, что дописывал в коде, если нужно — исправляем, проверяем, как работает ресурс, и, естественно, включаем кеширование. Без него сайт не сможет «летать».
Иногда предыдущие разработчики оставляют свои наработки, которые ухудшают текущее состояние сайта. Программист написал что-то, запустил, вроде работает. Но он не учитывал, как все сложится в будущем, когда нагрузка на сайт вырастет. От его прошлых нововведений сегодня сайт может проседать. У нас была ситуация, когда на странице каталога неправильно организовали запросы в базу данных. Вместо 100–200 запросов для генерации всей страницы там было несколько тысяч. Это сильно нагружало сервер и тормозило страницы. Мы переписали одну небольшую часть кода, и сайт резко «взлетел».
После того как мы разобрались с кешом, убедились, что он включен и быстро открывает страницы, приступаем к анализу ошибок на сайте.
Шаг 6. Анализируем ошибки на сайте
Нам надо отловить все ошибки, разобраться, почему они происходят, откуда взялись и все исправить. В Magento ошибки хранятся в двух местах: в папке var/report и в файле exception.log. В последнем обычно происходит ротация логов, и они не хранятся там долго. А вот report предыдущие разработчики могут забыть почистить, и здесь для нас самое интересное. По одному типу ошибки могут быть сотни файлов. Каждый файл — это ошибка, которую пользователь увидел у себя в браузере. Мы группируем их, выделяем самые критичные, которые непосредственно влияют на процесс покупки, и ранжируем все остальные по степени опасности для сайта. Исправляя одну ошибку, мы одновременно закрываем всю группу репортов, связанную с ней.Иногда, исправляя что-то, мы открываем доступ к ранее неизвестному функционалу. Поэтому мой вам совет: прежде чем исправить баг, разберитесь, чем он был вызван, надо ли его сейчас чинить именно так. Возможно, это лишь следствие другой ошибки и исправлять надо в другом месте. Также бывает, что ошибка блокирует доступ к какому-то ужасному функционалу, который положил бы сервер и сайт. Так что это не баг, а фича, которая спасала сайт все это время.
А бывают и совершенно дикие баги. Помню, нам достался сайт, на котором домашняя страница не открывалась без указания языка в адресе. Язык дописали руками — ресурс заработал. Не понятно, как посетители добирались до продуктов, если при входе на первую же страницу появлялась ошибка.
Шаг 7. Оптимизируем статический контент
Статический контент в Magento 2 — это стили сайта (CSS), скрипты, которые выполняются в браузере (JavaScript), и HTML-файлы, которые используются в этих скриптах. Если не настраивать никакой оптимизации для этого контента, то сайт будет довольно медленный, плюс ко всему будет создавать дополнительную нагрузку на сервер, так как в Magento вся статика раздроблена по отдельным файлам. Например, зайдя на страницу Checkout, вы скачаете около 500 JavaScript файлов.Для оптимизации в Magento включается сборка всего JavaScript в бандлы. Вместо того чтобы скачивать каждый раз по 500 файлов, они все собираются в «пачки», и мы уже качаем с десяток файлов. Минус этого подхода в том, что каждый раз придется качать весь JavaScript. Однако, если правильно настроить браузерное кеширование, эти скрипты будут кешироваться в браузере, их нужно будет скачивать только раз. При следующем посещении сайта весь JavaScript будет загружаться из кеша браузера. Есть и другой, более сложный подход без этих проблем — Advanced Bundling.
При использовании браузерного кеширования стоит убедиться, что все настроено правильно. Представим, что мы зарелизили новую фичу. Для ее работы изменили CSS и JS. Соответственно, новой функцией на сайте смогут воспользоваться только те, кто заново скачает весь статический контент. Но для тех, у кого эти файлы сохранены в браузере, это произойдет только в том случае, если URL файлов будет изменен.
В Magento есть функция подписывания статического контента. В адрес статического файла дописывается строка (Unix Timestamp), которая обновляется вслед за каждым следующим деплойментом. Таким образом, когда мы будем «выливать» на сайт что-то новое, эта строка будет обновляться и на сайте появится новая ссылка на статические файлы. Браузер просто заново перекачает последнюю версию CSS и JS.
Шаг 8. Проверяем интеграции с внешними сервисами
Когда пользователь заходит на сайт, выбирает продукт, оформляет заказ и оплачивает его, для посетителя на этом все заканчивается, а для владельца сайта — только начинается. Существуют различные внешние сервисы, которые позволяют организовать дальнейшую обработку заказа из Magento. Например, передадут данные на склад, где товар упакуют и через почтовый сервис отправят покупателю.Бывают ситуации, когда внешний сервис привязан к IP-адресу текущего сервера. Если мы переносим сайт на новый сервер, у него изменится IP-адрес и автоматически заблокируется доступ к сервису, который оформляет заказы. Разработчикам надо быть заранее готовыми к такому сценарию: прописать новый IP-адрес в этом сервисе, чтобы не потерялась возможность оформлять заказы.
Владельцы сайтов с большим количеством продуктов обычно используют сторонние системы для управления стоком, так как зачастую эти данные надо собирать из нескольких источников. При любых изменениях на сайте важно не сломать работу этих систем, иначе сайт может начать продавать продукты, которых нет в наличии или наоборот — не показывать новые поступления. На старте нужно собрать как можно больше информации об этих интеграциях.
Хорошо, когда предыдущая команда оставляет документацию об интеграции с внешними сервисами, но такое бывает редко. Обычно мы ищем контакты прошлых разработчиков и пишем им напрямую, чтобы выяснить, с чем у сайта есть интеграции и как они работают. Либо собираем по крупицам информацию от владельца сайта, расспрашиваем его на звонках и анализируем доступный код и логи. После сбора данных и их анализа формируем документацию, по которой и нам проще работать, и клиенту видно состояние его сайта.
Шаг 9. Мониторим состояние сайта
Ошибки исправили, все оптимизировали, сайт отлично работает. Но на этом дело не закрыто. Всегда надо контролировать, что происходит с ресурсом после наших вмешательств. Нужно трекать ошибки на сайте и, если к вам обратится клиент, иметь возможность объяснить ему их причины. Это поможет вам улучшить качество работы сайта, сэкономить ваше время и нервы.Одни сервисы могут мониторить состояние инфраструктуры: насколько хорошо работает сервер, хватает ли оперативной памяти, насколько загружен диск, когда истечет срок действия сертификата. А другие — контролировать работу самого приложения. Лучше использовать все. Например, случилась ошибка, вызванная нехваткой какого-то ресурса. Мы видим в одном мониторинге по ресурсам, что у нас переполнен диск, а в другом — что в приложении посыпались ошибки. Анализируя информацию с обоих сервисов, мы получаем полную картину происходящего, даже не заходя на сайт.
Также важно иметь удобную нотификацию из этих сервисов. По умолчанию везде уведомления отправляются на почту. Как показывает практика, иногда из-за большого количества писем важные уведомления могут потеряться, особенно это относится к мобильным почтовым клиентам. А вот за чатами, которые пишет бот, следить гораздо удобнее. Так вы быстрее сможете узнавать о проблемах на сайте и оперативно решать их.
Для мониторинга за инфраструктурой мы используем такие приложения:
- Zabbix;
- Influxdb.
- Tideways;
- New Relic.
Отучите клиента заниматься «самолечением». Взамен дайте ему удобный сайт
Клиенты, которые сами пытаются отладить работу сайта, напоминают тех, кто занимается самолечением, а не идет к врачу. Человек что-то где-то вычитал, кое-как реализовал, вроде работает. Один-два раза он еще сам справится. Но когда дело доходит до развития функциональности, появляются сбои. То, что клиент когда-то внедрил сам, может перегружать сайт. И уже специалистам приходится все переделывать, да еще и зачастую в очень сжатые сроки.Если вы владелец сайта и читаете эту статью, советую вам сразу обращаться к разработчикам. А девелоперам — стараться докапываться до сути проблемы. Если в ошибке сказано, что у вас нет какого-то параметра, не нужно просто так его дописывать. Разберитесь, нужен ли он там, нужна ли эта функциональность. Может, не стоит дописывать параметр, а лучше сделать исправление в другом месте, которое вызывает эту функцию.
DOU
DOU – Найбільша спільнота розробників України. Все про IT: цікаві статті, інтервʼю, розслідування, дослідження ринку, свіжі новини та події. Спілкування на форумі з айтівцями на найгарячіші теми та технічні матеріали від експертів. Вакансії, рейтинг IT-компаній, відгуки співробітників, аналітика...
dou.ua