Как оптимизировать веб-приложение против задержки из-за множественных асинхронных запросов в фоновом режиме? - PullRequest
6 голосов
/ 24 июня 2011

Я занимаюсь разработкой модульной RIA на основе тонкой серверной клиентской архитектуры MVC. Прямо сейчас, Заявка заполнена только на 10%, и поэтому еще не поздно включить изменения в дизайн.

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

Однако, что меня беспокоит, так это то, возможно ли, что многозадачные запросы ajax, работающие с данными, работающие в фоновом режиме, останавливают работу браузера? Недавно я наблюдал некоторые серьезные проблемы с задержкой в ​​некоторых службах агрегации социального контента, и после анализа кода на стороне клиента я был удивлен, что площадь приложения на стороне клиента была довольно маленькой, в пределах 300 КБ. Однако при запуске приложения браузер (как Firefox, так и IE) очень часто зависал, и для его восстановления требовалось несколько секунд. После анализа асинхронных запросов выяснилось, что приложение одновременно извлекало пользовательский контент из gmail, facebook и twitter и помещало его в DOM и занимало слишком много ресурсов памяти.

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

Любой совет будет высоко оценен.

Ответы [ 2 ]

2 голосов
/ 14 июля 2011

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

Это можно сделать с помощью ESIGates .Один из них - Varnish-Esi , но он не охватывает всю спецификацию ESI . Этот (esigate.org) также с открытым исходным кодом и, возможно, с лучшим охватом (еще не тестировался).Система ESI означает, что макет вашего приложения может представлять собой комбинацию различных блоков с разной политикой кэширования (TTL) и разных поставщиков.Сервер ESI будет принимать часть трафика, который вы первоначально депортировали в конечный браузер, так что этот будет стоить вам намного больше пропускной способности , но, по крайней мере, вы получите больший контроль в этом программном обеспечении, а не в других браузерах, используемых клиентами HTTP.

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

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

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

Таким образом, содержание социальных сетей и других веб-служб задерживается и цепочками вместо большой параллельной нагрузки не должно быть проблем.Может быть, его не будет в первые 15 секунд, но если он останется на странице в течение следующих 15 минут, то это, возможно, не проблема (если самый важный контент уже есть, пользователь может даже не заметить, что декоративный контентбыл недоступен).Один совет по IE6 (а иногда и по IE7), используйте команды SetTimeouts() js везде, чтобы принудительно перерисовывать страницы, вы увидите, что доступный контент отображается быстрее.

Последний совет, если вам нужно сделать какой-то обычный ajaxпроверяет наличие обновленного контента.Если вы действительно проверяете эти данные для 10 контентов каждую минуту, у вас всегда будут проблемы с параллельной загрузкой и большая активность, та же проблема, что и при начальной загрузке, обычно вы можете использовать две вещи для решения этой проблемы, одна из них - COMET семейные долгосрочные HTTP-соединения (так что вы можете вместо этого PUSH-данные и / или получать более быстрые ответы, но только с вашим сервером, настроенным для такого рода HTTP-трафика).Второй добавляет фактор времени для следующих проверок, так что первая проверка выполняется через 1 минуту, следующая - через 2 минуты, затем через 3, 15, 25 и т. Д., В конце вы получаете новыйпроверять только каждый час возможно.И вы можете уменьшить задержку следующей проверки, когда обнаружите некоторую активность пользователя (некоторое взаимодействие с пользователем).Это потому, что вы можете предположить, что пользователь действительно ищет свежие данные только тогда, когда он действительно что-то делает с вашей страницей.Вы сэкономите некоторый пользовательский ЦП, а также поможете загрузить свой сервер.

0 голосов
/ 24 июня 2011

У меня также была задержка загрузки страницы из-за плагинов Facebook / LinkedId / etc.

Решением для меня является асинхронная загрузка стороннего JavaScript. Он работает не для всех веб-сервисов / виджетов, а для многих из них (кнопка «Мне нравится» в Facebook, кнопка «Твиттер» в Twitter и т. Д.).

Пример:

<div id="tweet">
    <a href="http://twitter.com/share" 
        class="twitter-share-button" 
        data-count="horizontal"
    >Tweet</a>
</div>
<script type="text/javascript">
    $(function() {
        $.getScript('http://platform.twitter.com/widgets.js');
    });
</script>

Этот код отобразит кнопку "Tweet" после загрузки страницы (DOM).

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

...