Как повысить средний чек? Учимся у МакДональдса

Что нужно сделать, чтобы компания могла зарабатывать больше денег прямо сейчас? Берём пример с МакДональдса!

В прошлом веке маркетологи МакДональдса поняли, что люди очень часто заказывали один лишь гамбургер. Поломав головы, они решили провести эксперимент: каждый продавец принимая заказ, перед пробитием чека должен спросить у клиента — «Не хотите ли вы картошечки с вашим заказом?»

Старое меню МакДональдса - большие возможности для апселла

Оказалось, что половина клиентов брала картошку фри в дополнение к гамбургеру. Цена этого эксперимента для сети — примерно 10 секунд времени работника на кассе на каждого покупателя. Сейчас, каждый день, сеть МакДональдс продает порядка 5000 тон картошки в день. Я не смог найти точное число денег, которое удалось заработать благодаря этому решению, но счёт идёт на миллиарды долларов. Теперь, в каждой сети фаст фуда вам предложат взять картошку, соус, пирожок или колу к вашей покупке, в зависимости от размера вашего чека и состава заказа.

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

Схематичное изображение апселла на примере кофе и маффина

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

  1. Входящий поток клиентов
  2. Размер среднего чека
  3. Количество повторных покупок

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

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

Апселл в действии

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

Про PiterJS 13

Делюсь с вами впечатлениями и знаниями с piterjs 13!

Я сходил на PiterJS 13, который прошел в Селектеле, ниже информация, которую я почерпнул от докладчиков.

Re-imagining Webpack

