Pull to refresh

Разработка CSS в GitHub

Reading time 7 min
Views 11K
От переводчика:
Статья написана от лица Mark Otto, одного из ведущих мейнтейнеров популярного front-end фреймворка Twitter Bootstrap, ныне разработчика CSS в GitHub
.

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

Краткая характеристика


Обзор текущего состояния CSS кода показывает:

  • Использование SCSS в качестве препроцессора;
  • У нас более 100 отдельных исходных таблиц стилей, которые мы компилируем перед выпуском в продакшен;
  • Скомпилированный CSS разделен на 2 файла, чтобы избежать лимита на количество селекторов в версиях IE<10;
  • Два этих файла имеют общий вес в 90KB;
  • Мы не придерживаемся какого-то определенного подхода в архитектуре CSS;
  • Мы используем пиксели в качестве единицы измерения, хотя иногда мы также пользуемся em;
  • Мы используем Normalize.css и смешение наших собственных сбрасывающих стилей.


Препроцессор


Как сказано выше, мы используем SCSS. Этот выбор сделан задолго до моего прихода и я не имею ничего против (несмотря на то, что Bootstrap сейчас разрабатывается на LESS). Наши SCSS файлы компилируются Ruby on Rails с некоторой помощью Sprockets для включения файлов. Подробнее об этом чуть позже.

Что насчёт LESS, Stylus, или …? Я не думаю, что GitHub когда-то планировал переключиться на LESS, но не могу утверждать это. Сейчас мы также, скорее всего, не будем переключаться на разработку, используя LESS, т.к. не видим явных преимуществ.

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

На данный момент мы не используем Autoprefixer, но, на самом деле, нам следовало бы, т.к. в этом случае почти все наши миксины будут не нужны. Надеюсь, что скоро мы это реализуем.

Также на данный момент мы не используем source maps, но это скоро поменяется. (Если вы не знали, source maps позволяют вам видеть в Inspector’e браузера, из какого исходного SCSS файла был скомпилирован данный набор стилей, вместо скомпилированного и сжатого CSS. Они крутые.)

В добавок к этому, мы используем очень мало возможностей SCSS. В нашем случае функционал SCSS сводится к использованию переменных, миксинов, функций цвета (darken, lighten, etc), математических функций и наследования.

Архитектура


На данный момент два популярных подхода к CSS архитектуре – это BEM и OOCSS. Мы склоняемся в сторону OOCSS, но у нас нет целостного и глобального подхода. Мы стараемся разрабатывать новые элементы с расплывчатым подходом, комбинирующим свойства этих двух подходов, но который имеет следующие базовые черты:

  • Предпочтение класам, нежели чему-либо еще (ID, тэги), в селекторах;
  • Уклонение от лишнего наследования;
  • Использование (единичных) дефисов в названиях классов;
  • Стараемся давать как можно более короткие имена классам, но без создания путаницы и неразберихи.


Я напишу больше о моей предпочтительной CSS архитектуре в другом посте. Сейчас же текст выше подытоживает подход GitHub, который, конечно же, не идеален, но хорошо справляется с тем, что от него требуется.

Проверка синтаксиса (linting)


Мы начали пользоваться проверкой синтаксиса нашего SCSS несколько недель назад. У нас были свои условные соглашения касательно код-стайла, но стиль и форматирование каждого разработчика были в какой-то степени уникальны. Сейчас же каждый CI билд включает в себя базовый SCSS linting и файл не выпускался в билд, если:

  • Ваш класс есть в CSS, но его нет нигде в папке шаблонов app/views;
  • Вы используете один и тот же селектор несколько раз (т.к. они почти всегда должны быть совмещены);
  • Общие правила форматирования (лимиты наследования, отступы между правилами, отсутствие пробелов после : и т.д.) нарушены.


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

Два CSS файла


GitHub имеет набор из двух CSS файлов, github и github2. Файл был разделен несколько лет назад, чтобы разрешить проблему лимита в 4095 селекторов на один файл. Этот лимит распространяется на версии IE 9 и младше, т.к. GitHub требует поддержки IE9, наш подход к разделению CSS останется в силе еще долго. Потому что на сегодняшний день GitHub имеет около 7000 селекторов в этих двух файлах. Сравним эти цифры с данными с других сайтов:

  • Bootstrap v3.2.0 имеет чуть менее 1900 селекторов;
  • Twitter имеет чуть менее 8900 селекторов;
  • NY Times – около 2100 селекторов;
  • SoundCloud (новая версия) – около 1100.


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

Включения через Sprockets


CSS и JavaScript GitHub’a включаются через Sprockets и require. Мы разрабатываем наш CSS код с помощью разделенных подкаталогов внутри папки app/assets/shylesheets. Вот как это выглядит:

/*
 = require primer/basecoat/normalize
 = require primer/basecoat/base
 = require primer/basecoat/forms
 = require primer/basecoat/type
 = require primer/basecoat/utility
 = require_directory ./shared
 = require_directory ./_plugins
 = require_directory ./graphs
 = require primer-user-content/components/markdown
 = require primer-user-content/components/syntax-pygments
 = require primer/components/buttons
 = require primer/components/navigation
 = require primer/components/behavior
 = require primer/components/alerts
 = require primer/components/tooltips
 = require primer/components/counter
 = require primer-select-menu
 = require octicons

 = require_directory .
*/


