Опубликован: 16.06.2010 | Уровень: специалист | Доступ: платный
Лекция 9:

Практическое приложение

< Лекция 8 || Лекция 9: 12345678

8.1. Разгоняем ASP .NET: 100 баллов и оценка "А" в YSlow

Этот раздел написан под впечатлением статьи Viktar Karpach YSlow and ASP.NET: 100 points "A" grade is possible (http://www.karpach.com/ yslow-and-asp-net-100-points-a-grade.htm). Здесь мы разберем по шагам, как максимально ускорить работу вашего сайта на ASP .NET. Далее приводятся пункты рекомендаций советов от Yahoo!, с которыми могут возникнуть сложности.

Измерения скорости загрузки сайта при помощи YSlow.            Источник: www.karpach.com

Рис. 8.1. Измерения скорости загрузки сайта при помощи YSlow. Источник: www.karpach.com

8.1.1. Меньше HTTP-запросов

Во-первых, нужно объединить в один файл таблицы стилей и файлы скриптов. Это стоит сделать только для рабочего (не тестового) выпуска сайта при помощи MS BuiLd:

<ItemGroup>
<TextFiles Include="*.css" Exclude="global.css"/>
</ItemGroup>
<Exec Command="echo y| type %(TextFiles.Identity) >> global.css"/>

Таким образом мы можем объединить все CSS- и JS-файлы. Некоторые разработчики зададут резонный вопрос: а что можно сказать по поводу WebResource.axd? В новом AJAX ControL TooLkit есть TooLkitScriptManager, который позволяет объединить большинство ваших файлов WebResource.axd. Также он может применять к ним gzip-сжатие (это будет важно для следующих разделов).

Затем нам нужно создать CSS Sprites. Более подробно они уже были описаны в "Уменьшение количества запросов" . Идея заключается в том, чтобы группировать такие изображения по оси повторения. Например, все изображения, повторяющиеся по вертикали, сложить в vbackground.png, а все повторяющиеся по горизонтали — в hbackground.png. Затем можно использовать background-position: -OffsetPixeLs 0 для позиционирования внутри вертикального файла и background-position: 0 -OffsetPixeLs — для горизонтального.

8.1.2. Используем CDN (Content Delivery Networks)

Сети доставки содержания (англ. CDN, Content Delivery Network) стоят довольно дорого. Но можно поступить проще и использовать для этого GoogLe (подробнее рассказывается в "Технологии будущего" ). Естественно, придется немного попотеть, прежде чем собрать из GoogLe App Engine свою идеальную CDN.

Можно также применить msbuild для изменения файлов стилей при использовании CDN. Ниже приведен рабочий пример (в нем пути с ../images/ заменяются на http://karpach.appspot.com/cdn/images/):

<Import Project=".\References\MSBuild.Community.Tasks.targets" />
<Target Name="Release">

  <FileUpdate Files="$(OutputPath)styles\basic.css" Regex="\.\.\/images/(["\)]*)" ReplacementText= 
  "http:=""//karpach.appspot.com/cdn/images/$1" />
</Target>

Теперь нужно положить в CDN все ваши изображения, файлы стилей и скриптов. Здесь как раз и всплывает проблема сброса кэша. Что будет, если пользователь зашел к вам на сайт как раз перед тем, как вы выложили новую версию, в которой изменился файл стилей и некоторые изобра- жения? По-видимому, этот пользователь будет видеть сайт со старыми стилями и картинками еще 7 дней, и он просто не обнаружит изменений, пока не истечет срок действия кэша в его браузере. Это не есть хорошо. Если озвученный вопрос становится актуальным, то стоит посмотреть, что Yahoo! сделали на своем веб-сайте. В название картинки они "зашивают" метку даты и версию. Например, trough_2.0_062308.gif. Это выглядит разумно. Если вы изменяете какой-либо из ваших CSS Sprites, то его нужно вручную переименовать при помощи новой даты и версии (на самом деле процесс переименования файлов должен быть заложен в сам инструмент создания CSS Sprites; подробнее о сбросе кэша и объединении файлов было рассказано в "Уменьшение количества запросов" ).

Однако, по всей видимости, этот подход может быть неприменим для файлов стилей. Для начала стоит обеспечить контроль изменений версий таблиц стилей (в данном случае это SVN). Для картинок это не играет существенной роли, потому что они меняются не так часто. Основная идея заключается в том, что у нас может быть один физический файл (например, basic.css), а на странице используется адрес другого файла (например, basic_14102262.css), где 14102262 — это текущая версия приложения. Затем мы можем применить технологию url rewrite, так что basic_14102262.css будет указывать на basic.css. Пользователь с закэшированной версией basic_14102261.css будет вынужден загрузить новую версию basic_14102262.css, поскольку изменилось имя файла.

