[reposted post]Быстро и качественно. Законы макета.
Евгений Теслов
ziik
reposted by rawgift
0. Закрываем фотошоп
Каждый раз, открывая чистый лист в фотошопе для нового проекта, начинающие и не только дизайнеры сталкиваются с вопросом — что дальше? У каждого из них есть свои методики создания первого пикселя, я же расскажу о том, что я обычно рекомендую делать перед началом любого проекта.


1. Определяем требования к сайту

Если вы не получили их от клиента/менеджера/проект-менеджера, вы должны их принять самостоятельно, обязательно. Всего существует 3 основных видов требований:

а) БТ; Бизнес-требования (интсрументы бизнеса, цель ← задачи): как правило их три — лицо компании, инструмент продаж и/или развитие бизнеса. Лично я всегда стараюсь выделить одно основное.

б) ТУ; Требования участников проекта (о них всегда забывают): сайт как помощник сотрудника компании и часть бизнес-процессов (директор, маркетолог, юрист, логист, менеджер и т.д.).

в) ТП; Требования внешних пользователей: рассматриваем сайт как инструмент продаж товаров и услуг через интернет, целевые аудитории, сценарии пользователей (достаточно 1-3 сценариев).


2. Рефы сайтов

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

Хорошие художники копируют, великие художники воруют. © ПП

Тем более что проблем с этим сейчас нет: awwwards.com, revision.ru, behance.net, рейтинг рунета, один крутой японский сайт, inspiration.genue и т.д.


3. Думаем

Мой любимый пункт. На основании всего что у нас есть выше делаем быстрый скетч от руки. Всегда. За 5-10 минут для быстрой проверки. А чтобы было веселей, делаем его на re-print.me цветными карандашами.


4. Членение и соподчинение

На том же самом листе разбиваем всё на логические блоки и видим/создаём подчинённость.
Что важнее, что следует из чего, может что-то стоит выкинуть/разделить? Выкинуть что-нибудь обязательно!

Фотошоп не открываем!


5. Сетка и направляющие

Направляющие/Сетка всегда помогут не потеряться в пути, это Нить Ариадны для любого дизайнера (а еще и получить ободряющий кивок от технолога), и не важно, промо-сайт это или корпоративный портал.

Гуглим, читаем thegrids.ru или выбираем 960.gs, gridpak.com и т.д. GGS в тренде ;)

upd: для тех, кто не выдержал и открыл фотошоп → генератор сеток для фш guideguide.me

6. Шрифтовая схема

Как минимум, это:
— Базовый // основной контент
— Акцидентный // заголовки
— Меню/навигация
— Блок выделения // цитаты
— «Мелкий текст» // подсказки

Со временем, в голове каждого дизайнера формируются готовые наборы. Но всегда есть подсказки, например, lamb.cc/typograph/


7. Цветовая схема

Выбираем 5-10 основных/вспомогательных цветов. kuler.adobe.com — кулер нам в помощь.

Кстати, в кулер можно закинуть фотографию, например, с природы. В ней всегда и всё гармонично. А начиная с 5-х версий Kuler вообще — часть продуктов Adobe, покопайтесь в настройках.


8. Открываем фотошоп

Итого, потратив 30-40 минут в самом начале, мы сократим время разработки каждого и любого экрана проекта минимум в 2-3 раза. Хэй-хэй!


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



Небольшой Javascript чек-лист
rawgift
Этот «чек-лист» — второе приятное впечатление от Инновы полуторамесячной давности, когда я написал 100 строк кода, а Паша Моторин отревьюил их по-быстрому. До этого я писал джаваскрипт в одиночку в течение 3 лет, чужим кодом не интересовался (потому и заскучал в итоге) и вообще находился в информационном вакууме.

1. Single var pattern
Все объявления переменных надо размещать в самом начале функции, потому что в джаваскрипте переменная видна во всей функции, где бы она ни была объявлена. Пренебрежение этим правилом чревато возвратом значения «undefined» для переменной, которая по логике программиста ещё не существует (т.е. объявлена позже):

(function() {
    var def = 10;
    alert(def * undef); // 10 * undefined = NaN
    var undef = 20;
})();

Если убрать объявление undef, то интерпретатор сгенерирует ошибку и обидный косяк будет найден. 

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

