Повышение производительности приложений с помощью HTTP-заголовков кеширования


Оглавление (нажмите, чтобы открыть):

Как оптимизировать WordPress для повышения производительности

В данном руководстве рассматриваются следующие темы:

Включить динамическое кэширование

Добавление правильно настроенного динамического кэширования на ваш сайт WordPress будет иметь большое влияние на его скорость. Есть много услуг, таких как Varnish и APC , которые могут быть использованы, но все они требуют много конфигурации сервера и тонкой настройки вашего приложения, чтобы работать правильно. Есть плагины кэширования для сайтов на WordPress, такие как WP Super Cache. С его помощью, все, что вам нужно сделать, это установить плагин в WordPress и включить динамическое кэширование одним нажатием кнопки.

Включить сжатие GZIP

Для уменьшения размера данных, который передаются между вашим сервером и вашими посетителями, вы можете включить сжатие GZIP для ваших изображений, CSS и JavaScript файлов. Делая это, веб-сервер будет сжимать (как создается ZIP-файл, например) содержание, прежде чем он передается через Интернет в вашем браузере. С другой стороны, ваш браузер распаковывает содержимое перед выводом его. Это существенно снижает объем данных, которые передаваясь снижают время загрузки ваших страниц.

Самый простой способ включить сжатие GZIP для ваших изображений, CSS и JS файлы, это добавить эти строки в ваш файл .htaccess на сайте WordPress:

Использование CDN

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

Оптимизация изображений

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

  • Использование изображений нужного размера. Не нужно загружать большие изображения, а затем масштабировать их с HTML. Убедитесь, что ваши фотографии и другие изображения не больше, чем размер который на самом деле отображаются на сайте.
  • Smush изображения. В данных изображениях будут удалены все дополнительные данные из ваших фотографий – дата создания, камера используется для фото, GPS координаты и т.д. Существует хороший маленький плагин, который делает это для вас называется WP Smush.it.
  • Если возможно, используйте спрайты для ваших тем. Использование спрайтов является метод CSS, который использует одно изображение, чтобы показать несколько элементов дизайна на ваших страницах. Таким образом, вместо загрузки десятки маленьких изображений (создание запросов HTTP каждый раз), ваш сайт будет открывать только одно. Однако, необходимо учитывать, как тема разработана. Так всегда обращайте внимание на темы, которые используют спрайты.

Минимизировать ваши JavaScript и CSS файлы

Минимизация ваших CSS и файлов JavaScript означает, что все ненужные данные из них, как двойные пробелы, пустые новые строки, комментарии и т.д. , будут удалены из файлов, снижая их размер. Есть много онлайн – инструментов, которые можно использовать бесплатно для минимизации файлов. Кроме того, если вы используете плагин W3 Total Cache, он имеет возможность автоматически минимизировать CSS и JS файлы вашей темы.

Использование кэша браузера

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

Оптимизация БД WordPress

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

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Оптимизация производительности JavaScript и Ajax

Измерение производительности с помощью инструментов Firebug, Safari Web Inspector, YUI Profiler и YSlow

Серия контента:

Этот контент является частью # из серии # статей:

Этот контент является частью серии:

Следите за выходом новых статей этой серии.

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

В результате достижений в различных областях Web-технологии мы столкнулись с абсолютно новым классом проблем производительности. DSL и широкополосные сети сделали высокоскоростной доступ в Интернет доступным для многих, но и ожидания в отношении времени загрузки и отзывчивости дошли до того, что выполняя какие-либо действия на странице, мы рассчитываем на мгновенный результат. Появление Asynchronous JavaScript and XML (Ajax) позволило разработчикам создавать квазинастольные Web-приложения, которые, чтобы отреагировать на событие, больше не требуют загрузки целой страницы. Преимущества этого очевидны, но теперь рядовой пользователь ожидает столь же оперативного реагирования от любых Web-приложений. В последнее время развитие мобильных Web-технологий бросило новый вызов разработчикам, старающимся удовлетворить ожидания современных пользователей ― на целевом устройстве с меньшим экраном, меньшим источником энергии и более медленным соединением.

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

Советы и рекомендации по JavaScript- и Ajax-разработке

Одна из проблем JavaScript-разработки заключается в том, что большой процент разработчиков и Web-дизайнеров, пишущих на JavaScript, в действительности никогда не изучали собственно JavaScript с азов. Их знание языка, как правило, накоплено за годы добавления фрагментов, найденных в Интернете и выполняющих ту или иную функцию. Они знают, как декларировать переменные, писать условные операторы и выполнять расчеты, но никогда не сидели с полным руководством по языку JavaScript и не изучали его с нуля. Чтобы облегчить себе жизнь, программисты обращаются к разнообразным библиотекам и интегрированным средам разработки (ИСР), таким как JQuery и YUI.

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

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

Использование внешних файлов JavaScript

Золотое правило для достижения максимальной производительности JavaScript-приложений: везде, где это возможно, использовать внешние файлы JavaScript, вместо включения кода JavaScript непосредственно в файлы HTML. Иначе, мало того, что этот код JavaScript придется дублировать на множестве страниц, он не будет кэшироваться Web-браузером, и с каждой последующей загрузкой страницы будет загружаться заново. Первая загрузка страницы будет выполняться значительно медленнее, так как внешний файл требует передачи на сервер дополнительного HTTP-запроса. Однако в большинстве приложений связанный с этим удар по производительности более чем компенсируется экономией времени при последующих загрузках страницы.

Исключением из этого правила является случай, когда большинство посетителей просматривает только одну страницу. Или когда нужно, чтобы первая страница загружалась так же быстро или быстрее, чем последующие – в этих случаях предпочтителен встроенный JavaScript. В своей книге «Быстродействующие Web-сайты» (см. ссылку в разделе Ресурсы) Стив Саундерс выдвигает идею «Загрузки после загрузки» (Post-Onload Download), когда код JavaScript первой страницы встроен собственно в HTML-файл, а внешние файлы JavaScript, необходимые для последующих страниц, загружаются динамически, когда страница полностью загружена. Однако в большинстве случаев достаточно использовать только внешние файлы JavaScript.

Когда нужны ИСР и библиотеки JavaScript

Я обеими руками за использование ИСР и библиотек JavaScript. Они не только помогают решить многие проблемы кросс-браузерной совместимости, но при правильном использовании могут значительно ускорить разработку Web-приложений. Однако с учетом вышесказанного нужно очень внимательно относиться к использованию этих инструментов, так как большинство из них довольно велики и могут ухудшить производительность приложения.

Прежде всего, нужно спросить себя: действительно ли мне нужна ИСР? Мое знакомство с ИСР JavaScript состоялось несколько лет назад, когда в разрабатываемом Web-приложении нужно было использовать Ajax. Вместо того чтобы написать собственную функцию XMLHttpRequest , я решил облегчить себе жизнь и воспользовался ИСР Prototype. В приложении не использовались никакие другие возможности среды, кроме выполнения запросов Ajax и обработки ответов от сервера. К счастью, приложение было относительно невелико и предназначалось для внутреннего пользования, так что вопрос производительности не был критическим, но теперь мне ясно, что более легкое решениее, реализующее только функциональность Ajax, было бы лучше.

Последняя версия среды Prototype без минимизации и архивирования занимает 141 KB. Часть кода, относящаяся к моей задаче, составляла, вероятно, менее 2 КБ, так что около 139 KБ кода JavaScript в моем приложении абсолютно не использовались. Это увеличило не только время загрузки приложения из-за размера файла, но и время его выполнения, так как код JavaScript выполнялся в браузере.

Короче, современные ИСР и библиотеки JavaScript, такие как Prototype, JQuery, Dojo, MooTools, YUI, ExtJS, и т.п., обеспечивают множество возможностей, которые можно использовать или не использовать. Если используется только минимальный набор функций, возможно, стоит рассмотреть более легкое решение. Например, библиотека YUI позволяет по умолчанию загрузить самую минимальную ИСР, а затем выбирать, какие библиотеки в нее добавлять.

Полезные утилиты для управления кэшированием файлов

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

Кэширование в операционной системе Windows используется и при выполнении операций чтения и записи файлов. Кэширование файлов при чтении обеспечивает более быстрый доступ к ним в случае повторного обращения. При первоначальном обращении к файлу система считывает его с диска в оперативную память, а благодаря кэшированию при повторном чтении файла система мгновенно извлекает файл из оперативной памяти, вместо того чтобы считывать его с более медленного жесткого диска. Кэширование файлов при записи позволяет приложениям не тратить времени на ожидание завершения операции сохранения данных и практически мгновенно приступать к выполнению следующих операций. В результате возрастает скорость выполнения файловых операций: запуск программ, копирование файлов, открытие файлов, и т.д., но все это может иметь место только в случае оптимального управления дисковым кэшем. Дисковым кэшем (Disk Cache) называют часть установленной в компьютере оперативной памяти, используемой как промежуточный буфер при чтении данных и записи их на внешние устройства хранения (жесткий диск, дискеты, CD-ROM и пр.). Оптимальные размеры кэша диска зависят от аппаратной конфигурации, версии системы, используемых приложений, и в итоге они для каждого компьютера индивидуальны. Чем больше дисковый кэш, тем быстрее считываются файлы с жесткого диска и тем меньше остается свободной оперативной памяти для работы приложений — задача в том, чтобы найти удачный компромисс и определить такой размер кэша, чтобы файловые операции выполнялись быстро и оперативной памяти хватало для работы приложений.

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

Особенности кэширования в Windows

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

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

К сожалению, непосредственно в Windows отсутствуют удобные встроенные механизмы для эффективного управления кэшированием. Стандартные средства настройки, предусмотренные для этой цели разработчиками, позволяют лишь включать/отключать дисковое кэширование записи. Для этого следует выбрать из контекстного меню папки Мой компьютер команду Свойства, перейти на вкладку Оборудование, щелкнуть на кнопке Диспетчер устройств и открыть раздел Дисковые устройства. Затем нужно вызвать контекстное меню нужного устройства, для которого следует изменить настройки дискового кэширования, выбрать команду Свойства и включить или выключить флажок Разрешить кэширование записи на диск (рис. 1).

Рис. 1. Включение режима кэширования записи

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

Утилиты для управления кэшированием