Мы включаем наши зависимости (Primer это наш внутренний фреймворк) и после этого включаем все SCSS файлы папки в том порядке, в котором Sprockets решает включить их (мне кажется, по алфавиту). Легкость, с которой мы можем связывать наши стили (просто с помощью команды require_directory .) поражает, но в этом также есть недостатки.

Порядок, в котором применяются стили (а, соответственно, и порядок включения файлов) важен. На самом деле, это не должно быть так, но в каждой системе дизайна есть правила и базовая иерархия стилей. С подходом Sprockets мы иногда сталкиваемся с проблемами специфики. Это случается потому, что новые файлы могут быть добавлены в любой из двух CSS файлов в любое время. В зависимости от названия файлов они появляются в разных местах в скомпилированном CSS.

К тому же, использования Sprockets подразумевает, что ваши SCSS файлы не имеют непосредственного и автоматического доступа к вашим глобальным переменным и миксинам. Это ведет к тому, что вы должны включать их (через @ import) каждый раз вверху каждого SCSS файла, который обращается к переменной или миксину.

Производительность


Внутри GitHub мы используем много графиков для отслеживания того, как сайт и API поживают. Мы также отслеживаем несколько интересных фронт-енд характеристик. Например, вот график, иллюстрирующий размер двух наших CSS файлов за последние 3 месяца:



Также, вот график количества селекторов в CSS файлах за последние 3 месяца на наших blob страницах. Очевидно, что у нас еще осталось много работы по уменьшению количества tag-селекторов.



Из-за того, что мы постоянно добавляем обновленные CSS файлы и добавляем их десятки каждый день, мы постоянно сбиваем кэши наших довольно-таки больших CSS файлов. Мы мало сделали для того, чтобы оптимизировать размеры файлов или уменьшить сбой кэшей, но мы начинаем присматриваться в эту сторону более активно. Было бы очень круто иметь core-файл, который, надо надеяться, будет меняться очень редко и вторичный файл, который мы бы меняли более часто.

Раскрывая эту тему в Twitter, у нас было (не уверен, есть ли у них это сейчас) 2 файла, core и more. Core-файл содержал в себе стили, необходимые для того, чтобы время, прошедшее до первого твита, было как можно более маленьким. Всё остальное было в файле more. Зная о любви GitHub к быстрым переменам (здесь ничего не портируется, если это не было портировано быстро), мы обратим свое внимание на такой подход. Сейчас же наши два файла разделены произвольно.

В общем, оптимизация производительности селекторов не особо нас беспокоит. Мы в курсе плохих подходов: избыточные вложения, ID, элементы и т.д., но мы не стараемся переоптимизировать. Единственным исключением были diff страницы. Из-за слишком большого количества разметки, которое было нужно для рендеринга diff страницы, мы избегали аттрибутивных селекторов, как [class^=”octicon”]. При слишком частом использовании, эти аттрибутивные селекторы могут крашить (и крашили) браузеры.

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




Говоря о ней, мы делаем вполне себе хорошую работу, но и над улучшениями тоже работаем. У нас есть публично доступный CSS стайлгайд и все наши общие правила по написанию CSS живут там, также как и примеры большинства компонентов. Он построен на KSS, генераторе стайлгайдов.

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

Primer




Я намекал на это раньше, но для тех, кто не в курсе, Primer p это наш внутренний фреймворк для обших стилей и компонентов внутри наших публичных и внутренних приложений. Он включает:

  • Normalize;
  • Глобальные стили для box-sizing, типографию, ссылки и т.д.;
  • Навигацию;
  • Формы;
  • Сетку;
  • Стили разметки;
  • Специальное select меню.


Мы используем его на GitHub.com, Gist и нескольких внутренних приложениях.

Большинство компонентов Primer’a документированы в нашем стайлгайде (навигация, tooltips, и т.д.) Несмотря на это, мы недавно взялись за обновление и улучшение Primer’a, поэтому много компонентов сейчас меняется.

Для тех, кто хотел спросить, я бы очень хотел выложить в открытый доступ части Primer’a, но в этом направлении мало что поменяется в ближайшее время. Всё-таки, надежда у меня есть.

Рефактор кода


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

  • Ручной поиск вещей, которые выглядят похоже, но на самом деле имеют разный HTML и CSS код, и последующее комбинирование;
  • Запуск скрипта, который ищет класс в нашем CSS и проверяет, есть ли он в наших файлах вида.


Общий процесс рефакторинга, вероятно, не уникален для GitHub'a. Мы находим вещи, которые стоило бы удалить, удаляем их, публично обсуждаем, сообщаем об этом команде по разработке CSS и портируем их так быстро, насколько это возможно. Любой член команды может удалять код. У нас есть много разработчиков, которые непосредственно добавляют что-то новое в GitHub, но у нас также есть немало нердов, анализирующих то, что мы можем удалить.
Tags:
Hubs:
+4
Comments 1
Comments Comments 1

Articles