var $button = $('button.my'); 
$button.each(function() { ... });

Вроде бы ничего ужасного, но плохо становится, когда таких кусков в функции большинство. А именно так и хочется писать, когда заранее не продумываешь функциональность. На самом деле, single var pattern заставляет лучше продумывать архитектуру программы и делать это заранее. Я сторонник немного избыточного подхода, когда даже очень простой модуль из 50 строк пишется грамотно, чтобы сейчас было легко его понять, а потом — безболезненно расширить.


2. Проверка undefined-переменных
Часто стоит проверять не тип переменной и её истинность, а её неистинность. Т.е. вместо привычной мне проверки if (typeof variable !== ‘string’ && variable) стоит разворачивать условие наизнанку и писать if (!variable) { return; }  Проверять потенциально необъявленные переменные можно только первым способом, иначе есть вероятность нарваться на тот самый ReferenceError.

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


3. Правильные сравнения
Сишный стиль сравнения переменной с константой if ('value' == mystring) { ... } стоит забыть как страшный сон как минимум по 2 причинам.
Во-первых, оператор присвоения «=» и оператор строгого равенства «===», рекомендуемый Крокфордом, уже сложно перепутать. 
Во-вторых, typeof variable === 'string' читается намного лучше, чем 'string' === typeof variable.


4. Кэширование
Я часто использовал объекты-неймспейсы, чтобы не засорять глобальный объект своим барахлом:

var MySite = {};
MySite.pages = 10;


Удобно кэшировать обращения к таким объектам внутри функции: var MySite = window.MySite. И вообще имеет смысл кэшировать все объекты, находящиеся во внешнем scope — window, document и т.п., — если к ним нужно обратиться больше одного раза. Тем более в цикле!

Для примера создадим массив из 100 тысяч случайных чисел, а потом вычислим квадрат каждого внутри анонимной функции. В первом случае интерпретатору приходится каждый раз вылезать в scope-объект верхнего уровня, во втором — нет. Третий случай эталонный, т.к. scope остаётся глобальным.
Скопируйте и выполните этот код в браузере.

window.x = [];
for (i = 0; i < 100000; i += 1) {
    window.x[i] = Math.random() * 100;
}
(function() {
    var i;
    console.time('uncached');
    for (i = 0; i < 100000; i += 1) {
        window.x[i] *= window.x[i];
    }
    console.timeEnd('uncached');
}());

for (i = 0; i < 100000; i += 1) {
    window.x[i] = Math.random() * 100;
}
(function() {
    var i,
    wx = window.x;
    console.time('cached');
    for (i = 0; i < 100000; i += 1) {
        wx[i] *= wx[i];
    }
    console.timeEnd('cached');
}());
for (i = 0; i < 100000; i += 1) {
    window.x[i] = Math.random() * 100;
}
console.time('global');
for (i = 0; i < 100000; i += 1) {
    window.x[i] *= window.x[i];
}
console.timeEnd('global');

(function() {
    var x = [],
    i;
    for (i = 0; i < 100000; i += 1) {
        x[i] = Math.random() * 100;
    }
    console.time('local');
    for (i = 0; i < 100000; i += 1) {
      x[i] *= x[i];
    }
   console.timeEnd('local');
}());

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

5. Правильное именование событий
До этой штуки я без Паши точно не додумался бы — вот так бывает необходим взгляд со стороны. 
Я начал пользоваться кастомными событиями достаточно давно и часто писал что-то вроде: $(document).trigger('popup-start-handling'), т.е. дословно указывал на необходимость начать определённую процедуру — обработку открытия попапа.

Однако это в корне неверно, т.к. в названии события должна отражаться суть произошедшего: $(document).trigger('popup-appear'), например. И уже множество возможных слушателей сами решат, что им делать: то ли start-handling, то ли stop-destroying.


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