Чтобы более эффективно организовать управление кэшированием, лучше воспользоваться специализированной утилитой от сторонних производителей — это будет намного удобнее, быстрее, надежнее и может помочь оптимально настроить параметры кэширования и добиться более высокой производительности и стабильности работы системы. Правда, выбор ПО для управления кэшированием в Windows весьма ограничен. Те или иные возможности организации кэширования имеются в некоторых приложениях, отвечающих за настройку и оптимизацию операционной системы: Windows Accelerator, Reg Organizer, RAM Saver Pro и др. Однако существует и ряд специализированных утилит с более широкими возможностями в плане управления кэшированием — наиболее удачные из них мы и рассмотрим.

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

O&O CleverCache 6.0 Professional

Разработчик: O&O Software GmbH

Размер дистрибутива: 6,79 Мбайт

Способ распространения: shareware

Работа под управлением: Windows NT 4.0/2000/XP/2003

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

Рис. 2. Настройка параметров функции Mem-O-Free, отвечающей за контроль свободной оперативной памяти

При каждой загрузке операционной системы CleverCache загружается в системный трей, выполняет проверку аппаратной конфигурации компьютера и автоматически подбирает лучшие параметры настройки для оптимального использования ресурсов оперативной памяти. Результаты настройки отображаются в окне встроенного модуля Cache Monitor (рис. 3). Программа постоянно контролирует объем свободной оперативной памяти, и если он оказывается меньше некоторой величины, то неиспользуемые участки памяти сбрасываются в файл подкачки и освобождается недостающий объем оперативной памяти. В итоге в системе в любой момент времени оказывается доступным некоторый фиксированный объем свободной оперативной памяти, необходимой приложениям. Это приводит к уменьшению времени отклика и наиболее заметно при одновременном запуске нескольких приложений и частых переключениях между ними.

Рис. 3. Статистика CleverCache в окне Cache Monitor

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

CacheBoost Professional Edition 4

Размер дистрибутива: 898 Кбайт

Способ распространения: shareware


Работа под управлением: Windows NT/2000/XP

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

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

Рис 4. Вариант настройки параметров кэширования вручную

CacheBoost контролирует наличие свободной оперативной памяти, распределение ее между приложениями и активность использования дискового кэша, наглядно отображая статистику на графике (рис. 5). Программа дефрагментирует системную память для быстрого доступа к ней (рис. 6), восстанавливает утечку памяти в плохо оптимизированных приложениях и периодически освобождает часть оперативной памяти, помещая неиспользуемые данные в swap-файл. Это освобождает свободную оперативную память, необходимую для приложений, и тем самым повышает устойчивость работы системы, позволяет активным приложениям быстрее реагировать на действия пользователя. По желанию пользователя возможно принудительное очищение памяти, занятой дисковым кэшем. Реализованная в программе технология Data Safe обеспечивает полную безопасность кэшируемых данных.

Рис 5. График использования оперативной памяти и дискового кэша

Рис 6. Автоматическая оптимизация оперативной памяти

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

CachemanXP 1.12

Разработчик: Outer Technologies

Размер дистрибутива: 1,25 Мбайт

Способ распространения: shareware

Работа под управлением: Windows NT/2000/XP

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

Утилита работает в фоновом режиме, а иконка программы отображается в системном трее. Программа непрерывно контролирует загрузку процессора, объем свободной оперативной памяти и то, как ее расходуют различные запущенные процессы. Процессы, потребляющие свыше 10% загрузки центрального процессора, отображаются в информационном окне синим цветом, а процессы, которые потребляют свыше 80% загрузки процессора, показаны красным. При необходимости приоритет выполнения любого из соответствующих процессов можно изменить (рис. 7). CachemanXP позволяет вручную настраивать параметры дискового кэша (рис. 8), а также задавать размеры кэша DNS, кэша иконок и кэша Internet Explorer, хотя может сделать это и автоматически — в режиме автооптимизации. Кроме того, программа может периодически или по команде пользователя освобождать часть оперативной памяти, перемещая из нее часть не используемых в данный момент приложений из оперативной памяти на жесткий диск в файл подкачки. Дополнительно программа позволяет проводить тонкую настройку некоторых системных параметров.

Рис. 7. Изменение приоритета одного из запущенных процессов

Рис. 8. Настройка параметров дискового кэша