Движок Google Apps позволяет легко реализовывать rewrite для URL. Для этого можно просто изменить ваш app.yaml следующим образом:

- url: /cdn/styles/basic_\d*\.css
static_files: cdn/styles/basic.css
upload: cdn/styles/basic\.css

Более подробно о настройке CDN от Google рассказывалось в предыдущей лекции.

8.1.3. Добавляем заголовок Expires

У всех файлов, расположенных в CDN, уже выставлен этот заголовок. Для всех остальных можно создать следующий HttpModule:

private readonly static string[] CACHED_FILE_TYPES = new
string[] { ".jpg", ".gif", ".png",".css" };
public void Init(HttpApplication context)
{
  context.AcquireRequestState += new
EventHandler(context_AcquireRequestState);
}
void context_AcquireRequestState(object sender, EventArgs e)
{
    HttpContext context = HttpContext.Current;
    if (context != null && context.Response != null)
    {
    string fileExtension = Path.GetExtension
    (context.Request.PhysicalPath).ToLower();
    if (context.Response.Cache != null &&
    Array.BinarySearch<string>(CACHED_FILE_TYPES, fileExtension)
    >= 0)
    {
      HttpCachePolicy cache = context.Response.Cache;
      TimeSpan duration = TimeSpan.FromDays(365);
      cache.SetCacheability(HttpCacheability.Public);
      cache.SetExpires(DateTime.Now.Add(duration));
      cache.SetValidUntilExpires(true);
      cache.SetNoServerCaching();
      cache.SetMaxAge(duration);
    }
 }
}

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

8.1.4. Располагаем CSS-файлы в начале страницы

Это делается очень просто. Просто надо ввести эти действия в привычку. Помните об этом при разработке модулей на стороне сервера и используйте коллекцию Header.Controls для добавления таблиц стилей на страницу.

8.1.5. Располагаем JavaScript-файлы в конце страницы

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

Library.js

может содержать

function DoSomething()
{
}
А после этого прямо в коде страницы:
<script type='text/javascript'>
  if (typeof (DoSomething) == 'undefined')
  {
  alert('Library is not loaded yet');
  }
</script>

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

8.1.6. Уменьшаем число DNS-запросов

Для этого стоит скопировать внешние ресурсы (картинки, JavaScript файлы) к себе на сайт.

Например, на блоге располагается иконка валидной страницы от W3.Изначально эта иконка находилась на сайте W3 Schools, но для ускорения загрузки сайта стоит скопировать ее в свой проект. Тогда она будет располагаться локально, а при загрузке сайта понадобится на 1 DNS-запрос меньше.

8.1.7. Уменьшаем JavaScript

Минимизацию JS-кода можно осуществлять при публикации очередного выпуска сайта при помощи MS Build (это наиболее разумная позиция — осуществлять все оптимизационные процедуры при превращении сайта из тестового в рабочий). Для этой цели можно использовать YUI compressor. Ниже приведен вариант скрипта для MS Build.

<Target Name="Compress">
  <Message Text="Create temp files ..." />
  <Copy SourceFiles=".\$(ProjectName)\Javascript\ColorPicker.js"
  DestinationFiles=".\$(ProjectName)\Javascript\ColorPicker.js.full"/>
  <Copy SourceFiles=".\$(ProjectName)\Styles\ColorPicker.css"
  DestinationFiles=".\$(ProjectName)\Styles\ColorPicker.css.full"/>
  <Exec Command="java -jar yuicompressor-2.4.2.jar —type js
  .\$(ProjectName)\Javascript\ColorPicker.js.full
  >.\$(ProjectName)\Javascript\ColorPicker.js"/>
  <Exec Command="java -jar yuicompressor-2.4.2.jar —type css
  .\$(ProjectName)\Styles\ColorPicker.css.full
>.\$(ProjectName)\Styles\ColorPicker.css"/>
</Target>

8.1.8. Удаляем дублирующиеся скрипты

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

8.1.9. Настройте ETag

Кэширующий модуль и CDN должны решить эту проблему. Но стоит также иметь в виду, что в ASP .NET есть специальный метод для ETag:

Response.Cache.SetETag
< Лекция 8 || Лекция 9: 12345678
Сергей Крупко
Сергей Крупко

Добрый день.

Я сейчас прохожу курс  повышения квалификации  - "Профессиональное веб-программирование". Мне нужно получить диплом по этому курсу. Я так полагаю нужно его оплатить чтобы получить диплом о повышении квалификации. Как мне оплатить этот курс?

 

Галина Башкирова
Галина Башкирова

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

Системный администратор информационно-коммуникационных» систем.
Мне нужно самой найти тему? или делать по высланным темам

 

Александр Юдичев
Александр Юдичев
Россия
Даниил Климович
Даниил Климович
Беларусь, Гомель