$(document).on('click', function() { alert('a'); });
$(document).on('click', function() { alert('b'); });
$(document).on('click', function() { alert('c'); });
$(document).on('click', function() { alert('d'); });
$(document').off('click'); // ??? Warning! All click handlers are removed.


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

$(document).on('click.mine', function() { alert('a'); });
$(document).on('click.mine', function() { alert('b'); });
$(document).on('click.mine', function() { alert('c'); });
$(document).on('click.mine', function() { alert('d'); });
$(document).off('.mine'); // OK!

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

Удаление не всех обработчиков в соответствии с DOM Events
Код, приведённый в примере выше, однозначно плох: не стоит плодить сущности и создавать несколько функций с кодом обработчиков. Ведь в отличие от кода, написанного кем-то до нас или встроенного в браузер, свой код мы контролировать можем: надо переписать код так, чтобы получилась одна функция. Дальше делаем функцию именнованной, задаём её в качестве обработчика и — бинго! — мы можем удалить именно этот обработчик, когда потребуется:

var handler = function() {
    alert('a');
    alert('b');
    alert('c');
    alert('d');
}
document.addEventListener('click', handler);
document.removeEventListener('click', handler); 

Работает такой код не хуже, а организован, на мой взгляд, правильней. Что использовать — выбирать вам.
Наверняка джикверные неймспейсы работают на основе этой документированной возможности — за 5 минут разобраться не удалось.

Отказ от инициализации вместо её повторения 
Я часто использовал приём с удалением обработчика, чтобы застраховаться от нескольких выполнений одного и того же кода. Когда-то, видимо, натнулся на то, что галерея может проинициализироваться дважды и слайды будут листаться по 2. Понял, что это не дело, ну и придумал писать что-то подобное: 1) удаляем результаты предыдущей инициализации, 2) вешаем новый ТОТ ЖЕ САМЫЙ код.

Андрейка смотрел-смотрел на то, что я делаю, а потом открыл мне глаза на жизнь: намного логичней не проводить инициализацию заново, оставляя всё тот же обработчик события, а просто определять, была ли инициализация и ненужный код не выполнять. Бинго! 

Как правильно верстать почтовые рассылки
rawgift
Essence: рассылки верстаются таблицами, максимально просто и без изысков. Поменьше фоновых картинок, inline-стили, и всё с вашей рассылкой будет в порядке.

Когда я только пришёл в Иннову, мне приходилось верстать почтовые рассылки для наших многочисленных игр. До этого я опасался вёрстки под почтовые клиенты, но оказалось, ничего страшного в этом нет. Если верстать так, как верстали 10 лет назад.

Все наблюдения, описанные ниже, были проверены в веб-клиентах (Gmail, Mail.ru, Яндекс.Почта, Yahoo и Hotmail) и в десктопных программах (Outlook Express, Outlook 2010, The Bat!). На удивление, Outlook 2010 капризней, чем Express, и совершенно неудивительно, что Hotmail ведёт себя самым непотребным образом.

Раскладка
Письмо — это обычная страница с произвольным доктайпом. Почтовики вырезают всё, кроме body.
Основа раскладки: растянутая на 100% по ширине таблица с одним tr и одной ячейкой. Нужно обнулить cellpadding, cellspacing и border (атрибутами) и задать border-collapse:collapse; в инлайн-стиле.
Внутрь лейаутной таблицы вкладывается табличка, внутри которой находится само письмо.

Если нужно центрировать табличку, то удобней всего обернуть её в <center></center> и задавать выключку влево там, где это нужно для текста.

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

Абсолютное позиционирование, флоаты, прочие штучки — всё это использовать нельзя.

Допустимые элементы
Я обычно использую только h1-h2, div, span, p и элементы таблицы. В принципе каких-то ограничений нет (кроме наверное HTML5-элементов), но у почтовиков свой взгляд на то, какие стили задавать семантичным элементам, поэтому вам придётся сражаться за специфичность. Нужно быть готовым к тому, что ваши стили могут быть бесцеремонно затёрты.

Font, о котором пишут в статьях, мне использовать не приходилось: прекрасно работает и задание свойств шрифта в онлайн-элементах.

Картинки, вставленные как img, никаких проблем не доставляют, надо только размеры задавать. Мейл.ру не загружает тяжёлые картинки. Например, 70 Кб для него уже перебор — лучше не использовать прогрессивный джипег :) Большие иллюстрации стоит резать на части, чтобы они загружались отдельно. 

Стилизация
Отдельные от HTML таблицы стилей и тем более каскад использовать нельзя. Вся стилизация только в инлайн-стилях. Hotmail и Yahoo воспринимают таблицу стилей в head, но рассчитывать на это нельзя. Есть исключение: для Hotmail необходимы 2 правила в таблице стилей, иначе он не будет растягивать письмо на весь экран.

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

