Just-in-Time: Следующее поколение Tailwind CSS
Tailwind CSS на GitHubTailwind CSS в Telegram

Оптимизация для Продакшена

Удаление неиспользуемого CSS из Ваших производственных сборок для максимальной производительности.

Обзор

При использовании конфигурации по умолчанию разрабатываемая сборка Tailwind CSS 3645.2kB без сжатия, 294.2kB минимизирована и сжимается с помощью Gzip и 72.8kB при сжатии с помощью Brotli.

НесжатыйМинифицированныйGzipBrotli
3645.2kB2936.0kB294.2kB72.8kB

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

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

Думайте о попутном ветре как о гигантской коробке LEGO: вы вываливаете все это на пол и строите то, что хотите построить, а когда закончите, вы кладете все части, которые не использовали, обратно в коробку.

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

При сборке для производства вы всегда должны использовать опцию purge Tailwind, чтобы встряхнуть неиспользуемые стили и оптимизировать окончательный размер Вашей сборки. При удалении неиспользуемых стилей с помощью Tailwind очень сложно получить более 10 КБ сжатых файлов CSS.

Написание очищаемого HTML

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

PurgeCSS (библиотека, которую мы используем под капотом) намеренно очень наивен в том, как ищет классы в Вашем HTML. Он не пытается анализировать ваш HTML и искать атрибуты класса или динамически выполнять ваш JavaScript - он просто ищет любые строки во всем файле, которые соответствуют этому регулярному выражению:

