ASP.NET: законная проблема с архитектурой/HttpModule?

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

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

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

Есть смысл?

Мое беспокойство связано с модулем, который переписывает поток ответа страницы ASPX/HTML. Он просто применит кучу Regex.Replace() к атрибутам "src" тегов <script> и <img> и к атрибуту "href" тегов <link>. Это будет происходить для каждого отдельного запроса на сервере с типом содержимого "text/html". Потенциально сотни или тысячи в минуту.

Я понимаю, что HttpModules подключены к конвейеру IIS, но это должно добавить непомерную задержку времени, необходимого IIS для отправки HTTP-ответов. Нет? Что вы думаете?


person JamesBrownIsDead    schedule 18.11.2009    source источник
comment
Я думаю, что алгоритмы были бы такими же, если бы вы делали это в процессе сборки (на самом деле процесс публикации был бы лучше), единственная разница в том, что вы просто выполняете операции один раз, а не при каждом запросе.   -  person Josh Pearce    schedule 18.11.2009


Ответы (3)


Несколько вещей, о которых следует знать:

  1. Если идея состоит в том, чтобы добавить строку запроса к именам статических файлов, чтобы указать их версию, к сожалению, это также предотвратит кэширование драйвером HTTP режима ядра (http.sys).
  2. Сканирование каждого полного ответа на основе набора регулярных выражений будет медленным, медленным, медленным. Это также может быть ненадежным, с трудно предсказуемыми краевыми случаями.

Несколько альтернатив:

  1. Используйте адаптеры управления для явной замены определенных URL-адресов или путей текущей версией. Это позволяет вам сосредоточиться именно на изображениях, CSS и т. д.
  2. Измените имена папок вместо имен файлов при версии статических файлов.
  3. Рассмотрите возможность использования скинов ASP.NET для централизации имен файлов. Это поможет упростить обслуживание.

Если это будет полезно, я расскажу об этом в своей книге (Ultra-Fast ASP.NET), включая примеры кода. .

person RickNZ    schedule 18.11.2009

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

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

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

Браузеры поддерживают только ограниченное количество одновременных подключений, открытых для определенного имени хоста в любой момент времени. например, IE6 выполнит только 6 подключений, чтобы сказать www.foo.net.

Если вы вызываете свои изображения, скажем, с images.foo.net, вы сразу получаете 6 новых подключений. Идея состоит в том, чтобы разделить разные типы контента на разные имена хостов (css.foo.net, scripts.foo.net, ajaxcalls.foo.net), чтобы убедиться, что браузер действительно работает от вашего имени.

person Adrian K    schedule 18.11.2009
comment
Трюк с разными именами хостов также можно найти в том же руководстве Yahoo! «Исключительная производительность», на которое ссылается оригинальный постер, к вашему сведению! - person Funka; 18.11.2009

http://code.google.com/p/talifun-web

StaticFileHandler — Обслуживайте статические файлы кэшируемым, возобновляемым способом. CrusherModule — Подавайте сжатые версии JS и CSS кэшируемым способом.

Вы не совсем получаете скорость кэширования в режиме ядра, но обслуживание из HttpRuntime.Cache имеет свои преимущества. Кэш режима ядра не может кэшировать частичные ответы, и у вас нет точного контроля над кешем. Самое важное, что нужно реализовать, — это согласованный заголовок etag и заголовок с истекающим сроком действия. Это повысит производительность вашего сайта больше, чем что-либо еще.

Уменьшение количества обслуживаемых файлов, вероятно, является одним из лучших способов повысить скорость вашего сайта. CrusherModule объединяет все css на вашем сайте в один файл и все js в другой файл.

Память дешевая, жесткие диски медленные, так что пользуйтесь!

person Taliesin    schedule 18.02.2010