Имеется более дешевая упрощенная версия программы CachemanXP — Cacheman (https://www.outertech.com/index.php?_charisma_page=product& >

Рис. 9. Настройка параметров освобождения оперативной памяти

HTTP-кеширование

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

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

Когда сервер возвращает запрос, он также отправляет набор HTTP-заголовков, описывающих тип контента, длину, команды для работы с кешем, маркер подтверждения и т. д. Например, в примере выше сервер возвращает запрос размером 1024 Б, отдает команду клиенту кешировать его на 120 секунд и отправляет маркер подтверждения (x234dff). Он используется, чтобы проверить, не изменился ли ресурс, после того как срок действия ответа истек.

Подтверждение кешированных ответов с помощью ETags

  • Сервер отправляет маркер подтверждения в HTTP-заголовке ETag.
  • С помощью маркера подтверждения можно проверить, изменился ли ресурс.

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

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

В примере выше клиент автоматически отправляет маркер ETag в HTTP-заголовке If-None-Match. Сервер проверяет совпадение маркера с нужным ресурсом, и если тот не изменился, отправляет ответ 304 Not Modified. Это значит, что кешированный ответ остался прежним, и его можно снова использовать в течение следующих 120 секунд. Обратите внимание, что скачивать ресурс ещё раз не нужно. Это уменьшает время загрузки страницы и экономит пропускную способность канала.

Чем полезна проверка актуальности для разработчика? Браузер сделает все автоматически: проверит, был ли указан маркер подтверждения ранее, добавит его в исходящий запрос и обновит временные отметки на основе ответа от сервера. Все, что нам нужно сделать, — проверить, действительно ли сервер отправляет нужные маркеры ETag. Чтобы узнать, какие параметры следует установить, ознакомьтесь с документацией к серверу.

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

Cache-Control

  • Правила кеширования ресурса можно указать с помощью HTTP-заголовка Cache-Control.
  • Директивы Cache-Control определяют, где, как и на какое время может быть кеширован ресурс.

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

no-cache и no-store

Директива no-cache означает, что при повторном запросе к тому же URL ответ можно использовать только после проверки изменений. Таким образом, если указан соответствующий маркер подтверждения (ETag), будет выполнена повторная проверка. Однако при отсутствии изменений данные не будут скачиваться ещё раз.

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

public и private

Если в ответе содержится директива public, его можно кешировать, даже если с ним связана HTTP-аутентификация и код статуса ответа обычно нельзя сохранять. Эта директива требуется редко, потому что другая информация, заданная для кеширования, (например, max-age) показывает, что ответ можно сохранить.

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

max-age

Эта директива указывает период времени в секундах, в течение которого скачанный ответ может быть повторно использован. Отсчет начинается с момента запроса. Например, max-age=60 означает, что ответ может быть кеширован и использован в течение 60 секунд.

Выбор правил Cache-Control

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

Мастер Йода рекомендует:  Нюансы защиты персональных данных в облаке
Директивы Cache-Control Значение
max-age=86400 Ответ можно сохранить в браузере и промежуточных кешах (для него указана директива»public») на 1 день (60 секунд x 60 минут x 24 часа)
private, max-age=600 Браузер может кешировать ответ на 10 минут (60 секунд x 10 минут)
no-store Ответ нельзя кешировать. При повторном запросе нужно скачать его заново.

По данным HTTP Archive, на 300 000 самых популярных сайтов по рейтингу Alexa около половины скачанных запросов можно сохранить в кеше браузера. Это помогло бы сэкономить огромные объемы данных при повторном посещении страниц. Однако это не означает, что в вашем приложении обязательно есть 50% ресурсов, которые можно сжать. Некоторые сайты сохраняются в кеше более чем на 90%, а на других размещено много личной или меняющейся со временем информации, которую кешировать невозможно.

Проверьте ваши страницы, определите, какие ресурсы можно кешировать, и убедитесь, что они возвращают правильные заголовки Cache-Control и ETag.

Аннулирование и обновление кешированных ответов

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

Все HTTP-запросы сначала направляются браузером в его кеш, чтобы проверить наличие действительного сохраненного ответа. Если совпадение найдено, ответ считывается из кеша, уменьшая время загрузки сайта и объем скачиваемых данных. Однако нам может потребоваться обновить кешированный ответ или сделать его недействительным. Что нам предпринять в этом случае?

Предположим, мы задали команду кешировать таблицу стилей CSS в течение 24 часов (max-age=86400), но чуть позже обновили дизайн сайта и хотим, чтобы это увидели все пользователи. Как сообщить им, что нужно обновить устаревшую копию CSS в кеше? Это непросто, потому что нам потребуется изменить URL ресурса.

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

Как совместить кеширование ресурсов и обновления сайта? Можно просто отредактировать URL файла, чтобы пользователь скачивал новый ответ каждый раз, когда его контент меняется. Для этого добавьте в имя файла идентификационную метку или номер версии, например style.x234dff.css.

Установка правил кеширования для каждого ресурса позволяет нам определять иерархии кешей . Благодаря этому мы можем указывать, на какой период сохранен ресурс и когда пользователь увидит его новую версию. Рассмотрим пример выше.

  • Для HTML указана директива no-cache, поэтому браузер будет проверять актуальность документа при каждом запросе и при изменениях скачивать последнюю версию ресурса. Кроме того, мы изменили HTML-разметку, добавив идентификационные метки в URL CSS- и JavaScript-ресурсов. Если эти файлы изменятся, HTML тоже обновится, и браузер скачает новую копию HTML-ответа.
  • Браузерам и промежуточным кешам (например, сетям доставки контента) разрешено сохранять CSS. Срок его действия заканчивается через 1 год. Обратите внимание, что мы можем установить такой длинный период, потому что мы добавили идентификационную метку в название файла. Поэтому если CSS обновится, то URL тоже изменится.
  • Срок действия для JavaScript тоже истекает через 1 год. Однако ресурс отмечен директивой private, потому что в нем содержатся личные данные пользователи, которые нельзя сохранять в кеше сетей доставки контента.
  • У кешированного изображения нет версии или уникальной идентификационной метки, и срок его действия заканчивается через 1 день.

Таким образом, с помощью ETag, Cache-Control и уникальных URL мы можем достичь нужных нам результатов: долгих сроков действия, контроля над кешированием ресурса и обновлений в любой момент.

Список методов оптимизации


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

Помните о некоторых советах и техниках, которые помогут вам выбрать стратегию кеширования:

  1. Используйте одинаковые URL для одного ресурса. В противном случае контент каждый раз будет скачиваться заново. Помните, что в URL регистр букв имеет значение!
  2. Убедитесь, что сервер отправляет маркер подтверждения (ETag). Если ресурс на сервере не изменился, то благодаря этому маркеру те же байты не будут передаваться повторно.
  3. Определите, какие ресурсы можно сохранить в промежуточных кешах. Чаще всего это ответы, которые одинаковы для всех пользователей.
  4. Определите подходящий срок действия для каждого ресурса. У данных могут быть разные требования к частоте обновления информации. Учитывая это, выберите подходящее значение max-age для каждого ресурса.
  5. Установите подходящую иерархию кешей для вашего сайта. Используйте URL ресурсов с идентификационными отметками контента и короткие сроки действия (или директиву no-cache) для HTML-документов. С их помощью вы можете указать, когда кешированные версии данных будут обновлены.
  6. Уменьшите пересылку данных. Если часть ресурса, например функции JavaScript или наборы CSS-стилей, обновляется часто, отправляйте ее код в отдельном файле. Тогда та часть контента, которая меняется редко, например коды библиотек, может быть загружена из кеша. Это уменьшит количество скачиваемых данных при обновлении ресурса.

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Основы клиентского кэширования понятными словами и на примерах. Last-modified, Etag, Expires, Cache-control: max-age и другие заголовки

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

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

Но для начала давайте выясним, зачем вообще нужно кэширование на стороне клиента?.

Веб-страницы состоят из множества различных элементов: картинок, css и js файлов и т.п. Часть этих элементов используются на нескольких (многих) страницах сайта. Под клиентским кэшированием понимают способность браузеров сохранять копии файлов (ответов сервера), чтобы не загружать их повторно. Это позволяет значительно ускорить повторную загрузку страниц, сэкономить на трафике, а также снизить нагрузку на сервер.

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

Http заголовки для управления клиентским кэшированием

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

Без кэша (при отсутствии кэширующих http-заголовков)

Как мы видим, каждый раз при отображении картинки cat.png браузер будет снова загружать ее с сервера. Думаю, не нужно объяснять, что это медленно и неэффективно.

Заголовок ответа Last-modified и заголовок запроса if-Modified-Since .

Идея заключается в том, что сервер добавляет заголовок Last-modified к файлу (ответу), который он отдает браузеру.

Теперь браузер знает, что файл был создан (или изменен) 1 декабря 2014. В следующий раз, когда браузеру понадобится тот же файл, он отправит запрос с заголовком if-Modified-Since .

Если файл не изменялся, сервер отправляет браузеру пустой ответ со статусом 304 (Not Modified) . В этом случае, браузер знает, что файл не обновлялся и может отобразить копию, которую он сохранил в прошлый раз.

Таким образом, используя Last-modified мы экономим на загрузке большого файла, отделываясь пустым быстрым ответом от сервера.

Заголовок ответа Etag и заголовок запроса If-None-Match .

Принцип работы Etag очень схож с Last-modified , но, в отличии от него, не привязан ко времени. Время – вещь относительная.

Идея заключается в том, что при создании и каждом изменении сервер помечает файл особой меткой, называемой ETag , а также добавляет заголовок к файлу (ответу), который он отдает браузеру:

Теперь браузер знает, что файл актуальной версии имеет ETag равный “686897696a7c876b7e”. В следующий раз, когда брузеру понадобится тот же файл, он отправит запрос с заголовком If-None-Match: «686897696a7c876b7e» .

Сервер может сравнить метки и, в случае, если файл не изменялся, отправить браузеру пустой ответ со статусом 304 (Not Modified) . Как и в случае с Last-modified браузер выяснит, что файл не обновлялся и сможет отобразить копию из кэша.

Подробнее о ETag можно почитать здесь.

Заголовок Expired

Принцип работы этого заголовка отличается от вышеописанных Etag и Last-modified . При помощи Expired определяется “срок годности” (“срок акуальности”) файла. Т.е. при первой загрузке сервер дает браузеру знать, что он не планирует изменять файл до наступления даты, указанной в Expired :

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

Такой вид кэша особенно актуален для иллюстраций к статьям, иконкам, фавиконкам, некоторых css и js файлов и тп.

Заголовок Cache-control с директивой max-age .

Принцип работы Cache-control: max-age очень схож с Expired . Здесь тоже определяется “срок годности” файла, но он задается в секундах и не привязан к конкретному времени, что намного удобнее в большинстве случаев.

  • 1 день = 86400 секунд
  • 1 неделя = 604800 секунд
  • 1 месяц = 2629000 секунд
  • 1 год = 31536000 секунд

У заголовка Cache-control , кроме max-age , есть и другие директивы. Давайте коротко рассмотрим наиболее популярные:

public
Дело в том, что кэшировать запросы может не только конечный клиент пользователя (браузер), но и различные промежуточные прокси, CDN-сети и тп. Так вот, директива public позволяет абсолютно любым прокси-серверам осуществлять кэширование наравне с браузером.

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

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

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

must-revalidate
Эта директива предписывает браузеру делать обязательный запрос на сервер для ре-валидации контента (например, если вы используете eTag). Дело в том, что http в определенной конфигурации позволяет кэшу хранить контент, который уже устарел. must-revalidate обязывает браузер при любых условиях делать проверку свежести контента путем запроса к серверу.

proxy-revalidate
Это то же, что и must-revalidate , но касается только кэширующих прокси серверов.

s-maxage
Практически не отличается от мах-age , за исключением того, что эта директива учитывается только кэшем резличных прокси, но не самим браузером пользователя. Буква “s-” исходит из слова “shared” (например, CDN). Эта директива предназначена специально для CDN-ов и других посреднических кэшей. Ее указание отменяет значения директивы max-age и заголовка Expired . Впрочем, если вы не строите CDN-сети, то s-maxage вам вряд ли когда-либо понадобится.

Как посмотреть, какие заголовки используются на сайте?

Вы можете посмотреть заголовки http-запросов (request headers) и ответов (response headers) в отладчике Вашего любимого браузера. Вот например, как это выглядит в хроме:

То-же самое можно увидеть в любом уважающем себя браузере или http-сниффере.

Настройка кэшировения в Аpache и Nginx

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

Пример конфигурации Apache для контроля Expires

Выставляем различный “срок годности” для различных типов файлов. Один год для изображений, один месяц для скриптов, стилей, pdf и иконок. Для всего остального – 2 дня.

Пример конфигурации Nginx для контроля Expires

Выставляем различный “срок годности” для различных типов файлов. Одна неделя – для изображений, один день – для стилей и скриптов.

Пример конфигурации Apache для Cache-control (max-age и public/private/no-cache)

Пример конфигурации Nginx для Cache-control статических файлов

В заключение

“Кэшировать все то, что можно кэшировать” – хороший девиз для веб-разработчика. Иногда можно потратить всего несколько часов на конфигурацию и при этом значительно улучшить восприятие вашего сайта пользователем, значительно сократить нагрузку на сервер и сэкономить на трафике. Главное – не переусердствовать и настроить все правильно с учетом особенностей Вашего ресурса.

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

Как использовать кеш браузера пользователей для ускорения сайта (заголовки Last-Modified, ETag, Expires, Cache-Control)

Здравствуйте, уважаемые читатели блога Goldbusinessnet.com. Продолжаю цикл статей, которые касаются мероприятий по оптимизации, и сегодня настал черед для настройки использования в этих целях кэша браузера со стороны пользователей, что является очередным шагом выполнения рекомендаций Google Page Speed по ускорению сайта.

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

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

Рекомендация PageSpeed — используйте кэш браузера

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

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

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

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

Тогда после процедуры gzip сжатия файлов CSS, JS, HTML следующим по приоритету советом была как раз необходимость использования кэша браузера:

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


У моего теперешнего хостера кэширование включено, поэтому при анализе этого блога в упомянутом чуть выше online сервисе Pagespeed отразились опять же только внешние элементы, которые мне не подвластны (Граватар, контекстная реклама, Яндекс Метрика, Гугл Аналитикс):

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

Настройка кеширования в браузере пользователей в целях увеличения скорости сайта

Помните, в начале поста я обмолвился, что предлагаемый вариант не являются стопроцентно универсальным и подойдет не всем? К сожалению, это так. Дело в том, что этот метод годится только для серверов, управляемых ПО Apache (коих, правда, подавляющее большинство).

Более того, описанные ниже телодвижения дадут результат только в том случае, ежели у вас работает Апач в чистом виде. Если используется связка Apache + nginx, то настраивать придется последний, и в этом случае владельцам сайтов на разделенном виртуальном хостинге без помощи не обойтись. Так что придется обратиться к хостеру (впрочем, тоже вариант).

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

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

Находится .htaccess обычно в корневой директории (папке public_html или htdocs) вашего сайта. Для начала проверьте его наличие, подсоединившись к удаленному серверу, где хостится ваш проект, посредством ФТП-соединения (тут у меня разобран по косточкам менеджер Файлзилла). Если вы файла .htaccess в корне не наблюдаете, то попробуйте из верхнего меню FileZilla выбрать «Сервер» — «Принудительно отображать скрытые файлы»:

Если и в этом случае он не появится (что, впрочем, маловероятно), примените замечательный редактор Нотепад плюс плюс и создайте в нем такой файл:

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

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

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

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

Во-первых, необходимо обеспечить своевременное обновление веб-обозревателями кэшируемых объектов в интересах пользователей, которые будут получать в этом случае актуальный контент. Это можно сделать, используя заголовки Last-Modified и ETag (одновременно их оба нет нужды выводить, об этом недвусмысленно говорит сам Гугл).

На практике это означает, что при отправке браузером GET запроса (в данной статье вы найдете подробности о взаимодействии сервера и клиентских приложений) он получит HTTP ответ с кодом состояния 304 (без загрузки оттуда контента), если запрашиваемый ресурс не был изменен. Этот ответ означает, что можно загрузить контент из кеша.

И только в случае изменения содержание объекта будет отправлено для его отображения с сервера в составе ответа 200 (ОК). Подобная схема гарантирует максимальную экономию времени загрузки и одновременно актуальность отображаемой информации.

Во-вторых, нужно обязательно указать, на протяжении какого периода браузер должен хранить в кеше те или иные ресурсы. С этой целью можно использовать Expires либо Cache-Control с параметром max-age. Вывод этих заголовков инициируется с помощью модулей соответственно mod_expires и mod_headers, которые в том числе содержат названия объектов, к которым и будет применены правила хранения их в кеше.

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

В первую очередь, это весьма распространенные статические объекты, подлежащие хранению в кеше (скрипты, файлы стилей CSS, изображения с расширениями .png, .jpg, .gif и другие).

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

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

Итак, на основании выше сказанного нам нужно обеспечить вывод одного из заголовков Last-Modified и ETag, а также одного из пары Expires либо Cache-Control: max-age. Для наглядности и расширения диапазона рассмотрим различные варианты.

Вариации кодов для управления кешем с использованием заголовков Last-Modified, Expires и Cache-Control

Если на вашем хостинге уже настроен вывод того же Last-Modified, то пол-дела сделано (к слову, проверить наличие этого важного заголовка можно с помощью онлайн сервисов, включая в их список инструмент для проверки ответа сервера от Яндекса). Если же нет, то сделать это весьма несложно, прописав в том же незаменимом .htaccess пару строк:

Правда, работать этот метод будет опять же при условии наличия «чистого Апача» (но ведь как раз этот случай мы и рассматриваем). Будем считать, что заголовок Last-Modified, в качестве значения которого, кстати, будет выводится дата последнего изменения, настроен.

Теперь настала очередь Cache-Control с параметром max-age, в качестве значения которого будет прописан срок хранения в кеше каждого конкретного статического объекта. На сцену выходит модуль mod headers, код которого и следует вставить в .htaccess:

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

Время сохранения кеша определяется с помощью параметра max-age, его значение выставляется в секундах. Благодаря комментариям (которые, к слову, вы можете спокойно удалить), стоящим после символа решетки «#», основа этой конструкции, думаю, понятна.

Однако, вместо mod headers вполне можно воспользоваться модулем mod expires, выводящим заголовок Expires (который, по мнению самого Гугла является предпочтительнее, поскольку имеет более широкую поддержку). При этом фрагмент кода для его включения будет таким:

Точкой отсчета срока годности кэша в случае использования заголовка Expires является дата первой загрузки. Причем, в отличие от Cache-Control, где временной период определяется только в секундах, здесь он может указываться в любом временном формате, включая year (год).

Для того, чтобы убедиться в этом, посмотрите на участок кода, касающийся изображений. Там я специально указал время в различных единицах исчисления: 1 month (месяц), 4 weeks (недели), 30 days (дни), 43829 minutes (минуты), 2592000 seconds (секунды).

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

В дополнение к упомянутым модулям полезно задействовать еще и mod setenvif. Дело в том, что веб-обозреватели семейства Microsoft Internet Explorer и некоторые версии Мазилы корректно не воспринимают в ответе сервера HTTP заголовок Vary, который также вносит свою важную лепту в управление кэшированием. Этот модуль как раз позволяет решить эту проблему, исключая Vary из состава ответа сервера:

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

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

Код формирования заголовков Etag и Expires для настройки кэша

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

Но если в качестве значения Expires отображается дата последнего изменения, то в ETag используется тот или иной уникальный идентификатор ресурса (чаще в этой роли выступает версия файла). Для активации ETag требуется лишь ввести в тот же .htaccess одну строчку:

Ну а затем применить уже известный нам модуль mod expires. Можно добавить и mod setenvif, который, как я уже сказал выше, запрещает формирование заголовков Vary для определенной группы веб-браузеров, чтобы гарантировать образование кеша с их стороны:

Здесь использован комплекс с минимумом типов задействованных объектов, но зато наиболее востребованных (CSS, JavaScript и изображения), который также должен быть достаточным, чтобы обеспечить максимальную эффективность в ускорении сайта. При желании к комплекту «jpg|jpeg|gif|png|ico|css|js» можно добавить другие виды файлов.

Кроме того, в приведенном выше примере кода для всех файлов действует один и тот же период «жизни» кеша, равный одному году («access plus 1 year»), который является рекомендуемым со стороны Гугла. Но можно для каждой группы объектов указать свой временной отрезок по примеру содержания модулей mod_expires и mod_headers из предыдущего раздела статьи.

Проверка наличия нужных заголовков в ответе сервера

После того, как вы вставите код в файл .htaccess, можно проверить, находятся ли необходимые заголовки в составе ответа сервера. Для этой цели можно воспользоваться каким-нибудь онлайн сервисом, например, Checkmy.ru, где в качестве клиента (User Agent), посылающего HTTP-запрос на сервер, выбираем любой браузер, а также вводим URL ресурса (для примера я взял путь до изображения, используемого в одной из статей блога):

После нажатия кнопки «Отправить запрос», через несколько секунд появится результат:

Как видите, в моем случае присутствуют все четыре заголовка. Я говорил, что обязательно должны выводится по одному из пар «Last-Modified — ETag» и «Expires — Cache-Control», остальные излишни. При этом полный комплект, насколько можно судить, не причинит вреда.

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

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

Далее советую для закрепления материала обратиться к видео и посмотреть последовательно 6 уроков (один из которых посвящен настройке кеширования в браузерах), в которых подробно рассмотрены все наиболее важные аспекты ускорения сайта WP:

Повышение производительности загрузки страницы: Pingdom, YSlow и GTmetrix

Дата публикации: 2020-07-27

От автора: оптимизация скорости сайтов — это ремесло, а каждому ремеслу нужны инструменты. Наиболее используемыми инструментами, направленными на повышение производительности, являются GTmetrix, YSlow и Pingdom Tools.

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

YSlow по-прежнему актуальна, хотя лучшими ее были дни, когда Firebug правил среди инспекторов браузеров. Он предлагает приложение Chrome и другие реализации, такие как надстройки для Safari и Opera, букмарклет, расширение для PhantomJS и т. д.

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

Матрица правил YSlow в течение ряда лет была измерительной палочкой для работы сайта.

Как создать сайт самому?

Какие технологии и знания необходимы сегодня, чтобы создавать сайты самостоятельно? Узнайте на интенсиве!

Pingdom Tools — это сервис SaaS, который предлагает мониторинг и отчетность об эффективности веб-сайта, и в последние годы он укрепил свои позиции на рынке. Он также предлагает проверку работоспособности DNS и тестирование скорости веб-сайта на своем свободном уровне, что сопоставимо с GTMetrix и YSlow.

Для целей этой статьи мы приобрели подходящее доменное имя — ttfb.review — и установили Drupal с некоторым демо-содержимым на нем. Мы также установили WordPress на wp.ttfb.review и демонстрационные установки Yii и Symfony в своих соответствующих поддоменах.

Мы использовали начальную установку WordPress по умолчанию. Для Drupal мы использовали расширения Devel и Realistic Dummy Content для генерации демонстрационного контента. Для Symfony мы использовали демонстрационное приложение Symfony, а для Yii мы использовали базовый шаблон приложения.

Таким образом, мы сможем сравнить эти установки бок о бок и укажем на то, что заслуживает внимания.

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

GTmetrix

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

Мы видим, что наша установка Drupal загружалась быстрее всего, а установка Yii заняла целых десять секунд для загрузки. Однако было бы нецелесообразно использовать это для любого сравнения технологий, так как это не готовые к производству веб-сайты, а те системы, которые требуют больше знаний и работы по настройке, как ожидается, придут в режим отладки (или разработки). Другая вещь, которую следует иметь в виду, состоит в том, что для получения каких-либо убедительных результатов рекомендуется повторять тесты пару раз. Система виртуализации нашего сервера тестирования — OpenVZ, для которой распределение ресурсов может быть непоследовательным.

Мы можем видеть соответствующие показатели:

общее количество запросов


общий размер страницы

общее время загрузки

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

Шон Андерсон из агентства Hobo SEO из Великобритании опубликовал статью о соотношении между скоростью веб-сайта и конверсиями / рейтингом Google — с некоторыми интересными результатами.

Вещь, о которой нужно помнить — это то самое время. Все остальные показатели — простые рекомендации.

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

Первый набор результатов находится на вкладке PageSpeed, где мы видим, что единственное, что этот алгоритм жалуется на нашу установку Yii (самый медленный в нашем тесте) — это минимизация JS (или, скорее, ее отсутствие). Drupal является лучшим, хотя в нем есть большинство красных флагов. Если принять во внимание размер страницы, Symfony сделает все возможное, при этом вес страницы составляет всего 507 КБ.

Из этого примера видно, что простые тесты не говорят нам всего. Если перейти на вкладку YSlow, мы увидим более реалистичные оценки:

Но по-прежнему трудно приписать разницу времени загрузки для любого из этих элементов. Вот почему у нас есть вкладка «Водопад»: она показывает нам, где задержка. Сравнение водопада, из-за отсутствия экранной недвижимости, может сравнивать только два результата бок о бок, поэтому мы сравним установки Drupal и Yii (лучшее и худшее время загрузки) на этой странице результатов.

Это, наконец, дает нам некоторое представление о том, что ни один из предыдущих инструментов не дал нам. Целые девять секунд, потраченные Yii, расходуются на первый (основной) запрос HTML-кода веб-сайта, а не на статические ресурсы. Если мы навешиваем длинную фиолетовую линию на диаграмме Yii, у нас будет спецификация GTmetrix для нас точной анатомии этого девятисекундного ответа:

Здесь мы можем обнаружить, где лежит проблема — в фазе «Ожидание», на этапе генерации страницы или использовать более привычный термин TTFB, Time To First Byte. Это означает, что проблема лежит исключительно на нашей стороне Nginx или PHP. То, что мы можем сделать по этому поводу, многообразно и имеет много общего с тем, с чем мы имеем дело. Нам нужно будет проверить, где находится проблема на нашем сервере.

Это может быть ресурсоемкое приложение, неэффективные запросы к базе данных, ограничения на ОЗУ сервера и т. д. Инструмент, который может пригодиться здесь для мониторинга серверных процессов — это Monit, а также инструменты и процедуры для конкретных приложений для диагностики и улучшения времени загрузки. Двумя вещами, которые почти всегда улучшают TTFB, являются: больше ресурсов сервера и кеширование решений, таких как Varnish. Если статические ресурсы были основным виновником, нам нужно будет уделять больше внимания предупреждениям на вкладках PageSpeed и YSlow, gzipping, minification и, возможно, развертывать наш сайт на CDN, например Cloudflare.

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

Мы видим, что установка Drupal по умолчанию включает в себя некоторые решения для кеширования:

После того, как немного поработал с Drupal, и играя со своими встроенными модулями и параметрами конфигурации, такими как BigPipe и кешированием, мы могли бы уменьшить время загрузки еще на полсекунды:

На GTmetrix мы можем сравнить наши тесты с главной страницы:

Мы также можем просто добавить разные суффиксы URL-адреса, чтобы видеть их бок о бок:

Для вкладки «Видео» мы должны включить параметр видеозаписи в наших дополнительных опциях:

(Кстати, мы видим, что в последующих тестах разогрев кэша Drupal сократил время загрузки нашего сайта еще на 200 миллисекунд.)

Теперь у нас есть видео, доступное на вкладке Видео результатов:

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

В отдельных тестах есть также вкладка Timings, которая разделяет фазы загрузки и дает нам время и объяснение каждой фазы, например, Time To First Byte, о которой мы упоминали ранее:

(Это ttfb.review о загрузке Drupal с одной секундой).

Вкладка «История» в отчетах одной страницы предназначена для отслеживаемых страниц или нескольких тестов с течением времени, где мы можем видеть наш прогресс:

Для сравнения у нас есть вкладка «Графики»:

Есть больше настроек, которые можно найти на боковой панели:

Повторяя тесты, в ходе написания этой статьи мы увидели, что время загрузки для приложения Yii уменьшилось до 1,2 секунды, а Symfony — до 1,6 секунды.

С помощью Symfony на вкладке «История» показано, что TTFB остается прежним, а улучшение в 400 миллисекунд, скорее всего, связано с различием в загрузке статических ресурсов:

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

С Yii улучшение является более радикальным по всем трем показателям: TTFB, onload и полностью загруженному времени:

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

У GTmetrix есть еще много вариантов, и это выходит за рамки одной статьи. Например, даже по бесплатному плану мы можем протестировать мобильные или настольные браузеры, и мы можем имитировать скорость сети посетителя — ADSL, 3G и т. д.

Мы также можем протестировать веб-сайт из разных мест на земном шаре:

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

YSlow

YSlow, с его набором правил, пришел из работы разработчиков Yahoo Exceptional Performance. Он стал важным инструментом для веб-производительности, прежде всего, как дополнение Firebug, но это было устаревшим с помощью Firefox Quantum.

Как создать сайт самому?

Какие технологии и знания необходимы сегодня, чтобы создавать сайты самостоятельно? Узнайте на интенсиве!

Он по-прежнему доступен как букмарклет, расширение Safari , средство командной строки или приложение Chrome:

Мы можем выбрать набор правил для применения, установить строгость критериев и затем получить результаты в классе, с оценками по пунктам, от A до F, с пояснениями и ссылками для каждого элемента / измерения.

На вкладке «Оценка» мы можем отфильтровать наши результаты. Например, с нашим приложением Yii, отфильтровывая результаты только на те, которые относятся к Серверу, мы видим следующее:

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

Каждая из рекомендаций / оценок YSlow дает нам краткое объяснение и ссылку, чтобы больше узнать о теме.

Вкладка «Компоненты» дает нам обзор всех ресурсов или URL-адресов, загруженных во время загрузки страницы, включая саму страницу, JS, CSS, изображения, их размеры, сжатые размеры, файлы cookie, отправленные заголовки.

Например, в случае нашего демонстрационного приложения Yii мы можем видеть на вкладке «Компоненты», что мы не сжимаем наш JS должным образом (размер такой же, как несжатый), и не устанавливаем заголовки Expires, которые должны выполняться в производственное приложение:

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

На веб-сайте YSlow есть более подробное руководство по каждому из 23 критериев, которые он использует для оценки тестируемых веб-сайтов, с дальнейшими советами по оптимизации.

Инструменты Pingdom

Pingdom предлагает широкий набор инструментов, как для проверки работоспособности DNS, так и для полностраничного тестирования.

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

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

Ниже мы можем проверить наши HTTP-ответы и есть ли у нас проблемные перенаправления или неверные ответы (в случае, если некоторые из ресурсов не загружались):

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

Вернемся к нашей тестовой установке Drupal на https://ttfb.review, Pingdom дает нам — дальше по странице результатов — разбивка содержимого по типу, массе и проценту:

В случае упомянутого ресурсного ресурса, который мы тестировали (мы не оставили URL видимым, потому что это довольно плохой пример веб-сайта, который работает в производстве), мы можем видеть проблематичные части: массивное видео, Карты Google, виджет чата внешним поставщиком:

Назад с нашего сайта Drupal, Pingdom позволяет нам анализировать всю загрузку страницы, запрашивать по запросу, позволяя нам видеть, какие запросы / ответы составляют большую часть нашего времени загрузки:

Затем, по цветам, мы можем далее разбивать фазы каждого отдельного запроса / ответа и находить узкие места, либо избавляясь от самых дорогих ресурсов, либо gzipping их, уменьшая JS и CSS, или развертывая их на CDN.

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

Под этой диаграммой водопада Pingdom имеет цветовую легенду, объясняя каждую.

В случае с нашим веб-сайтом Drupal, поскольку мы настроили параметры DNS домена с нуля, когда мы начали писать эту статью, мы установили TTL записи A — Time To Live или время кэширования записи домена — до 1 минуты, пытаясь ускорить развертывание нашего домена. Чтобы уменьшить пинг, часть DNS первого запроса, мы увеличили бы время TTL, как только домен будет настроен максимально. Таким образом, настройка домена будет кэширована, и нет необходимости в тщательном поиске DNS домена.

Каждый из этих запросов имеет кнопку выпадающего меню справа, и, щелкая по нему, мы получаем представление о заголовках каждого запроса и ответа:

Здесь мы можем отлаживать, кэшируется ли запрос на сервере, кэшируется ли содержимое и т. д.

Например, с веб-сайта, развернутого в Cloudflare, из заголовков ресурсов видно, что cf-cache был HIT — это означает, что ресурс кэшируется, мы видим, что он настроен на gzipped, установлены заголовки истечения, а также заголовки управления кешем:

На веб-сайте, размещенном в Cloudflare, мы можем видеть на нашей диаграмме водопада Pingdom, загрузка ресурсов более параллельна, асинхронна и не блокируется. Этого также можно добиться, настроив наш сервер на использование протокола HTTP / 2:

(Нет ожиданий завершения одного цикла запроса / ответа для следующего запуска).

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

С Pingdom, как и с GTmetrix, мы можем выбрать место для тестирования. Мы попытались проверить нашу демонстрационную установку Yii, https://yii.ttfb.review, из Швеции (предыдущие тесты GTmetrix были сделаны из Ванкувера, Канада), и разница очевидна. На наш сайт теперь загружено 445 миллисекунд:


В этом случае мы также видим, что задержка DNS берет, возможно, больше, чем нужно. Мы должны уменьшить параметр TTL DNS, а синие части на статических ресурсах — это фаза «Подключиться», поэтому мы можем предположить, что HTTP / 2 с его усовершенствованиями keepalive сможет использовать одно соединение, чтобы вытолкнуть все эти ресурсы без накладных расходов на создание нового TCP-соединения для каждого ресурса:

Простейшим путем здесь, вероятно, будет CDN.

Задержка DNS еще более заметна, когда мы тестируем из Калифорнии:

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

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

Файлы HAR

Как GTmetrix, так и Pingdom дают нам возможность экспортировать файлы HAR. Файлы формата HAR — или HTTP Archive — это архивные файлы в формате JSON для регистрации взаимодействия веб-браузера с сайтом. Мы прикрепляем файл HAR из нашего теста GTmetrix тестовой установки WordPress (кстати, у него много проблем для отладки).

Этот файл является стандартным форматом для отладки отклика веб-сайта.

Затем этот файл можно импортировать в Har Analyzer Google:

Затем это может быть дополнительно проанализировано, разделено и т. д.

Другие инструменты

Другие инструменты, которые заслуживают упоминания — это Page Load Time for Chrome, которое работает как опрятный виджет браузера с краткими статистическими данными загрузки:

Он предлагает 24 места для тестирования, а затем подробные графики водопада для каждого из них.

Google PageSpeed Insights — еще один инструмент, который мы можем использовать для получения информации и рекомендаций по возможным улучшениям и лучшим практикам, как для мобильных, так и для настольных посетителей:

Заключение

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

Автор: Tonino Jankov

Редакция: Команда webformyself.

Как создать сайт самому?

Какие технологии и знания необходимы сегодня, чтобы создавать сайты самостоятельно? Узнайте на интенсиве!

Как ускорить сайт на WordPress в 17 раз. Пошаговая инструкция

Представляю наиболее полную инструкцию с способами по ускорению работы сайта на WordPress. Благодаря описанным ниже способам я ускорил загрузку своего сайта с 24,40 секунд до 1,41 секунды. Увеличил скорость загрузки в 17,3 раза! Хороший результат. Чтобы узнать как — читайте полную статью.

Замеры скорости работы сайта я проводил сервисом Pingdom Speed Test. Тестировал главную страницу сайта. Смотрите ниже показатели сайта «до» и «после» улучшений, и короткую и полную инструкцию по ускорению сайта.

Показатели сокрости загрузки сайта

Перед оптимизацией После оптимизации
Время загрузки 24.4 секунды 1.41 секунды
Количество запросов 94 запроса 76 запросов
Размер страницы 3.5 Мб 1.6 Мб

Скриншот замера скорости ПЕРЕД оптимизацией блога:

Скриншот замера скорости после оптимизации и проведенных ниже рекомендаций.
Ссылка на результат теста.

Короткое резюме по ускорению сайта на WordPress

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

Полная инструкция как ускорить сайт на WordPress

1. Качественный SSD хостинг, быстрый пинг

Хостинг должен быть на SSD дисках. Желательно чтобы сервера хостинга располагались в вашей географической зоне, на которую ориентирован сайт. Если хостинг будет на SSD, но в США, а ваш блог ориентирован на Россию и страны СНГ, то толку от такого SSD будет мало. Так как будет идти долгий пинг для связи с сервером. Поэтому месторасположение дата центра хостинга также важно. Это важный параметр хостинга — быстрый пинг, отклик серверов. И чтобы хостер не делал оверселлинг услуг. Про тип хостинга — конечно лучше брать как VDS (виртуальный выделенный сервер) с необходимыми для вашего сайта параметрами, вместо обычного shared хостинга. Какую именно конфигурацию VDS выбрать — это зависит от нагрузки которую ваш сайт создает не сервер и от размера его суточной аудитории. Я бы советовал брать минимум 1Gb Ram, 1 ядро процессора и 10 Гб SSD. В начале у меня был VDS на обычных HDD дисках, затем я поменял его на SSD VDS хостинг.

Хостинг «До»:

VPS хостинг FreeHost.com.ua
Размер диска: 30 Gb HDD
Память: 2 Gb RAM
Частота CPU: 2,2 Ghz
Количество CPU: 1
Расположение серверов: Киев, Украина
Стоимость: 12,8 $/месяц

Хостинг «После»:

VDS хостинг от ihor.ru
Размер диска: 20 Gb HDD
Память: 1 Gb RAM
Частота CPU: 2,4 Ghz
Количество CPU: 1
Расположение серверов: Москва, Россия
Стоимость: 250 руб/месяц (примерно 5$/месяц)

По скриншотам теста скорости загрузки сайта, видно что на старом хостинге время ответа сайта достигало 12,3 секунды. Что непомерно много. На новом хостинге от ihor.ru время ответа сайта составляло 1,2 секунды, что в разы быстрее, по сравнению со старым хостингом. На этот показатель повлияли SSD диски, и более лучший дата центр с лучшим и более быстрым каналом.

Смена хостинга является одной из главных причин ускорения работы сайта.

2. Оптимизировать изображения

Проверьте используете ли вы оптимизированные jpg файлы изображений. Которые занимают небольшой размер и при этом обладают хорошим качеством. В Photoshop сохранять такие изображения можно командой Save for Web (Ctrl + Shift + Alt + S), или через функцию export assets если вы используете Photoshop CC. Не стоит сохранят большие непрозрачные картинки в .png формате, он занимает слишком много места, и для этого лучше использовать jpeg формат. Формат png подходит для небольшой графики которая используется в оформлении сайта, в шаблоне, это могут быть изображения кнопок, буллеты, изображения с прозрачным фоном.

Некоторые миниатюры к записям у меня были сохранены в .png формате, и размер изображения достигал 300 Кб. Пересохранив изображения в jpg формат, каждая миниатюра стала занимать 60-90 Кб в среднем. Таким образом вес некоторых изображений уменьшился в 3-4 раза, без потери качества.

Существует специальный плагин для оптимизации изображений – WP Smush. Признаюсь — я ним не пользуюсь, так как сам перед публикацией оптимизирую все изображения на предмет размера и качества. Но если вы хотите автоматизировать процесс — то используйте этот плагин.

3. Настройка wp-config.php для ускорения работы сайта на wordpress

Небольшой способ снизить загрузку на хостинг — отредактировать файл wp-config.php, который находится в коревой директории вашего сайта.

Находим в файле wp-config.php строку:

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

4. Настройка Robots.txt — запрет на индексацию ненужным сайтам.

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

Например, помимо роботов от Yandex и Google на сайт также заходит поисковый робот от поисковика Yahoo. Таким кодом можно запретить Yahoo роботу просматривать сайт:

Я прописал следующие запрещающие директивы:

Вот пример моего файла robots.txt

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

5. Настройка файла .htaccess для снижения нагрузки на сервер.

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

Настройка №1. Часто с сайтов копируют информацию вместе с картинками, не изменяя адреса картинок. И когда такое происходит картинки лежащие на нашем хостинге загружаются на других сайтах, и это создает ненужную нагрузку на хостинг.

Следующим кодом можно запретить загружать изображения нашего сайта на сторонних сайтах:

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

Настройка №2. В файле .htaccess можно и следует указать кэширование для некоторых объектов сайта (изображений, css и js фалов) чтобы браузер кешировал их на своей стороне и не загружал их каждый раз. Для этого в .htaccess ниже первого кода добавляем следующий код:

Настройка №3. Включим gzip сжатие страниц перед отправкой их пользователю. Вставим в .htaccess следующий код:

Настройка №4. Ограничение спама в комментариях. Большинство спам комментариев отправляются автоматически. Этим кодом мы запретим напрямую отсылать комментарии минуя форму комментирования. Теперь спам боты не смогу отправлять комментарии.

Настройка №5. Если вы пользуетесь системой FeedBurner, то у вас явно установлены плагины, которые отправляют RSS-контент на сайт FeedBurner. Сегодня вы можете их удалить, потому что перенаправить контент можно и без плагинов, уменьшив нагрузку на хостинг.

ВНИМАНИЕ. Не забудьте в примерах выше заменить адрес yourdomain.ru на адрес своего сайта.

6. Оптимизация базы данных

Важное значение в скорости работы сайта имеет База Данных. При сохранении постов по нескольку раз WordPress создает ревизии записи — состояния постов в разные моменты их редактирования. В результате со временем база данных содержит большое количество ненужных ревизий постов, и их необходимо очищать и оптимизировать. Сделать это можно с помощью плагина Optimize DB. Установить его можно из админки WordPress. Например запустив его на своем сайте я удалили более 1200 ревизий постов. Что значительно улучшило скорость работы БД.

7. Оптимизация кода шаблона (темы)

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

Настройка №1. Найти код, который отвечает за стили в файле header.php:


Внимание. Не забудьте изменить yoursite.ru на ссылку своего сайта.

Настройка №2. Изменить код пинбеков:

Заменить с исправлением yoursite.ru на свою ссылку:

Настройка №3. Изменение кода RSS ленты:

Заменить с исправлением yoursite.ru на свою ссылку:

Настройка №4. Довольно часто в подвале сайта (footer.php), разработчики тем оставляют совершенно ненужные запросы к Базе данных. Например:

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

Некоторые маленькие советы, которые позволят ускорить загрузку сайта:

1) Если ваш сайт не использует комментарии, не стоит их скрывать с помощью плагинов, это создает совершенно ненужную нагрузку. Так как вам комментарии совершенно не нужны, просто удалите следующий код из файла темы (single.php):

