Всем привет.
У нас тут намечается проект с жесткими требованиями по масштабируемости и производительности. Теорию этого дела я себе более-менее представляю, хочу обсудить с коллегами некоторые практические аспекты.
Итак, к делу.
Сайт состоит из большого количества страниц, значительную часть которых составляет тяжеловесная статическая навигация. Что неприятно — так это то, что части страниц все-таки динамические, что мешает правильному кэшированию (а именно оно в вебе ключ к производительности).
В связи с этим у меня возникает идея построить шаблон страницы примерно так:
+<IFRAME>-------------------------+
| верхняя навигация, логотип и пр.|
+</IFRAME>------------------------+
+<IFRAME>---+ Вот тут - динамичный
| левое меню| контент.
| |
| |
| |
| |
| |
| |
+</IFRAME>--+
+<IFRAME>-------------------------+
| Футер: копирайт, адми мыло и пр.|
+</IFRAME>------------------------+
Т.е. выкинуть всю статику нафиг в ифреймы. По идее, это очень сильно сократит объем основных страниц, и позволит максимально использовать кэш браузера и проксей.
Однако подобная техника, сколько мне известно, не очень распространена.
Теперь, собственно, вопросы:
— есть ли какие-либо контраргументы? (может быть, IFRAME плохо cross-browser compatible?)
— есть ли опыт применения?
— любые комментарии привествуются
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Теперь, собственно, вопросы: S>- есть ли какие-либо контраргументы? (может быть, IFRAME плохо cross-browser compatible?)
Новые версии браузеров его вполне понимают. А вот со старыми он действительно, плохо совместим.
Если вы делаете Интранет-систему, то пофиг, конечно. Иначе придется выписывать требования к браузерам. Навскидку не скажу.
S>- есть ли опыт применения?
Да, мы его широко применяем. В-основном, для двух различных целей:
1) Сделать часть страницы редактируемой без перезагрузки основной страницы. Например, страница представляет собой систему Master-Detail, и при переходе по Master-ссылкам в основной странице обновляется только "подвал" с редактируемыми деталями в IFRAME. Очень удобно также прятать туда всякие тяжеловесные контролы, которые бы тормозили основную загрузку — например, DevExpress ASPxGrid. Минусы — у IFrame проблемы с вертикальным ресайзом, приходится делать его либо фиксированной высоты, либо хитро верстать в таблицу, либо использовать скрипты для ресайза.
2) Сделать часть страницы динамической без перезагрузки. Например, вставить в контент таблицу с результатами поиска или Tree-контрол, который динамически достраивает ветку при клике на "плюсик". Здесь применяется невидимый IFRAME размерами 1x1 пиксел, в который по мере необходимости грузится адрес нужной .aspx с параметром и полученный InnerHTML вставляется в нужное место. Фактически, такой доморощенный запрос к серверу без перезагрузки.
У этого подхода тоже есть минусы (IFRAME гадит в историю браузера и т.д.). Но в целом работает. Сейчас бы я применил другой способ: XmlHTTP или динамический рендеринг тэга <SCRIPT src="page.aspx?param=blablabla">. Недавно в форуме Dotnet.Web, кажется, пролетала интереснейшая ссылка. Gollum подскажет.
[... skipped ...]
R>У этого подхода тоже есть минусы (IFRAME гадит в историю браузера и т.д.). Но в целом работает. Сейчас бы я применил другой способ: XmlHTTP или динамический рендеринг тэга <SCRIPT src="page.aspx?param=blablabla">. Недавно в форуме Dotnet.Web, кажется, пролетала интереснейшая ссылка. Gollum подскажет.
Здравствуйте, Oyster, Вы писали:
O>Здравствуйте, retalik, Вы писали:
O>[... skipped ...]
R>>У этого подхода тоже есть минусы (IFRAME гадит в историю браузера и т.д.). Но в целом работает. Сейчас бы я применил другой способ: XmlHTTP или динамический рендеринг тэга <SCRIPT src="page.aspx?param=blablabla">. Недавно в форуме Dotnet.Web, кажется, пролетала интереснейшая ссылка. Gollum подскажет.
O>Я не Gollum, но... Набла №41: JSHttpRequest: динамическая подкачка данных без перезагрузки страницы
Уникальность техники, описанной на той странице, в том, что не используется XMLHTTP и IFRAME для загрузки контента без post-back. Используется для этого тег <script> — на самом деле, описан достаточно остроумный и переносимый метод.
Здравствуйте, Oyster, Вы писали:
O>Уникальность техники, описанной на той странице, в том, что не используется XMLHTTP и IFRAME для загрузки контента без post-back. Используется для этого тег <script> — на самом деле, описан достаточно остроумный и переносимый метод.
Здравствуйте, mogadanez, Вы писали:
M>Здравствуйте, Oyster, Вы писали:
O>>Уникальность техники, описанной на той странице, в том, что не используется XMLHTTP и IFRAME для загрузки контента без post-back. Используется для этого тег <script> — на самом деле, описан достаточно остроумный и переносимый метод.
M>как появится посмотримс...
Идея в том, что в страничку динамически добавляется тег <script src="page.aspx?param1=value1&...">. Соответствующая page генерирует валидный JavaScript, в котором вызывается некая callback-функция клиента с параметрами респонса.
O>>[офф] O>>А не открывается страница, видимо, из-за того, что Москва частично сидит без электричества. O>>[/офф]
M>да..да.. а Питер тут причем
Цитата с той ссылки:
Почему не работают многие сайты
ММТС 9 осталась без электричества, как сообщили сотрудники станции корреспонденту NEWSru.com пока по неизвестных для них причинам. Поскольку через М9 проходит более 80% российского Интернет-трафика, и многие московские провайдеры устанавливают на М9 свое телекоммуникационное оборудование, большинство популярных Интернет-ресурсов будут недоступны, пока на станции не будут решены проблемы с электричеством.
Поэтому не работают многие проекты.
Также через М9 проходит большинство международных телекоммуникационных каналов, соединяющих Россию с миром, могут возникнуть проблемы с доступом из России к зарубежным Интернет-ресурсам и с международной телефонной связью.
Здравствуйте, mogadanez, Вы писали:
O>>[офф] O>>А не открывается страница, видимо, из-за того, что Москва частично сидит без электричества. O>>[/офф]
M>да..да.. а Питер тут причем
Спасибо, джентльмены. Но тут есть некоторая тонкость: я предполагаю использовать iframe как раз для статики, а не для динамики.
Сейчас я объясню почему.
Дело в том, что типичная страница современного сайта представляет собой этакий орешек, в котором очень толстая скорлупа статического контента обрамляет маахонькое зернышко динамического контента. Давайте рассмотрим клинический случай: у нас есть меню на 48 килобайт, всякие печки-рамочки, и унутре тока одна динамическая фишечка "текущее время сервера = 24.05.2005 17:00".
Итак, из всего текста страницы меняются ровно 16 байт. Поскольку они устаревают мгновенно, для корректного результата мы вынуждены выставлять страничке немедленный expiration. При нажатии F5 КПД равен, соответственно, 16/48000. Или примерно 0.03%. Маловато.
Что полезного мы можем сделать для нашей державы, т.е. сайта? Мы можем перенести текущее время сервера в маахонький iframe, задав ему отдельный src. Таким образом, мы развалили запрос на два. Первому, размером все в те же 48K, мы честно выставляем expiration в never, а второму, соответственно, в immediate. Теперь при нажатии F5 браузер не станет перезакачивать статику, что очень позитивно повлияет как на его эмоциональное состояние, так и на масштабируемость нашего сервера. Более того, при нажатии Ctrl+F5 сервер сможет обойтись отправкой 302 Not Modified, чтобы указать браузеру на его же кэш.
КПД = почти 100%.
Но надо сказать, что нам очень повезло с SRC этого внутреннего IFRAME. Потому, что он случайно оказался совершенно одинаковым для всех запросов.
Добавим толику интереса: пусть у нас теперь будут две странички. http://somesite.com/catalog/cars.coolsp и http://somesite.com/catalog/homes.coolsp
Эти странички отличаются только тем, что у одной в середине список из двух машынок, а у другой — список из двух домиков. Вокруг по прежнему 48к статики.
С точки зрения браузера, эти странички никак не связаны между собой. Поэтому ему придется делать отдельные запросы для их получения. КПД падает до 50%.
Если мы вынесем внутреннюю часть в IFRAME, то никакого результата не будет. Поскольку для браузера http://somesite.com/catalog/cars.coolsp и http://somesite.com/catalog/homes.coolsp — по прежнему разные документы. Равно как и http://somesite.com/catalog.coolsp?section=cars супротив http://somesite.com/catalog.coolsp?section=homes
Но фреймы суть великое зло, как минимум с точки зрения юзабилити. Поэтому хочется вместо них использовать IFRAME, чтобы создать впечатление полноценной страницы с плоской структурой.
Вот у меня и возникают вопросы относительно кроссбраузерной совместимости.
Облегчения:
— эти ифреймы скорее всего будут иметь фиксированные размеры
— эти ифреймы будут иметь статический SRC, никаких подгрузок контента с его последующим анализом [пока] не предполагается
З.Ы. еще один вопрос: а meta refresh ифреймы хорошо поддерживают? А то там есть одно место, где хочется сделать еще и автоматический релоад.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
M>>как появится посмотримс...
O>Идея в том, что в страничку динамически добавляется тег <script src="page.aspx?param1=value1&...">. Соответствующая page генерирует валидный JavaScript, в котором вызывается некая callback-функция клиента с параметрами респонса.
Я такой фигней пользуюсь, например, здесь для генерации контента страницы.
Главный плюс — то, что после перехода по всем страницам они кэшируются и в итоге открываются моментально (как минимум, в Файрфоксе)
И он же — главный минус. Иногда браузер даже не запрашивает, а не изменился ли контент...
И еще минус. Говорят, что такой способ приводит к утечкам памяти в эксплорере
... << RSDN@Home 1.1.4 beta 7 rev. 447>> ... <<Winamp is playing "Elvis vs Jxl — A LITTLE LESS CONVERSATION — elvis vs jxl">> ..
[... skipped ...]
M>И еще минус. Говорят, что такой способ приводит к утечкам памяти в эксплорере
Насколько я знаю, IE "течёт" только в случае циклических ссылок, в которых учавствуют как объекты DOM, так и объекты JS. Вроде как фишка в том, что для объектов DOM и JavaScript используются разные GC, и в случае такой циклической ссылки объекты, учавствующие в ней, никогда не собираются. Known bug ещё с IE 4.
M>>И еще минус. Говорят, что такой способ приводит к утечкам памяти в эксплорере
O>Насколько я знаю, IE "течёт" только в случае циклических ссылок, в которых учавствуют как объекты DOM, так и объекты JS. Вроде как фишка в том, что для объектов DOM и JavaScript используются разные GC, и в случае такой циклической ссылки объекты, учавствующие в ней, никогда не собираются. Known bug ещё с IE 4.
Хмм... У меня подгружающийся JS заполняет некий объект в JS, которому потом говорит "фас" и тот начинает манипулировать ДОМом. В общем, надо переползать на XHTTP
... << RSDN@Home 1.1.4 beta 7 rev. 447>> ... <<Winamp is playing "The Verve — Bitter Sweet Symphony">> ...
S>Вот у меня и возникают вопросы относительно кроссбраузерной совместимости. S>Облегчения: S>- эти ифреймы скорее всего будут иметь фиксированные размеры S>- эти ифреймы будут иметь статический SRC, никаких подгрузок контента с его последующим анализом [пока] не предполагается
IFrame работает сам по себе на всех браузерах, но событие OnReadyStateChange(или как то так) позволяющее отслеживать его состояние есть только в IE
если это не нужно
— то проблем быть не должно, все будет работать на всех браузерах.
есть опыт использования iframe для всяких динамических выпадающих диалогов(типа datePicker), причем сам iframe создается динамически — работает везде
если надо, то есть всякие ухищрения, дающие почти такой же результат.
S>З.Ы. еще один вопрос: а meta refresh ифреймы хорошо поддерживают? А то там есть одно место, где хочется сделать еще и автоматический релоад.
Да.
единственное что может стать немного сложнее — это скрипты, если они должны работать с разными фреймами.
Здравствуйте, Mamut, Вы писали:
M>>>И еще минус. Говорят, что такой способ приводит к утечкам памяти в эксплорере
O>>Насколько я знаю, IE "течёт" только в случае циклических ссылок, в которых учавствуют как объекты DOM, так и объекты JS. Вроде как фишка в том, что для объектов DOM и JavaScript используются разные GC, и в случае такой циклической ссылки объекты, учавствующие в ней, никогда не собираются. Known bug ещё с IE 4.
M>Хмм... У меня подгружающийся JS заполняет некий объект в JS, которому потом говорит "фас" и тот начинает манипулировать ДОМом. В общем, надо переползать на XHTTP
Одно дело манипулировать, и совсем другое — создавать cyclic reference. Если ты манипулируешь DOM-ом — это ок, но если ты, например, посадишь обработчик на onclick, который в своём теле ссылается на этот же элемент — тогда труба. Вот пример того, как делать memory leak в IE :
<html>
<head>
<script>
function create_div()
{
var x = document.createElement("div");
x.innerText = 123;
// Тут создаётся замыкание - функция содержит ссылку на x,
// x содержит ссылку на функцию - итого memory leak
x.onclick = function() { alert("Clicked!"); };
document.body.appendChild(x);
}
function create()
{
for (var i = 0; i < 1000; ++i) {
create_div();
}
}
</script>
</head>
<body onload="create()">
</body>
</html>
Здравствуйте, Sinclair, Вы писали:
S>Всем привет. S>У нас тут намечается проект с жесткими требованиями по масштабируемости и производительности. Теорию этого дела я себе более-менее представляю, хочу обсудить с коллегами некоторые практические аспекты. S>Итак, к делу.
S>Т.е. выкинуть всю статику нафиг в ифреймы. По идее, это очень сильно сократит объем основных страниц, и позволит максимально использовать кэш браузера и проксей.
Хм, мы поступили наоборот — выкинули в IFRAME-ы динамику. Т.е. вся навигация висит в главном окне, а кнутри него сидит IFrame такого вида:
fr_load() подгружает соджержимое первой страницы внутрь iframe. Все изменения, которые могут происходить в главной странице (например, поменять отображение названия раздела или любые другие параметры вне фрэйма), делаются JavaScript-ом, приходящим внутри фрэйма.
Вся навигация перенаправляется таргетами внутрь врэйма.
Кстати, указанная технология хорошо подходит для закрытой системы (не публичной), поскольку сложнее подставлять под поисковики и делать полную печать страницы средствами браузера. Зато всё летает.
S>Однако подобная техника, сколько мне известно, не очень распространена.
Не очень распространена на очень публичных сайтах. По причине вышеуказанной...
S>Теперь, собственно, вопросы: S>- есть ли какие-либо контраргументы? (может быть, IFRAME плохо cross-browser compatible?)
Ну, в общем да...
При использовании iframe как минимум можно получить разный view в разных браузерах (где есть скроллер, где нет...). Да и, частенько, необходимо достаточно активно взаимодействовать с этим фрэймом из других фрэймов и из родительской страницы, что требует очень аккуратного прописывания JavaScript для обеспечения кроссбраузерности.
S>- есть ли опыт применения?
Есть. У нас весь вебинтерфейс системы прописан на iframe.
S>- любые комментарии привествуются
Всё проще, если ограничить пользователя использованием только IE, например Если это возможно, конечно.
Ещё такая штука — если хорошо пишется на JavaScript, то можно в главную страницу (да и в нулевые iframe-ы) выносить как можно больше JavaScript-овкого кода, чтобы не грузить его по сетке каждый раз. Да и некоторое форматирование тоже можно вынести. Например, подгружается страница только с данными, а страница прорисовыватся уже на клиенте заранее подгруженным JavaScript-ом.
Здравствуйте, Sinclair, Вы писали:
S> При нажатии F5 КПД равен, соответственно, 16/48000.
А что, бизнес процесс работы с сайтом подразумевает постоянное нажатие пользователями F5?
S>З.Ы. еще один вопрос: а meta refresh ифреймы хорошо поддерживают? А то там есть одно место, где хочется сделать еще и автоматический релоад.
Без проблем. Но лучше делать скриптом.
Здравствуйте, Spidola, Вы писали:
S>А что, бизнес процесс работы с сайтом подразумевает постоянное нажатие пользователями F5?
В частности. А в целом будет очень большая нагрузка со стороны различных пользователей, а также относительно длинные пути навигации по сайту в процессе визита. S>>З.Ы. еще один вопрос: а meta refresh ифреймы хорошо поддерживают? А то там есть одно место, где хочется сделать еще и автоматический релоад. S>Без проблем. Но лучше делать скриптом.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Всем привет. S>У нас тут намечается проект с жесткими требованиями по масштабируемости и производительности. Теорию этого дела я себе более-менее представляю, хочу обсудить с коллегами некоторые практические аспекты. S>Итак, к делу. S>Сайт состоит из большого количества страниц, значительную часть которых составляет тяжеловесная статическая навигация.
[...] S>- любые комментарии привествуются
Ok, тогда так.
А что такое тяжеловесная статическая навигация. и почему она тяжеловесная.. К тому же если посмотреть на prior art, то что-то не припомню сайтов concerned with "масштабируемость и производительность" сделанных так.
Я не expert, просто пытаюсь использовать "engineering common sense".
Здравствуйте, Oyster, Вы писали:
O>Здравствуйте, Mamut, Вы писали:
M>>>>И еще минус. Говорят, что такой способ приводит к утечкам памяти в эксплорере
O>Одно дело манипулировать, и совсем другое — создавать cyclic reference. Если ты манипулируешь DOM-ом — это ок, но если ты, например, посадишь обработчик на onclick, который в своём теле ссылается на этот же элемент — тогда труба. Вот пример того, как делать memory leak в IE :
O>
O><html>
O><head>
O><script>
O>function create_div()
O>{
O> var x = document.createElement("div");
O> x.innerText = 123;
O> // Тут создаётся замыкание - функция содержит ссылку на x,
O> // x содержит ссылку на функцию - итого memory leak
O> x.onclick = function() { alert("Clicked!"); };
O> document.body.appendChild(x);
O>}
O>function create()
O>{
O> for (var i = 0; i < 1000; ++i) {
O> create_div();
O> }
O>}
O></script>
O></head>
O><body onload="create()">
O></body>
O></html>
O>
Глубоко прокопано!
Это проверенно на IE? или еще на других browsers? Вообще то по идее замыкание образовываться не должно — function() { alert("Clicked!"); } не использует никаких переменных из create_div — но я давно ECMA standard читал уже деталей не упомню. Вообще надо бы разобраться и в FAQ.