Фоновый цвет надо задавать одновременно для body и лейаутной таблицы, а фоновую картинку — только для таблицы. Яндекс.Почта, например, игнорирует фон, заданный для одного только body (или вырезает его). Можно использовать повторяющиеся паттерны. Но всегда стоит быть готовым к тому, что ваш фон не отобразится (Outlook 2010 этим грешит), либо пользователь вообще не увидит никаких картинок, т.к. не обнаружит кнопку «показать картинки».

Если нужны фоновые картинки не только для всей страницы, то background-image нужно задавать внутренним ячейкам таблицы.

Почтовые клиенты
Gmail
Никаких аномалий не замечено.

Яндекс.Почта
Раскрашивает красным ссылки при наведении мышки, в остальном всё хорошо.

Mail.ru
Не загружает тяжёлые картинки, больше 50-70 Кб.

Outlook Express и Outlook 2010
Старый Express из Windows XP работает отлично, в нём движок от IE7, кажется. Outlook 2010 не загружает фоновые картинки.

Yahoo
Ничего особенного не заметил

Hotmail
С ним больше всего проблем.
  1. Чтобы растянуть body письма на весь экран, надо задать width:100% классам .ReadMsgBody и .ExternalClass в head. Обязательно сделать это 2 правилами, иначе не сработает.
  2. Не факт, но записано в старых конспектах: body почему-то не растягивается без правила body { margin: 0; padding: 0; }
  3. Хотмейл добавляет свои маргины. Например, правило margin: 10px 0; для абзаца будет перезаписано. Но если задавать отдельной каждый из маргинов, эту фигню можно победить.
  4. Не показываются фоновые картинки.


Бесплатный вебинар «Как работает сайт»
rawgift
Как работает сайт

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

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

Зарегистрироваться на вебинар можно оставив свой e-mail в форме на сайте. Спасибо!

Очередь задумок
rawgift
Essence: использовать очередь для организации и планирования работы в свободное время. Первая записанная идея и обрабатывается в первую очередь. 

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

Время от времени возникает состояние, когда руки чешутся сделать что-то полезное. Я очень люблю это состояние, но не умею им полноценно пользоваться.

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

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

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

Изначально мне пришла в голову идея мобильного приложения (mobile first, привет!) со слайдом влево с главного экрана, чтобы что-то записать, и вправо, чтобы посмотреть первую в очереди идею, но потом я понял, что это излишне. Пока что остановился на табличке из двух колонок — задуманное и сделанное, в каждую из которых записывается идея и даты. Теоретически это должно быть удобно, т.к. раскиданные по куче бумажек и пространно описанные (что бессмысленно, потому что ни черта из этого не делается) идеи невозможно найти когда нужно. Попробую :-)

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

Flyous — javascript-плагин для отображения картинки загрузчика рядом с курсором
rawgift
Ура, свершилось! Я выпустил первую версию своего Javascript-плагина для отображения картинки загрузчика рядом с курсором!
Для меня это событие значимо вот почему:
  • я разобрался с гитхабом и гитом (особенно прикольно, что теги автоматически собираются в архивы), прочувствовал кайф, так сказать;
  • научился сносно комментировать код, писать README.md и LICENSE, свистнул шаблон копирайта из jQuery;
  • впервые сделал что-то общественнополезное (теоретически) и выложил это на всеобщее обозрение;
  • нехило укрепил свой javascript coding скилл, т.к. написал плагин без jQuery, ещё и читая параллельно книжку «Оптимизация Javascript производительности». Всячески рекомендую!

Идея плагина родилась тогда, когда я увидел клёвую анимацию предзагрузчика у нас на Фогейме. Мне стало интересно, как это работает, но решил написать свой плагин вместо того, чтобы лезть и разбираться (во-первых, не такая сложная задача, во-вторых, я тогда со структурой кода знаком не был и видел только скомпилированные плоские js-файлы, где чёрт ногу сломит). Авось кому и пригодится!

В добрый путь, значит!