Оказалось, что в Хельсинки одновременно с PiterJS проходил митап про react, и доклад Юхо Вепсалайнена мы слушали через скайп. Юхо рассказал про путь появления вебпака из не принятого пулл реквеста (#меняневзяли), про того, каких успехов добилася проект и показал красивые экспоненциальные графики роста скачиваний. Вот несколько интересных фактов и идей, которые я запомнил из его рассказа:

  • Вебпак хотят децентрализовать, отделить разработку ядра от разработки различных лоадеров. Для них есть отдельное сообщество, где ссылки на все репозитории есть в одном месте, очень удобно;
  • Вебпак принимает пожертвования через платформу Open Collective, вы можете видит все траты на проект и отправить деньги в помощь, в идеале, автор хочет работать над вебпаков фул-тайм и это вполне возможно с помощью этого механизма;
  • Можно голосовать за фичи, которые будут у разработчиков в приоритете на специальной странице;
  • Юхо написал книжку про вебпак (и ещё одну про реакт), её можно бесплатно прочитать тут или купить через leanpub.

Документация кода в JS

Вадим Горбачёв рассказал про то, как писать комментарии так, чтобы они были понятными. В целом, советы применимы к любому языку, самое важное:

  • Старайтесь, чтобы названия переменных и методов объясняли, что они делают;
  • Обязательно комментируйте код, в котором есть высокий уровень сложности, какие-то хаки и сюрпризы;
  • Автоматизируйте процессы — используйте автогенерацию и линтеры;
  • Указывайте в комментариях используемые единицы измерения и допустимые диапазоне;
  • Прочитайте книги «Code Complete» и «Clean Code».

А видео можно посмотреть по этой ссылке.

Нужен ли мне TypeScript?

Александр Баумгертнер попытался разобраться, нужна ли типизация и можно ли без неё обойтись. В качестве альтернативы TypeScript’у и Flow, Александр предлагает использовать очевидные названия переменных и функций, а для удобства работы в редакторах использовать простые JSDoc аннотации.

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

  • Без использования внешних инструментов, требуется, что все участники разработки обладали достаточной дисциплиной для написания кода в «правильном» стиле, а это сложно, особенно когда разработчики разного уровня;
  • Необходимость писать аннотации типов для абсолютно всех вещей в коде, даже тех, которые никто не увидит. Это требует колоссальных усилий, а качество комментариев понижается из-за чисто технический записей;
  • Иногда бывает сложно придумать очевидное название для функции, или в некоторых случаях, как например с переменной, которая содержит дату, тип этой переменной может быть непонятен и можно с ней совершить неправильно операцию. В случае с типизацией, код не скомпилируется, а без проверок — упадёт в рантайме;
  • Падение в яму провала — поддерживая руками типы вместо использования автоматических инструментов, вы увеличиваете вероятность появления ошибки, которая рано или поздно произойдёт и приведёт к проблемам.

Дискуссия интересная, поэтому я советую посмотреть видео тут.

Про #pitercss 11

Делюсь с вами впечатлениями и знаниями с pitercss 11!

Про «Semrush»

21 марта в питерском офисе компании Семраш прошёл митап про вёрстку и дизайн. Отдельно хочется отметить Семраш, не так много компаний с российскими корнями хорошо известны на западе, например, недавно Ноа Кэйган, маркетолог и бизнесмен упомянул продукт в своем блоге (Ноа сам по себе интересный человек и активно делиться своими знаниями, советую подписаться). Такие компании всегда ищут людей и это хороший вариант для работы. Лично я люблю больше компании, которые разрабатывают свой собственный продукт, а компаний такого размера, которые не были бы аутсорсерами в СПб можно пересчитать по пальцам руки. Поэтому вот ссылочка на вакансии, если вы в раздумьях о своём будущем — посмотрите позиции,  уверен, что что-то вас заинтересует.

Относительный CSS

Первым выступил Валерий Любимов  рассказал про относительные величины в CSS — rem, vw, vh, vmax, vmin и currentColor. Лично для меня это были новые вещи, потому что за CSS я не особо слежу, хотя про rem слышал.

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

Аналогичную экономию труда предлагает rem — единица измерения, которая вычисляется относительно корня html, а не от текущего размера шрифта, как у простого em. В сложном коде бывает непросто понять, от какого именно размера считается em, в случае с rem вы всегда знаете число и для изменения размеров под разные вьюпорты с помощью медиа-выражений достаточно в одном месте задать разные варианты размера font-size для тега html, чтобы получить адаптивность для всего проекта. Из минусов rem-ов можно отметить сложность создания изолированных компонентов, так как появляется жесткая внешняя зависимость от размера тега html, возможные проблемы с браузерным зумом и сложность конвертации абсолютных величин из макета дизайнера в относительные величины от размера шрифта, не уверен, что тут можно получить пиксель-пёрфект верстку.

vw, vh, vmax и vmin — позволяют задавать размер в процентах от вьюпорта, что супер полезно, когда вы хотите разместить блок на весь экран, например для лайтбоксов или промостраниц, можно заменить javascript код на простой изящный CSS. Правда, тут есть свои особенности, связанные с подсчётом ширины скроллбаров и адресной строки, которая исчезает в браузерах.

Презентация доклада: https://pitercss.ru/11/pres/relative-css/

Учите дизайнеров верстать

Дизайнер Вадим Матвеев рассказал зачем он научился верстать. Оказалось, что знания верстки даёт кучу преимуществ всей команде.

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

Презентация доклада: https://pitercss.ru/11/pres/design-code.pdf

Дизайн-системы. В поисках «идеального компонента»

Роман Ганин рассказал про дизайн системы и показал, как очень легко можно превратить обычный параграф текста в интерактивный и информационный веб-документ минимальными средствами без кучи фреймворков. Посмотрите презентацию: https://pitercss.ru/11/pres/ideal-component/

Фронтендер + Дизайнер = ♥

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

Субботний переполох

Вчера я сидел, попивал кофе и смотрел забавные видеоролики на ютюбе. Вдруг мне приходит смс от сервиса мониторинга, оказалось, что GoDesigner не отзывается…

Прекрасный субботний день

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

А они точно сохраняются?

Тут я решил проверить, как там поживают бэкапы, и к своему шоку обнаружил, что файлов не хватает. Бэкапы файлов (а это в нашем случае огромное количество картинок) не полностью соответствуют тому количеству, которое должно присутствовать. Я запустил процесс бэкапа с выводом информации и понял, что процесс зависает при копировании случайного файла! Вот такой неприятный сюрприз.

Копирование производилось с помощью программы rsync вот такой командой:

Во время вывода я обратил внимание на большое количество ошибок, связанных с отсутствием прав на смену прав доступа (простите!) для файлов на бэкап сервере. Погуглив, оказалось, что  проблема с зависанием возникает довольно часто, но по разным причинам. Прогнав команду strace, я решил, что при попытке присвоить нужные права, при зависании, происходило бесконечное ожидание ответа. По крайней мере, такова моя интерпретация логов.

Решение

Я решил убрать из команды все опции, связанные с установкой владельца, прав и времени и команда выше превратилась в

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

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

Стоит дополнить чеклисты двумя пунктами:
1) Убедится, что бэкап завершается правильно и все файлы копируются;
2) Убедится, что можно восстановить файлы обратно/