/[^<>"'`\s]*[^<>"'`\s:]/g

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

Женщина платит за покупку
Маркетинг
Поиск клиентов для Вашего нового бизнеса

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

<div class="md:flex">
  <div class="md:flex-shrink-0">
    <img class="rounded-lg md:w-56" src="/img/shopping.jpg" alt="Женщина платит за покупку">
  </div>
  <div class="mt-4 md:mt-0 md:ml-6">
    <div class="uppercase tracking-wide text-sm text-indigo-600 font-bold">
      Маркетинг
    </div>
    <a href="/get-started" class="block mt-1 text-lg leading-tight font-semibold text-gray-900 hover:underline">
      Поиск клиентов для Вашего нового бизнеса
    </a>
    <p class="mt-2 text-gray-600">
      Начало нового бизнеса - это тяжелая работа.
      Вот пять идей, которые Вы можете использовать, чтобы найти своих первых клиентов.
    </p>
  </div>
</div>

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

Не используйте конкатенацию строк для создания имен классов

<div class="text-{{  error  ?  'red'  :  'green'  }}-600"></div>

Динамически выбирайте полное имя класса

<div class="{{  error  ?  'text-red-600'  :  'text-green-600'  }}"></div>

Пока имя класса отображается в Вашем шаблоне полностью, PurgeCSS не удалит его.

Удаление неиспользуемого CSS

Основное использование

Для начала предоставьте массив путей ко всем Вашим файлам шаблонов, используя опцию purge:

// tailwind.config.js
module.exports = {
  purge: [
    './src/**/*.html',
    './src/**/*.vue',
    './src/**/*.jsx',
  ],
  theme: {},
  variants: {},
  plugins: [],
}

Этот список должен включать любые файлы в Вашем проекте, которые ссылаются на любой из Ваших стилей по имени. Например, если у вас есть файл JS в Вашем проекте, который динамически переключает некоторые классы в Вашем HTML, вы должны убедиться, что включить этот файл в этот список.

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

Теперь всякий раз, когда вы компилируете свой CSS с параметром NODE_ENV, установленным в значение production, Tailwind автоматически удаляет неиспользуемые стили из вашего CSS.

Включение вручную

Если вы хотите вручную контролировать, следует ли удалять неиспользуемые стили (вместо неявной зависимости от переменной среды), вы можете использовать синтаксис объекта и предоставить опцию enabled, указав Ваши шаблоны с помощью опции content:

// tailwind.config.js
module.exports = {
  purge: {
    enabled: true,
    content: ['./src/**/*.html'],
  },
  // ...
}

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

Создание безопасных списков определенных классов

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

// tailwind.config.js
module.exports = {
  purge: {
    content: ['./src/**/*.html'],
    safelist: [
      'bg-blue-500',
      'text-center',
      'hover:opacity-100',
      // ...
      'lg:text-right',
    ]
  },
  // ...
}

Преобразование контента

Иногда вы создаете контент в формате, который компилируется в HTML, и было бы лучше скомпилировать этот контент в HTML перед поиском потенциальных классов. Отличный пример этого - работа с файлами разметки.

Вы можете использовать опцию transform, чтобы указать Tailwind преобразовать любой файл, соответствующий определенному расширению, прежде чем он будет искать классы, чтобы гарантировать наиболее точные результаты:

// tailwind.config.js
let remark = require('remark')

module.exports = {
  purge: {
    content: ['./src/**/*.{html,md}'],
    transform: {
      md: (content) => {
        return remark().process(content)
      }
    }
  },
  // ...
}

Настройка логики извлечения

Если вам нужно переопределить логику, которую Tailwind использует для обнаружения классов в содержимом определенного типа файла, вы можете использовать опцию extract, чтобы предоставить функцию, которая будет использоваться для обнаружения потенциальных классов в совпадающих файлах:

// tailwind.config.js
module.exports = {
  purge: {
    content: ['./src/**/*.{html,md}'],
    extract: {
      md: (content) => {
        return content.match(/[^<>"'`\s]*/)
      }
    }
  },
  // ...
}

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

Сохранение HTML-элементов

По умолчанию Tailwind сохраняет все основные стили HTML-элементов в Вашем CSS, например стили для тегов html, body, p, h1 и т.д. Это сделано для того, чтобы свести к минимуму случайную чрезмерную очистку в случаях, когда Вы, например, используете исходные файлы с уценкой (где нет фактического тега h1) или используете структуру, которая скрывает оболочку документа (содержащую теги html и body) где-нибудь в каталоге поставщика (например, Next.js).

Если вы хотите отключить это поведение, вы можете установить для preserveHtmlElements значение false:

// tailwind.config.js
module.exports = {
  purge: {
    preserveHtmlElements: false,
    content: ['./src/**/*.html'],
  },
  // ...
}

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

Очистка определенных слоев

По умолчанию Tailwind удалит все стили в base, components и utilities слои. Если вы хотите изменить это, используйте опцию layers, чтобы вручную указать слои, которые вы хотите очистить:

// tailwind.config.js
module.exports = {
  purge: {
    layers: ['components', 'utilities'],
    content: ['./src/**/*.html'],
  },
  // ...
}

Удаление всех неиспользуемых стилей

По умолчанию Tailwind удаляет только неиспользуемые классы, которые он генерирует сам или был явно заключен в директиву @layer. Он не удаляет неиспользуемые стили из стороннего CSS, который вы добавляете в свой проект, например, из библиотеки datepicker, которую вы загружаете.

/* Все эти стили будут удалены */
@tailwind base;
@tailwind components;
@tailwind utilities;

/* Эти стили будут удалены */
@layer components {
  .btn { /* ... */ }
}

/* Эти стили не будут удалены */
.flatpickr-innerContainer { /* ... */ }
.flatpickr-weekdayContainer { /* ... */ }
.flatpickr-weekday { /* ... */ }

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

Если вы действительно хотите удалить все неиспользуемые стили, установите mode: 'all' и preserveHtmlElements: false и будьте очень осторожны, чтобы указать пути к все файлам, которые могут ссылаться на любые классы или элементы HTML:

// tailwind.config.js
module.exports = {
  purge: {
    mode: 'all',
    preserveHtmlElements: false,
    content: [
      './src/**/*.js',
      './node_modules/flatpickr/**/*.js',
    ],
  },
  // ...
}

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

Удаление неиспользуемых ключевых кадров

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

// tailwind.config.js
module.exports = {
  purge: {
    content: ['./src/**/*.html'],
    options: {
      keyframes: true,
    },
  },
  // ...
}

Параметры PurgeCSS

Если вам нужно передать какие-либо другие параметры непосредственно в PurgeCSS, вы можете сделать это с помощью options:

// tailwind.config.js
module.exports = {
  purge: {
    content: ['./src/**/*.html'],

    // Эти параметры передаются напрямую в PurgeCSS
    options: {
      safelist: ['bg-red-500', 'px-4'],
      blocklist: [/^debug-/],
      keyframes: true,
      fontFace: true,
    },
  },
  // ...
}

Список доступных опций можно найти в документации PurgeCSS.


Альтернативные подходы

Если вы не можете использовать PurgeCSS по той или иной причине, вы также можете уменьшить площадь, занимаемую Tailwind, удалив неиспользуемые значения из Вашего файла конфигурации.

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

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

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

Вот несколько стратегий, которые вы можете использовать, чтобы ваш сгенерированный CSS был небольшим и производительным.

Ограничение цветовой палитры

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

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

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

Вот как использование меньшей цветовой палитры влияет на окончательный размер:

ЦветаОригинальныйМинифицированныйGzipBrotli
84 (по умолчанию)3645.2kB2936.0kB294.2kB72.8kB
502805.8kB2231.3kB238.7kB59.3kB
252177.6kB1702.8kB198.3kB50.6kB

Удаление неиспользуемых контрольных точек

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

Вот как определение меньшего количества экранов влияет на вывод:

Контрольные точкиОригинальныйМинифицированныйGzipBrotli
5 (по умолчанию)3645.2kB2936.0kB294.2kB72.8kB
32395.9kB1936.0kB196.2kB62.3kB
21781.4kB1446.0kB147.4kB57.3kB
11167.3kB956.3kB98.6kB52.5kB

Если вам нужно всего 3 размера экрана и 35 цветов, вы можете сжать 46.8kB без каких-либо изменений.

Отключение неиспользуемых основных плагинов и вариантов

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

// tailwind.config.js
module.exports = {
  // ...
  corePlugins: {
    float: false
  }
}

Если вам нужно только несколько утилит, вы можете передать массив в corePlugins с плагинами утилит, которые вы хотите сохранить.

// tailwind.config.js
module.exports = {
  // ...
  corePlugins: [
    'margin',
    'padding'
  ]
}

Вышеупомянутое отключило бы все утилиты, кроме полей и отступов.

Если вам нужна утилита, но не нужны адаптивные версии, установите для ее вариантов пустой массив, чтобы сгенерировать на 83% меньше классов:

module.exports = {
  // ...
  variants: {
    appearance: []
  }
}

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