Быстродействие округления в Javascript
rawgift
Сегодня на работе задался интересным вопросом: какая из математических функций округления работает быстрей и почему — Math.round(), Math.floor() или Math.ceil(). Докопаться, почему, так и не удалось — я скачал гугловский v8, написанный на C++, но реализацию математических функций найти не смог. Слишком много кода, а времени на работе мало. Пришлось делать все выводы на основе собственных опытов.

Округление числе в Javascript

Для начала обнаруживаю, что round() и floor() работают примерно с одинаковой скоростью, а вот ceil() сильно отстаёт по скорости — разница не менее 2 раз не в пользу ceil(). Тест проводится достаточно примитивно: вызываем каждую функцию миллион раз, округляя псевдослучайное число, сохраняем результат, и так 100 раз. А потом выводим среднее арифметическое ста результатов.

Будьте аккуратны, браузер (или вкладка в случае с хромом) подвиснет секунд на 20-30!

Ради интереса добавляем вызов Number.toFixed(0), что эквивалентно вызову Math.round() — функция округляет аргумент до ближайшего целого числа. И видим, что Number.toFixed() медленнее Math.round() примерно в 10 раз, и использовать её для округления нельзя!

Ну и чтобы повеселиться от души: попробуем для «округления» использовать parseInt(). Делать этого категорически не рекомендую! Хе: на удивление, округление с помощью parseInt() работает всего в 1,5 раза медленнее, чем round(). Правда пользоваться им всё равно не стоит. А если приспичит, то обязательно указывайте второй необязательный аргумент — основание системы счисления.

Получается, что джавскриптовые библиотечные функции для округления вниз или до ближайшего целого работают хорошо, а безусловно вверх — нет. Вова Цванг рассказал, что можно использовать двойное побитовое отрицание (~~) для округления числа в большую сторону, прибавляя к получившемуся числу единицу. Быстродействие побитовой операции с прибавлением единицы получилась даже на 10% выше, чем у floor(). Однако у неё есть проблемы с отрицательными и целыми числами — об этом дальше. Андрейка предложил использовать операцию минус-тильда (-~), чтобы добиться того же результата. Лично мне так тоже больше нравится.

Интересно, что оба варианта округления с бинарным отрицанием работают даже немного быстрей (разница около 5 %), чем самый быстрый Math.floor(), поэтому вариант без прибавления единицы можно попробоавть использовать в качестве немного более быстрой альтернативы округлению вниз.

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

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

Чтобы вызвать метод Number для числового литерала, его (в данном случае нуль) надо обрамить скобками. В противном случае (я лишь предполагаю!) интерпретатор Javascript пытается найти объект с именем «0», а сделать этого не может, т.к. идентификаторы не могут начинаться с цифры.

Целые числа
Совершенно очевидно, что округлённое целое число равно самому себе. Проверяем и обнаруживаем, что побитовые «тильда-тильда» и «тильда плюс 1» операции прибавляют ненужную единицу. Если избавится от этого ненужного эффекта, можно написать более быстрые функции округления вниз и вверх Math.floorFast() и Math.ceilFast() на основе побитовых операций. Они могут пригодиться в задачах, где производительность критична: например, в обработке графики.


Попытка написать быстрое округление
Казалось бы очевидное решение: обернуть нехитрую логику, обнаруженную выше, в отдельные функции и использовать их не сработало. Операция взятия остатка по-прежнему дорога́, то же самое относится и к немногочисленным, но присутствующим условиям. В итоге моё «быстрое» округление вниз работает почти в 2 раза дольше встроенного, а «быстрое» округление вверх — на 10 % быстрее встроенного. 

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

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

Неудачные проекты — копилка опыта
rawgift
Судя по всему, вся заметка будет изложением очевидных истин. Будучи прочувствованными на собственной шкуре, они представляются мне неписанными правилами. Впредь будет мне наука.

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


Отношения с клиентом

Самые просветляющие выводы тут.

Я оказался в плену собственного опыта, который подсказал мне: делаем сайт. Я долго работал над клёвым тянущимся шаблоном, полировал и проверял технологии (например, History API из HTML5, позволяющий переключать аяксом страницы и красиво менять URL в строке браузера, без хэшей), раскладывал независимые блоки по отдельным каталогам и рефакторил джаваскрипт. Это оказалось ошибкой, потому что нужен был не сайт, а интерактивная презентация. Логично было бы сделать её на флеше, но он не работает на айпадах и айфонах. Вывод: надо внимательно слушать клиента и переспрашивать его по 30 раз. В идеале стоит добиться сформулированной в 2—3 предложениях задачи с расставленными приоритетами.