Rsync hangs up/stop working

English TL;DR:

If your rsync hangs up/stop working in a middle of uploading on seemingly random file, make sure you enable verbose mode with -v option and run it again. If there are lot of «permission denied» errors, you should try run rsync without trying to preserve all access file rights, owner and time. If you are using -a options, replace it with -rlD whis is -a without options that deal with file metadata. It helped my backup, and may help yours. See above example bash script for reference. It very well maybe that you have totally another problem. You may use strace utility, which writes all activity of other command in log file. Analyzing this log file, may help figure out why process stops. Use following commands to do this:

 

Настройка сервера

Краткий гайд про то, как можно настраивать nginx, php-fpm и mysql для оптимального потребления ресурсов сервера.

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

Настройка Nginx

Веб-сервер Nginx обладает огромным количеством настроек и с нуля во всех разобраться довольно сложно. Я советую вам взять за основу структуру конфига с уже заданными неплохими значениями от проекта H5BP.

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

Если вы хостите php сайты, то вам необходимо добавить примерно такой кусочек, который можно назвать php.conf:

Имейте в виду, что следует продумать, какие именно php файлы вы хотите исполнять, и, возможно, ограничить их одним файлом или директорией.

Для современных CMS и фреймворков, которые используют паттерн FrontController, вам нужно направлять все запросы на файл index.php. Ниже вариант конфига для WordPress и пара вариантов для фреймворков:

Вот два сайта, которые служат хорошим источником информации про nginx:
http://nginx.org/en/docs/
https://www.nginx.com/resources/wiki/

Настройка PHP-FPM

Настройка php-fpm — самая простая вещь. Задача заключается в том, чтобы посчитать, какое максимальное количество процессов запустить на вашем сервере. Математика следующая:

pm.max_children = (Общее количество свободной RAM — Резерв для системы) / Размер памяти для одного процесса.

Важный нюанс! Под общим количеством свободной памяти имеется в виду не физическая память, а то, сколько осталось памяти после того, как вы вычли память для базы, redis, memcache и прочего. Учитывайте, что на эти системы может уйти гигабайты памяти в зависимости от настроек. Тут следует подумать, что важнее — больше память для хранения и быстрого извлечения данных или же большое количество php процессов наготове.

Узнать средний размер потребления памяти для php процесса можно так:

500 мегабайт мы оставляем в резерв системе, тоже довольно гибкая цифра, её можно увеличить, если кажется, что 500 мегабайт недостаточно для нормальной работы.

Чаще всего я встречал использование динамического процесс менеджера, как наиболее гибкий вариант. Ниже я привожу пример конфигурации для сервера с 16 ГБ памяти. С учетом базы данных и прочего софта, у нас остаётся 6 ГБ свободной памяти, а команда показала, что в среднем наш процесс потребляет 90 мегабайт.

Новые настройки войду в силу после перезагрузки сервиса.

Настройка MySql

Настройки mysql-совместимой базы содержатся в файле my.cnf. Ниже опции, которые имеет смысл отредактировать:

Как узнать, сколько наш диск может операций в секунду:

В таблице результатов нас интересует среднее между read iops и write iops, значение в конфигурации для базы не должно превышать цифры в результатах.

После любых изменений, следует промониторить потребление процессоров и память, быстродействие. Иногда, приходится корректировать цифры, потому что расчётные значения могут не соответствовать реальным цифрам. Также не забывайте, что проверять следует на реальной нагрузке, цифры при спящем трафике могут разительно отличаться от полноценной дневной нагрузки. Самый просто способ — команда top, более продвинутые и удобные способы мониторинга — сервисы вроде NewRelic или Nginx Amplify

Надеюсь, это информация поможет вам при настройке вашего сервера.

Я был в шоке, когда понял, от чего возник баг

Иногда баги могут возникать на пустом месте. Я даю совет, как можно избежать ряда неожиданного и неправильно поведения в программе.

Непонятный код

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

Двойные отрицания в коде

Проснувшись утром, выпив чашку кофе, я вернулся к этому чудо-коду, расставив брейкпоинты, я стал исполнять код по шагам. И вскоре я нашёл ошибку в логике. Проблема была в следующем коде:

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

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