2) Старайтесь не использовать внешние скрипты, такие как, комментарии от Вконтакте, различные виджеты социальных сетей. Да, это выглядит красиво и эффектно, но создает приличную нагрузку на сайт. Из примеров могу сказать что мой сайт значительно грузил код веб-визора от ЯндексМетрики, виджет Add.This. Кнопки соц сетей я поменял на отельный JS плагин.

3) Почистите весь код вашего сайта от комментариев, данные комментарии вставляются с помощью тегов и /*код/. Оставьте только нужное, так как сайту приходится тратить лишние силы на их загрузку…

4) Старайтесь размещать все скрипты в конце страницы перед закрвающим тегом

Лучшие практики кэширования

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

Подавляющее большинство лучших практик кэширования относится к одному из двух паттернов:

Паттерн №1: неизменяемый контент и долгий max-age кэша

  • Содержимое по URL не меняется, следовательно…
  • Браузер или CDN могут без проблем закэшировать ресурс на год
  • Закэшированный контент, который младше, чем заданный max-age может использоваться без консультации с сервером

Страница : Эй, мне нужны «/script-v1.js» , «/styles-v1.css» и «/cats-v1.jpg» 10:24

Кэш : У меня пусто, как насчет тебя, Сервер? 10:24

Сервер : ОК, вот они. Кстати, Кэш, их стоит использовать в течение года, не больше. 10:25

Страница : Ура! 10:25

Страница : Эй, мне нужны «/script-v2.js» , «/styles-v2.css» и «/cats-v1.jpg» 08:14

Кэш : Картинка с котиками есть, остального нет. Сервер? 08:14

Сервер : Легко — вот новые CSS & JS. Еще раз, Кэш: их срок годности не больше года. 08:15

Кэш : Супер! 08:15

Страница : Спасибо! 08:15

Кэш : Хм, я не пользовался «/script-v1.js» & «/styles-v1.css» достаточно долго. Пора их удалять. 12:32

Используя этот паттерн, вы никогда не меняете контент определенного URL, вы меняете сам URL:

В каждом URL есть что-то, меняющееся одновременно с контентом. Это может быть номер версии, модифицированная дата или хэш контента (этот вариант я и выбрал для своего блога).

В большинстве серверных фреймворков есть инструменты, позволяющие с легкостью делать подобные вещи (в Django я использую Manifest​Static​Files​Storage); есть также совсем небольшие библиотеки в Node.js, решающие те же задачи, например, gulp-rev.

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

Паттерн №2: изменяемый контент, всегда проходящий ревалидацию на сервере

  • Содержимое URL изменится, значит…
  • Любая локальная закэшированная версия не может использоваться без указания сервера.

Страница : Эй, мне нужно содержимое «/about/» и «/sw.js» 11:32

Кэш : Ничем не могу помочь. Сервер? 11:32

Сервер : Есть такие. Кэш, держи их при себе, но перед использованием спрашивай у меня. 11:33

Кэш : Так точно! 11:33

Страница : Спс! 11:33

На следующий день

Страница : Эй, мне опять нужно содержимое «/about/» и «/sw.js» 09:46

Кэш : Минутку. Сервер, с моими копиями все в порядке? Копия «/about/» лежит с понедельника, а «/sw.js» вчерашняя. 09:46

Сервер : «/sw.js» не менялась… 09:47

Кэш : Круто. Страница, держи «/sw.js» . 09:47

Сервер : …но «/about/» у меня новой версии. Кэш, держи ее, но как и в прошлый раз, не забудь сначала спросить меня. 09:47

Кэш : Понял! 09:47

Страница : Отлично! 09:47

Примечание: no-cache не значит “не кэшировать”, это значит “проверять” (или ревалидировать) закэшированный ресурс у сервера. А не кэшировать совсем браузеру приказывает no-store . Также и must-revalidate означает не обязательную ревалидацию, а то, что закэшированный ресурс используется только, если он младше, чем заданный max-age , и только в ином случае он ревалидируется. Вот так все запущено с ключевыми словами для кэширования.

В этом паттерне мы можете добавить к ответу ETag (идентификатор версии на ваш выбор) или заголовок Last-Modified . При следующем запросе содержимого со стороны клиента, выводится If-None-Match или If-Modified-Since соответственно, позволяя серверу сказать “Используй то, что у тебя есть, твой кэш актуален”, то есть вернуть HTTP 304.

Если отправка ETag / Last-Modified невозможна, сервер всегда отсылает содержимое полностью.

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

Это не редкость, когда у нас нет инфраструктуры для первого паттерна, но точно также могут возникнуть проблемы с сетевыми запросами в паттерне 2. В итоге используется промежуточный вариант: короткий max-age и изменяемый контент. Это плохой компромисс.

Использование max-age с изменяемым контентом это, как правило, неправильный выбор

И, к сожалению, он распространен, в качестве примера можно привести Github pages.

С серверным заголовком:

  • Содержимое URL меняется
  • Если в браузере есть кэшированная версия свежее 10 минут, она используется без консультации с сервером
  • Если такого кэша нет, используется запрос к сети, по возможности с If- Modified-Since или If-None-Match

Страница : Эй, мне нужны «/article/» , «/script.js» и «/styles.css» 10:21

Кэш : У меня ничего нет, как у тебя, Сервер? 10:21

Сервер : Без проблем, вот они. Но запомни, Кэш: их можно использовать в течение ближайших 10 минут. 10:22

Страница : Спс! 10:22


6 minutes later

Страница : Эй, мне опять нужны «/article/» , «/script.js» и «/styles.css» 10:28

Кэш : Упс, я извиняюсь, но я потерял «/styles.css» , но все остальное у меня есть, держи. Сервер, можешь подогнать мне «/styles.css» ? 10:28

Сервер : Легко, он уже изменился с тех пор, как ты в прошлый раз забирал его. Ближайшие 10 минут можешь смело его использовать. 10:29

Кэш : Без проблем. 10:29

Страница : Спасибо! Но, кажется, что-то пошло не так! Все поломалось! Что, вообще, происходит? 10:29

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

Часто при внесении значительных изменений в HTML, мы меняем и CSS, для правильного отражения новой структуры, и JavaScript, чтобы и он не отставал от контента и стилей. Все эти ресурсы независимы, но заголовки кэширования не могут выразить это. В итоге у пользователей может оказаться последняя версия одного/двух ресурсов и старая версия остальных.

max-age задается относительно времени ответа, поэтому если все ресурсы передаются как часть одного адреса, их срок истечет одновременно, но и здесь сохраняется небольшой шанс рассинхронизации. Если у вас есть страницы, не включающие JavaScript или включающие другие стили, сроки годности их кэша будут рассинхронизированы. И хуже того, браузер постоянно вытаскивает содержимое из кэша, не зная, что HTML, CSS, & JS взаимозависимы, поэтому он с радостью может вытащить что-то одно из списка и забыть про все остальное. Учитывая все эти факторы вместе, вы должны понять, что вероятность появления несовпадающих версий достаточно велика.

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

К счастью, у пользователей есть запасной выход…

Обновление страницы иногда спасает

Если страница загружена путем обновления, браузеры всегда проводят серверную ревалидацию, игнорируя max-age . Поэтому, если у пользователя что-то поломалось вследствие max-age , простое обновление страницы может все исправить. Но, разумеется, после того как ложки найдутся, осадок все равно останется и отношение к вашему сайту будет несколько иным.

Сервис-воркер может продлить жизнь этих багов

Например, у вас есть такой сервис-воркер:

  • кэширует скрипт и стили
  • использует кэш при совпадении, иначе обращается к сети

Если мы меняем CSS/JS, мы также увеличиваем номер version , что инициирует обновление. Однако, так как addAll обращается сначала к кэшу, мы можем попасть в состояние гонки из-за max-age и несоответствующих версий CSS & JS.

После того как они закэшированы, у нас будут несовместимые CSS & JS до следующего обновления сервис-воркера — и это если мы опять не попадем при обновлении в состояние гонки.

Вы можете пропустить кэширование в сервис-воркере:

К сожалению, опции для кэширования не поддерживаются в Chrome/Opera и только-только добавлены в ночную сборку Firefox, но вы можете сделать это самостоятельно:

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

Сервис-воркеры и HTTP-кэш отлично работают вместе, не заставляйте их воевать!

Как видите, вы можете обойти ошибки с кэшированием в вашем сервис-воркере, но правильней будет решить корень проблемы. Правильная настройка кэширования не только облегчает работу сервис-воркера, но и помогает браузерам, не поддерживающим сервис-воркеры (Safari, IE/Edge), а также позволяет вам извлечь максимум из вашей CDN.

Правильные заголовки кэширования также могут значительно упростить обновление сервис-воркера.

Здесь я закэшировал корневую страницу с паттерном №2 (серверная ревалидация) и все остальные ресурсы с паттерном №1 (неизменяемый контент). Каждое обновление сервис-воркера будет вызывать запрос к корневой странице, а все остальные ресурсы будут загружаться только, если их URL изменился. Это хорошо тем, что сохраняет трафик и улучшает производительность, независимо от того, обновляетесь ли вы с предыдущей или очень старой версии.

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

Сервис-воркеры работают лучше в качестве улучшения, а не временного костыля, поэтому работайте с кэшем вместо того, чтобы воевать с ним.

При аккуратном использовании max-age и изменяемый контент могут быть очень хороши

max-age очень часто бывает неправильным выбором для изменяемого контента, но не всегда. Например, у оригинала статьи max-age составляет три минуты. Состояние гонки не является проблемой, так как на странице нет зависимостей, использующих одинаковый паттерн кэширования ( CSS, JS & изображения используют паттерн №1 — неизменяемый контент), все остальное этот паттерн не использует.

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

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

При правильном использовании кэширование дает значительное улучшение производительности и экономию трафика. Передавайте неизменяемый контент, если вы можете легко изменить URL, или используйте серверную ревалидацию. Смешивайте max-age и изменяемый контент, если вы достаточно смелы и уверены, что у вашего контента нет зависимостей, которые могут рассинхронизироваться.

Основы кэширования в ASP.NET

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

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

Конечно, сохранение информации в памяти — не всегда хорошая идея. Память сервера — ограниченный ресурс; если вы попытаетесь сохранить в ней слишком много, то некоторая информация будет сброшена на диск, что потенциально может замедлить работу всей системы. Вот почему наилучшие стратегии кэширования (в том числе встроенные в ASP.NET) являются самоограниченными. Когда вы сохраняете информацию в кэше, то чаще всего ожидаете найти ее там при следующем запросе. Однако время существования такой информации зависит от сервера. Если кэш переполняется, или другое приложение запрашивает значительный объем памяти, эта информация будет выборочно удалена из кэша для обеспечения максимальной общей производительности. Как раз такая самодостаточность и делает кэширование настолько мощным (и сложным для самостоятельной реализации).

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

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

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

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

Кэширование вывода

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

Кэширование данных

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

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

На основе этих моделей построены также два специализированных типа кэширования:

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

Кэширование источников данных.

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

Кэширование вывода

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

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

Декларативное кэширование вывода

Чтобы увидеть кэширование вывода в действии, можно создать простую страницу, отображающую текущее время. На рисунке ниже показан пример. Код для этой страницы достаточно прост. Он устанавливает текущую дату и время в метке Label1 при наступлении события Page.Load:

Существуют два способа добавить страницу в кэш вывода. Наиболее распространенный подход заключается во вставке директивы OutputCache в начало файла .aspx, непосредственно под директивой Page:

В этом примере атрибут Duration инструктирует ASP.NET о том, что страницу нужно хранить в кэше в течение 20 секунд. Атрибут VaryByParam также необходим, но о нем речь пойдет в следующем разделе.

Запустив эту тестовую страницу, вы обнаружите некоторое интересное поведение. При первом обращении к ней будет отображено текущее время. Если обновить страницу спустя несколько секунд, ее содержимое не изменится. Вместо этого ASP.NET автоматически отправит кэшированный HTML-вывод (предполагая, что это случилось до истечения 20 секунд, и поэтому копия не была удалена из кэша). Если ASP.NET получает запрос после того, как кэшированная страница устарела, ASP.NET запустит ее код снова, сгенерировав новую кэшированную копию, и будет использовать ее в течение следующих 20 секунд.

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

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

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

Кэширование и строка запроса

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

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

В рассматриваемом примере атрибут VaryByParam устанавливается в None. Это сообщает ASP.NET, что мы хотим хранить только одну копию кэшируемой страницы, которая подходит для всех сценариев. Если запрос к этой странице будет добавлять строку аргументов к URL, это не имеет значения — ASP.NET все время будет использовать тот же самый вывод, пока он не устареет. Вы можете проверить это, добавляя параметр строки запроса вручную в окне браузера (как, например, ?a=b ).

На основе этого эксперимента вы можете предположить, что кэширование вывода не подходит для страниц, использующих аргументы в строке запроса. Однако ASP.NET предлагает другой выбор. Значение атрибута VaryByParam можно установить в «*», указав, что страница использует строку запроса, и таким образом проинструктировать ASP.NET о том, что нужно кэшировать отдельные копии страницы для разных значений аргументов в строке запроса:

Теперь, когда вы обратитесь к странице с дополнительной информацией в строке запроса, ASP.NET проверит эту строку. Если она будет соответствовать предыдущему запросу, и кэшированная копия этой страницы существует, то она будет использована повторно. В противном случае будет создана новая копия страницы и помещена в кэш отдельно.


Чтобы лучше представить, как работает этот процесс, рассмотрим следующую последовательность запросов:

Вы запрашиваете страницу без каких-либо параметров строки запроса и получаете копию страницы A.

Вы запрашиваете страницу с параметром Product >

Другой пользователь запрашивает страницу с параметром Product >

Другой пользователь запрашивает страницу с параметром Product >

Затем пользователь запрашивает страницу без параметров строки запроса. Если копия A не устарела, она извлекается из кэша и отправляется ему.

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

Кэширование со специфичными параметрами строки запроса

Установка VaryByParam=»*» позволяет использовать кэширование с динамическими страницами, которые варьируют свой вывод в зависимости от строки запроса. Этот подход может быть исключительно полезен для детальной страницы товара, которая принимает идентификатор товара в строке запроса. При кэшировании с варьированием параметров можно сохранять отдельную страницу для каждого товара, таким образом, экономя на обращениях к базе данных. Однако чтобы получить выигрыш в производительности, может понадобиться увеличить время существования кэшированного вывода до нескольких минут или больше.

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

Во многих ситуациях установка VaryByParam=»*» вносит ненужную неопределенность. Обычно лучше специально идентифицировать важную переменную строки запроса по имени. Вот пример:

В этом случае ASP.NET будет проверять строку запроса, пытаясь найти параметр ProductID. Запросы с разными параметрами ProductID будут кэшироваться раздельно, но все остальные параметры будут игнорироваться. В частности, это может оказаться удобным, если страница может принимать дополнительную информацию в строке запроса, которую она не использует. Без вашей помощи ASP.NET не имеет возможности отличить «важные» параметры строки запроса.

Можно указать несколько параметров, разделяя их точками с запятой:

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

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

Настраиваемое управление кэшем

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

Один из способов применения настраиваемого кэширования — хранение разных версий страницы для различных типов браузеров. Таким образом, браузеры Firefox всегда будут получать оптимизированные для Firefox страницы, a Internet Explorer получит HTML-разметку, оптимизированную именно для него. Чтобы настроить такую логику, следует начать с добавления директивы OutputCache к страницам, которые будут кэшироваться. В атрибуте VaryByCustom должно быть указано имя, представляющее тип создаваемого наслаиваемого кэширования. В следующем примере применяется имя браузера, поскольку страницы должны кэшироваться на основе клиентского браузера:

Далее потребуется создать процедуру, которая будет генерировать пользовательскую строку кэширования. Эта процедура должна быть закодирована в файле приложения global.asax, как показано ниже:

Функция GetVaryByCustomString() получает имя VaryByCustom в параметре arg. Это позволяет создавать приложение, которое реализует несколько типов настраиваемого кэширования в одной и той же функции. Каждый отдельный тип должен использовать отличающееся имя VaryByCustom (такое как Browser, BorwserVersion или DayOfWeek). Функция GetVaryByCustomString() должна проверить имя VaryByCustom и вернуть соответствующую строку кэширования. Если строки кэширования для разных запросов совпадают, ASP.NET использует кэшированную копию страницы. Или, если посмотреть с другой стороны, ASP.NET будет создавать и сохранять в кэше отдельные котированные версии страницы для каждой строки кэширования, которую встретит.

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

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

Директива OutputCache также включает третий атрибут, который можно использовать для определения кэширования. Этот атрибут — VaryByHeader — позволяет сохранять отдельные версии страницы на основе значения заголовка HTTP, полученного с запросом. Можно указывать один заголовок или целый список заголовков, разделенных точками с запятой. Такой прием можно применять на многоязычных сайтах, чтобы кэшировать разные версии страницы на основе языка клиентского браузера, как показано ниже:

Кэширование с помощью класса HttpCachePolicy

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

Однако есть и другой выбор: можно написать код, использующий специальное встроенное свойство Response.Cache, которое предоставляет экземпляр класса System.Web. HttpCachePolicy. Этот объект содержит свойства, позволяющие включать кэширование для текущей страницы. Это позволяет программно решить, нужно ли включать кэширование вывода.

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

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

Послекэшевая подстановка и кэширование фрагментов

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

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

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

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

Кэширование фрагментов

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

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

Послекэшевая подстановка

Средство послекэшевой подстановки вращается вокруг единственного метода, добавленного в класс HttpResponse. Этот метод называется WriteSubstitution() и принимает один параметр — делегат, указывающий на метод обратного вызова, который вы реализуете в своем классе страницы. Метод обратного вызова возвращает содержимое этой части страницы.

Трюк состоит вот в чем: когда среда обработки страниц ASP.NET извлекает кэшированную страницу, она автоматически инициирует метод обратного вызова, чтобы получить от него динамическое содержимое. Затем она вставляет это содержимое в кэшированную HTML-разметку страницы. Изящество в том, что даже если страница еще не была помещена в кэш (она генерируется первый раз), ASP.NET все равно вызывает метод обратного вызова для получения динамического содержимого. По сути, идея заключается в том, что вы создаете метод, который генерирует некоторое динамическое содержимое, чем гарантируете, что он всегда будет вызван, и то, что он выдаст, никогда не будет помещено в кэш.

Метод, генерирующий динамическое содержимое, должен быть статическим. Это объясняется тем, что среда ASP.NET должна иметь возможность вызывать его, даже если не существует доступного экземпляра класса страницы. (Очевидно, что когда страница доставляется клиенту из кэша, объект страницы не создается.) Сигнатура метода достаточно проста — он принимает объект HttpContext, который представляет текущий запрос, и возвращает строку с новой HTML-разметкой. Ниже приведен пример возвращения даты с полужирным форматированием:

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

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

Но если вы не хотите заниматься разработкой пользовательского элемента управления, чтобы получить в свое распоряжение средство послекэшевой подстановки, то ASP.NET предлагает сокращенный вариант — обобщенный элемент управления Substitution, использующий эту технологию для того, чтобы делать все свое содержимое динамическим. Элемент управления Substitution привязывается к статическому методу, возвращающему динамическое содержимое, точно так же, как в предыдущем примере. Однако элемент Substitution можно разместить рядом с другими элементами управления ASP.NET, позволяя явно контролировать место появления динамического содержимого.

Рассмотрим пример, который дублирует предыдущий, используя разметку в .aspx-части страницы:

К сожалению, во время проектирования содержимое элемента управления Substitution не видно.

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

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

Профили кэшей

Одна из проблем кэширования вывода связана с необходимостью встраивания инструкции в страницу — либо в часть разметки .aspx, либо в код класса. Хотя первый вариант (использование OutputCache) относительно ясен, все же он порождает проблемы управления, если создаются десятки кэшированных страниц. Если вы хотите изменить кэширование для всех этих страниц (например, изменив время нахождения объектов в кэше с 30 до 60 секунд), то придется модифицировать каждую страницу. Кроме того, ASP.NET понадобится их все перекомпилировать.

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

Теперь этот профиль можно использовать на странице через атрибут CacheProfile:

Конфигурация кэша

Конфигурировать различные детали поведения кэша ASP.NET можно через файл web.config. Многие из этих опций предназначены для упрощения отладки и могут не иметь смысла в готовом рабочем приложении. Для конфигурирования этих настроек используется элемент внутри описанного ранее элемента . Элемент предоставляет несколько опций для настройки:

Используйте disableMemoryCollection и disableExpiration для прекращения сбора элементов ASP.NET, когда объем свободной памяти ограничен (процесс называется очисткой), и удаления устаревших элементов. Будьте осторожны с этими настройками, поскольку вы можете легко привести к перерасходу памяти вашим приложением.

Применяйте percentagePhysicalMemoryUsedLimit для установки максимального процента физической памяти компьютера, разрешенной для использования в кэше ASP.NET. Когда кэш достигнет этого предела памяти, ASP.NET начинает очистку, удаляя самые старые или наиболее редко используемые элементы. Значение 0 указывает, что под кэш не должно оставляться никакой памяти, и что ASP.NET следует удалять элементы столь же быстро, как они и добавляются. По умолчанию ASP.NET использует для кэширования до 90% физической памяти.

Параметр privateBytesLimit определяет максимальное количество байт, которые специфическое приложение может использовать для своего кэша, прежде чем ASP.NET начнет интенсивную очистку. Этот лимит включает как память, используемую кэшем, так и память, расходуемую при обычной работе приложения. Значение 0 (по умолчанию) указывает, что ASP.NET будет использовать собственный алгоритм для определения момента, когда начнется освобождение памяти. Параметр privateBytesPollTime указывает, насколько часто ASP.NET проверяет используемые приватные байты (private bytes). По умолчанию это значение составляет 2 минуты.

Расширяемость кэширования вывода

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

Однако система кэширования ASP.NET не работает столь же хорошо, если в кэш требуется помещать крупные объемы данных на длительное время. Например, возьмем пополняемый каталог товаров в какой-нибудь гигантской компании электронной коммерции. Предполагая, что каталог товаров изменяется нечасто, может возникнуть желание кэшировать тысячи страниц с данными о товарах во избежание затрат на их создание. Но при таком большом объеме данных использование для этого памяти веб-сервера будет рискованным делом. Поэтому предпочтение следует отдать хранилищу другого типа, которое медленнее памяти, но быстрее процесса воссоздания страниц (и с меньшей вероятностью приводящего к нехватке ресурсов). Возможными вариантами может быть дисковое хранилище, база данных или распределенная система хранения, подобная Windows Server AppFabric.

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

В прошлом применение экзотических систем кэширования было возможно, но их реализация была совершенно отдельной от ASP.NET. В результате каждое стороннее решение кэширования имело собственный API-интерфейс. Но в ASP.NET 4 к средству кэширования была добавлена модель поставщиков, которая позволяет подключать поставщиков кэша, которые используют разные хранилища. Однако помните о двух следующих аспектах:

ASP.NET не включает никаких заготовленных поставщиков кэширования. Тем не менее, члены команды разработчиков ASP.NET уже продемонстрировали прототипы, которые используют кэширование на основе файлов и Windows Server AppFabric. Они намерены превратить их в отдельные компоненты, доступные для бесплатной загрузки на www.codeplex.com. Вдобавок архитекторы ASP.NET пообещали выпустить примеры, показывающие, как интегрировать кэширование вывода ASP.NET и популярную распределенную систему кэширования memcached с открытым исходным кодом.

Специальные поставщики можно использовать только с кэшированием вывода, но не кэшированием данных.

В последующих разделах приведен простой пример решения по кэшированию на основе файлов.

Построение специального поставщика кэша

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

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

Сокращенное использование памяти

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

Создать специальный поставщик кэша довольно просто. Унаследуйте новый класс от OutputCacheProvider из пространства имен System.Web.Caching. Затем переопределите в нем методы, описанные в таблице ниже:

Переопределяемые методы OutputCacheProvider

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

Добавляет элемент в кэш, если такового там не существует. В противном случае метод ничего не должен делать

Добавляет элемент в кэш. Если такой элемент там уже существует, этот метод должен перезаписать его

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

Удаляет элемент из кэша

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

После создания этих классов остается только переопределить методы Add(), Set(), Get() и Remove(). Все эти методы получают ключ, который уникально идентифицирует кэшированное содержимое. Ключ основан на имени файла кэшированной страницы. Например, если кэширование вывода используется для страницы по имени OutputCaching.aspx на веб-сайте CustomCacheProvider, код может получить следующий ключ:

Для преобразования этого ключа в действительное имя файла символы \ просто заменяются в коде символами дефиса (-). Кроме того, добавляется расширение .txt, которое позволяет различать это кэшированное содержимое от настоящей страницы ASP.NET и облегчает ее открытие и просмотр во время отладки. Вот пример преобразованного имени файла:

Для выполнения такого преобразования FileCacheProvider использует приватный метод по имени ConvertKeyToPath(). Ниже показано полное определение класса FileCacheProvider и сериализуемого класса CacheItem:

Давайте разберем этот код более подробно. Метод Set() всегда сохраняет свое содержимое, в то время как метод Add() должен сначала проверить его существование. Кроме того, Add() возвращает кэшированный объект. Действительный код сериализации просто использует BinaryFormatter для преобразования визуализированной страницы в поток байтов, которые затем могут быть записаны в файл. Метод Get() столь же прост. Однако он должен проверять дату истечения срока хранения у извлекаемого элемента и отбрасывать его, если срок хранения истек. И, наконец, метод Remove() просто удаляет файл с кэшированными данными.

Использование специального поставщика кэша

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

Здесь предполагается, что FileCacheProvider — это класс в текущем веб-приложении (например, файл в папке App_Code беспроектного веб-сайта). Если бы он являлся частью отдельной сборки, понадобилось бы включить имя этой сборки. Например, класс FileCacheProvider из пространства имен CustomCaching, скомпилированный в сборку по имени CacheExtensibility, потребует следующую конфигурацию:

Добавить комментарий
Метод Описание
Initialize()