Более того, мелочей в работе не существует. Изначально неправильно расставив приоритеты, я решил, что анимации тут вторичны и относятся скорее к мелочам. В итоге, за 8—10 часов до ожидаемого окончания проекта мы с клиентом неприятно расстались, т.к. наши взгляды на то, что важно, а что нет, разошлись. Я не получил оставшиеся деньги, а клиенты — ожидаемый результат.

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

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

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

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


Организационные моменты

Проектирование — всему голова. Самый банальный вывод, но невероятно важный. Я очень хорошо убедился в том, что неверные плохо продуманные решения тянут за собой на дно весь проект, усложняя работу с каждой дописанной строчкой кода. Две недели назад я решил, что сетка важней, а анимации можно будет докрутить потом с помощью jQuery.animate(), а сегодня не сдал проект.

Изучать, изучать и ещё раз изучать задачу! Я плохо изучил исходники, получил с задержкой видео анимаций — как результат, я фатально недооценил сложность. Такое у меня тоже впервые. Как минимум, стоимость проекта нужно было удвоить, если не утроить. Злую шутку сыграла опять же призма «опыта», через которую я увидел 3 странички и решил, что всё просто как три рубля. Даже скинул немного цену относительно первоначально названной. Этого делать нельзя. В начале проекта необходимо досконально разобраться в задаче, потратив на это пускай и много времени.

Торговаться нельзя, это портит карму и вредит как самооценке разработчика, так и результату проекта.

Мне есть чему учиться. Возможно, самый главный вывод лично для меня. Он вдохновляет и наполняет энтузиазмом, опуская вместе с тем на землю. И это очень хорошо — на земле всегда есть чем заняться.

Хватит работать за еду! Как-то так получается (боюсь, что тянется это откуда-то из детства и обусловленности прошлым), что даже зарабатывая вполне серьёзные деньги на некоторых проектах, я всегда получаю минимально достаточное количество денег. Особенно если посчитать стоимость часа (хоть это и бессмысленно, как я уже выяснил). Участие хорошего специалиста в проекте должно стоить дорого, а иначе и хорошим специалистом не стать. Причём не обязательно участие «на полную катушку» с 8-часовым работим днём. Даже небольшая консультация стоит денег, не говоря уж об умении довести начатое до конца. Оговорка: конечно же, речь идёт о настоящем профессионале.

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

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


Технология

Джаваскрипт — это сложно, как и программирование любой логики. Анимации — это сложно, как и любое другое программирование графики. Это необходимо учитывать как в сроках выполнения, так и в стоимости проекта. Сами по себе анимации — что джаваскриптовые, что CSS3 не так уж и сложны. Логика какой-нибудь галереи пишется за несколько часов, если изначально потратить 15 минут и всё продумать. Но вот в совокупности с нетривиальным поведением сетки и самого шаблона сложность возрастает на поядок.  Конечно, с ростом профессионализма такие вещи становится проще делать, но пока что я не знаю, как. У меня уходит очень много времени на отладку логики. А программировать графику без раскадровок и сценариев — это вообще сущий ад.




Через некоторое время напишу заметку с наблюдениями про использование технологии: организацию Javascript-кода и независимые блоки в одном проекте, CSS3-анимации и т.п.

Независимые блоки (БЭМ) и иже с ними
rawgift

Это был один из последних проектов, выполненных на фрилансе, и первый — на независимых блоках. Раньше я не понимал, что такое «БЭМ» и не хотел отказываться от привычных способов вёрстки, но сейчас дотумкал, что независимые блоки — штука классная. Ещё и проект попался такой, где меня попросили верстать с использованием БЭМ.

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


Сроки

Взявшись за работу, я пообещал уложиться в двухнедельный срок с запасом в 4—5 дней (почти дополнительная рабочая неделя). В итоге вышло, что на работу я потратил чуть меньше 70 часов, т.е. чуть меньше расчётного минимального срока, если работать по 40 часов в неделю. Я столько не работаю, поэтому задержался даже относительно «дедлайна» на несколько дней. Зато пару дополнительных страниц бесплатно сделал :)

В макетах была предусмотрена достаточно универсальная сетка, разработкой которой я занимался почти что 2 недели! Реальные 10 с лишним страниц я сделал за оставшиеся 5 дней. Если бы ковыряться с сеткой не так долго, то вышло бы совсем вовремя. Однако работа была кропотливая, плюс БЭМ, плюс новый для меня Sublime2.

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


Независимые блоки

Итак, независимые блоки. Идея уже несколько лет как не «новаторская», но для множества верстальщиков (для меня в том числе) — новая и немного диковатая. Например, писать селектор .b-link .b-link__underline для ссылки с вложенным спаном внутри кажется сущей глупостью.

Я специально говорю «независимые блоки», а не «БЭМ», т.к. не разобрался в бэме настлько, чтобы стать его безусловным апологетом. Мне нравится идея независимых блоков, как таковых. Мне интресны в первую очередь методологии, которые помогают работать эффективней и с меньшими нервами, и тут независимые блоки в любой реализации — это то, что нужно.

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

    «Таблица существующих элементов» как поддерживающая бумажная сущность не прижилась, не удобно. А вот «таблица страниц» — очень даже подходящая штука.

  2. «Инструменты БЭМ» и правда очень важны: поддерживать вручную правильную структуру каталогов и файлов неудобно и сложно. IE действительно не понимает больше 32 @import в одном CSS-файле.

  3. Мы использовали следующий шаблон именования:

    1. b-block__element, к которому дописываются модифкаторы вида m-block__element__modifier. Это неудобно.

    2. Лучше использовать яндексовский (или чей он там) опыт и отделять имя элемента от блока двумя подчёркиваниями, а модификатора от элемента — одним: block__element_modifier. Так визуально понятней.

    3. В названиях стоит использовать венгерскуюНотацию (это не венгерская нотация, а почти CamelCase, только первая буква маленькая), а не подчёркивания или дефисы.

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

  5. Размеры для всех картинок, вставленных элементом IMG, лучше указывать в HTML-коде. Иногда это бывает избыточно, например, для повторяющихся картинок одникового размера в каком-нибудь каталоге, но зато делает код более наглядным.

  6. Использовать множественные бэкграунды в CSS пока что рановато: слишком неудачные результаты получаются в IE. Да и дополнительная разметка даже для 4—5 дополнительных обёрток не настолько «дорога́» с использованием независимых блоков.

  7. БЭМ сам по себе достаточно избыточен: мы часто пишем одни и те же правила для разных элементов и руки чешатся эти правила «вынести за скобки», набивать HTML-код руками тоже излишне и долго. Короче говоря, работу надо автоматизировать по-максимуму — теперь это понятно.

    Надо попробовать использовать LESS или SASS с компиляцией на сервере. Высказывания в духе «БЭМ противоречит принципу Don't Repeat Yourself» — чушь, потому что отсутствие повторения появляется на более высоком уровне.

    Нужно также отказаться от написания HTML вручную и как-то автоматизировать процесс. Как — покажет время, предложения и предположения уже есть.

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

Бизнес-процессы и метрики

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

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

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


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


Хочу денег.
rawgift
Оригинал взят у cenzored в Хочу денег.
Originally posted by joselita at работает!!!!!!!!!!!!!!!!!!!!!!!!!!
Оригинал взят у enrolar в а фигня то работает!!!!!!!!!!!!!!!!!!!!!!!!!!
Оригинал взят у nojka_na_nojku в а фигня то работает!!!!!!!!!!!!!!!!!!!!!!!!!!
Помните эту лабуду???
РАБОТАЕТ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Совершенно неожиданно получила оттуда, отсюда деньги!!!! разрулила все свои вопросы , которые еще вчера может кахались неразрешимы!!!!
я никогда не верила во все это!! а тут думаю дай попробую))

а потом у друзей в ленте читаю типа у многих эта лабуда сработала. 
Тут же вспоминаю что и у меня неожиданно деньги появились :)

открываю свою запись старую и смотрю опана) реально практически 8 дней назад ( не считая выходных) разместила)))

http://p-i-f.livejournal.com/
Это - Богиня Денег Лакшми.
Скопируйте в дневник
и через 7-8 дней
Вы получите неожиданные деньги


?

Log in

No account? Create an account