Подлипенский Павел

Блог о технологиях и деньгах

Что нового в JQuery 1.3

clock декабря 24, 2008 09:15 by author Подлипенский Павел

Недавно John Resig писал в блоге о релизе бета-версии JQuery 1.3. Большинство новых фич опубликованы в официальном roadmap, но я вам расскажу то, о чем никто не знает.. Тсссс...

Sizzle Selector Engine

Новый движок для навигации по ДОМу, который Джон аннонсировал еще в августе, должен работать в четыре раза быстрее под Firefox. (А как же Internet Explorer?)

Забиваем на определение версии браузера

Теперь вместо

if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) { 

будем писать

if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) { 

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

Live event delegration

Всем известно как добавлять обработчики событий к элементам с помощью JQuery:

$("#foo > div").bind("click", someFn);

Также все помнят, что после добавления нового элемента div в контейнер с id=”foo” необходимо заново забайндить это событие. С новым релизом JQuery мы сможем воспользоваться методом live, который добавит обработчик событий всем элементам, даже тем, которые будут добавлены позднее.

$("#foo > div").live("click", someFn);

Event triggering

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

Улучшение производительности эффектов

Не буду вдаваться в подробности, но методы append(), prepend(), before(), after(), hide() и show() теперь могут работать быстрее (раз эдак в 15!).

Клозет-метод

Метод оправдывает свое название и находит ближайший туалет элемент соответствующий условию.

//Найти ближайший div. Если this и есть div-элемент, то вернет this.
$(this).closest("div"); 

И в заключение предоставлю скриншоты результатов теста на производительность различных фреймворков (MooTools, Prototype, YUI, JQuery) под разные браузеры (IE, Opera, FireFox, Chrome):

Chrome IE 7 Opera FireFox
chrome ie7 opera firefox

Верить им или нет – решайте сами.

Полезные ссылки

Speed/validity selectors test for frameworks

Help Test jQuery 1.3 Beta 1

Текущий рейтинг: 5.0 (4 голосов)

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Быстрые веб-страницы: оптимизируем JQuery

clock ноября 24, 2008 09:20 by author Подлипенский Павел

Начнем с того, что фреймворк JQuery очень быстрая штука. Да, конечно найдутся такие, кто скажет: "Короче, начал юзать джэйквери и у меня все повисло. Ну, я типа решил, что надо писать все самому...". Что ж, идиотов всегда хватало и мы не будем их переубеждать. Тем не менее, существуют некоторые практики и советы по использованию этого мощного (в руках homosapiens) инструмента.

Используйте ID, вместо классов для выборки элемента. Если у вас большой дом(не путать с дорогущим сооружением по соседству), то выборка $(.one-element') приведет к просмотру всего дерева для поиска этого элемента. Помогите ему и себе, предоставьте как можно больше информации о месторасположении объекта: ('.block1 > .block2 > .block3 …), укажите стартовую точку для поиска $('.foo', startObject) или используйте выборку по айдишнику $('#block45').

Читайте подробнее и на английском:

http://www.learningjquery.com/2006/12/quick-tip-optimizing-dom-traversal

http://blog.multitweet.com/2007/09/13/jquery-performance/

http://www.componenthouse.com/article-19

https://www.adaptavist.com/display/%7Egfraser/2008/01/12/Some+quick+tips+for+jQuery+performance

Иногда filter работает быстрее, чем find.

Читайте подробнее и на английском:

http://groups.google.com/group/jquery-en/browse_thread/thread/533451087251c952/9bb31c108c089c4f

http://www.learningjquery.com/2006/12/how-to-get-anything-you-want-part-2

Естественно это зависит от браузера, но объединение нескольких строк в одну таким способом: string1 = string2 + string3 может работать медленнее, чем если бы вы создали массив строк, а затем сделали join. В редких случаях имеет смысл использовать и третье решение - конкатенацию строк.

js-compare

Читайте подробнее и на английском:

http://www.nabble.com/document.write-and-DOm-creation---performance-optimization--td18390436s27240.html

http://www.sitepen.com/blog/2008/06/09/string-performance-getting-good-performance-from-internet-explorer/

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

Недавно открыл для себя, что iterators в джаваскрипте работают медленее, чем generators при больших объемах данных. Будьте бдительны, товарищи!

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

   1: var myCachedObjects = $(".find-me");
   2: var anotherObjects = myCachedObjects.filter(".another-object");
   3: var favouriteObjects = myCachedObjects.filter(".favourite-object");

Ухх, за эти выходные мое javascript-мировоззрение перевернулось: xml парсится в четыре раза медленнее, чем json, if(isTrue) работает быстрее, чем if(isTrue == true) и многое другое. Не хочу превращать этот пост в энциклопедию, поэтому добро пожаловать в полезные ссылки.

Полезные ссылки

jQuery: Performance analysis of selectors

IE + JavaScript Performance Recommendations

Evaluate Low Level JavaScript Performance Characteristics

Some more JavaScript performance tips

Текущий рейтинг: 4.8 (6 голосов)

  • Currently 4,833333/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Динамическое добавление ASP.NET пользовательского контрола с использованием JQuery

clock сентября 9, 2008 09:58 by author Подлипенский Павел

Недавно у меня возникла необходимость динамически подгружать пользовательские контролы на страницу. Это довольно просто реализовывается с помощью UpdatePanel. Но мне этот вариант не подошел, так как страница должна весить как можно меньше и работать как можно быстрее. Поэтому выбор пал именно на связку ASP.NET и JQuery + Web Service. Для начала давайте разберемся каким образом можно вызвать Web Method с помощью JQuery.

function getJsonAjaxObject(webServiceURL, jsonData) {
 $.ajax({
  type: "POST",
  contentType: "application/json; charset=utf-8",
  url: serviceURL,
  data: jsonData,
  success:
   function(msg){
   //код обработки успешного вызова веб-метода
   },
  error:
   function(XMLHttpRequest, textStatus, errorThrown){
    //код обработки ошибки выполнения веб-метода
   }
 });
}

Из всего множества методов (load, get, post, getJSON, ajax) я выбрал именно ajax т.к. этот метод позволяет наиболее полно контролировать процесс создания асинхронного запроса к веб-сервису.

Имя Тип Описание параметра
type string возможные варианты – GET или POST. Если параметр упущен, то по умолчанию будет использоваться метод GET. Типы запроса PUT или DELETE тоже могут быть использованы, но они поддерживаются не всеми браузерами.
contentType string при передаче данных серверу сообщает content-type. По умолчанию - application/x-www-form-urlencoded.
url string адрес веб-сервиса. Например, http://mysite.com/myservice.asmx/mywebmethod
data object данные, передаваемые на сервер. Добавляются в URL GET-запроса. Если используется объект, он должен представлять собой пары ключ/значение. Если значения представлены в виде массива, jQuery сериализует значения с некоторым ключом. Например: {foo:["bar1", "bar2"]} будет представлено как "&foo=bar1&foo=bar2".
success function указывается функция, которая будет вызвана в случае успешного завершения запроса. Функция принимает два аргумента: данные, возвращенные с сервера и отформатированные с учетом параметра dataType и строка, описывающая статус ответа(в нашем примере это строка всегда будет “success”).
error function определяет функцию, которая будет вызвана в случае неуспешного выполнения запроса.
dataType string строка, описывает тип данных, которые ожидаются в качестве ответа сервера. Если не определена, то jQuery сам попытается определить тип, основываясь на MIME-типе ответа сервера. Доступные типы: - xml: вернет XML документ, который может быть обработан через jQuery. - html: вернет HTML как plain text. - script: расценивает ответ как JavaScript и возвращает его как plain text. - json: расценивает ответ как данные в формате JSON и возвращает JavaScript объект. - jsonp: загружает данные в формате JSON используя JSONP. Необходимо дополнительно добавить "?callback=?" в конец строки запроса в URL, чтобы определить вызов. (Добавлено в jQuery 1.2). - text: строка plain text.
async boolean
по умолчанию все запросы выполняются в асинхронном режиме (значение true). Если необходимо выполнить синхронный запрос, следует установить значение false для этой опции. Помните, что синхронный запрос может временно заблокировать браузер, запретив любые действия во время выполнения запроса.
beforeSend function
может содержать функцию, которая должна быть вызвана до передачи запроса. beforeSend - это Ajax Event (события рассмотрены в другой статье).
cache boolean
опция добавлена в jQuery 1.2. По умолчанию - true. Если установить в false, запрашиваемая страница не будет кэшироваться браузером.
complete function
определяет функцию, которая будет вызвана по окончанию запроса (успешного и ошибочного выполнения). Принимает два аргумента: объект XMLHttpRequest и строку, описывающую "успешность" запроса. complete - это Ajax Event (события рассмотрены в другой статье).
global boolean
true или false. Вызывать или нет глобальные обработчики событий Ajax для этого запроса. Может быть использована для контроля различных Ajax событий. По умолчанию - true.
ifModified boolean
запрос будет успешным только в случае, если данные ответа изменились со времени последнего запроса. По умолчанию - false.
processData boolean
по умолчанию true. В опции data данные представлены в виде объекта, который преобразуется в строку запроса, подходящую для content-type по умолчанию - "application/x-www-form-urlencoded". Если необходимо иное, установите опцию processData в false.
timeout number
устанавливает локальный тайм-аут для запроса в миллисекундах. Отменяет глобальный тайм-аут для этого запроса, если тот определен через $.ajaxSetup


Необходимо также учесть, что ASP.NET Ajax enabled веб-сервис разрешает только HTTP POST (по умолчанию) для вызова метода, который возвращает JSON.

В большинстве случаев IIS 6 и выше требует наличия content-length элемента в запросе POST, даже если данных в запросе нет. Content-length для запроса без данных должен быть равен 0, но JQuery, в таком случае, этот элемент не добавляет. Поэтому для readonly запросов POST необходимо указывать пустой JSON объект:

data: “{}”

Это натолкнет JQuery на мысль указать корректный content-length и ваш веб-сервис сможет правильно распознать readonly-запрос, отбросив при этом пустой параметр.

Хочу еще обратить ваше внимание на то, что contentType установлен в "application/json;charset=utf-8". Этого требует ASP.NET AJAX. JSON-запросы, не имеющие подобного заголовка будут проигнорированы ASP.NET.

Еще одна проблема, с которой мне пришлось столкнуться, это “Maximum length exceed” ошибка. Она возникает в случае, когда длина JSON-ответа превышает длину по умолчанию. Во избежание этой ошибки необходимо добавить в web.config следующее:

<system.web.extensions>
  <scripting>
     <webServices>
    <jsonSerialization maxJsonLength="5000000" />
     </webServices>
  </scripting>
</system.web.extensions>

Вот так выглядит код моей страницы

<%@ Page Language="C#" EnableViewState="false"  %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="head" runat="server">
    <title>Add ASP.NET User Control dynamically with JQuery</title>
    <script language="javascript" type="text/javascript"   src="Scripts/jquery-1.2.6.pack.js"></script>
    <style type="text/css">
        body
        {
            width:95%;
            padding-left:20px;
            font-family:Arial;
            font-size:10pt;
            padding-right:20px;
        }
    </style>
</head>
<body>
    <form id="form" runat="server">
        <input type="button" value="Load GridView" onclick="getData('ScriptService.asmx/GetControlHtml','~/Controls/GridView.ascx');" />
        <input type="button" value="Load Login Control" onclick="getData('ScriptService.asmx/GetControlHtml','~/Controls/LoginControl.ascx');" />
 <div id="testDiv"></div>
    </form>
<script type="text/javascript">
…     
</script>
</body>
</html>

JavaScript для вызова веб-метода и динамического добавления пользовательского контрола на страницу

function getData(serviceURL, controlLocation) {
 $.ajax({
  type: "POST",
  contentType: "application/json; charset=utf-8",
  dataType: "json",
  url: serviceURL,
  data: "{'controlLocation':'" + controlLocation + "'}",
  success:
   function(msg){
     $('#testDiv').html(msg.d);
   },
  error:
   function(XMLHttpRequest, textStatus, errorThrown){
       alert( "Error Occured!" );
   }
 });
}

Для товарищей, малознакомых с JQuery (к коим отношусь пока и я), хочу объяснить следующую строку javascript-кода

$('#testDiv').html(msg.d);

Собственно в этой строке и происходит все чудо, а именно нам возвращается некий JSON-объект (msg), содержащий в себе строку. Часть строки $(‘#testDiv’) вернет нам набор объектов с id=’testDiv’ (в нашем случае это будет один div), далее мы вызываем метод html, который превратит нашу строку в дерево объектов и поместит его в коллекцию дочерних элементов нашего div’a. Эту операцию можно было записать несколько иначе:

$("#someElement")[0].innerHTML = msg.d;

Возможно, такая запись для кого-то будет понятней.

Данный пример доступен для скачивания. Исходные коды на C#.

Текущий рейтинг: 5.0 (5 голосов)

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Search


LinkedIn Profile

Tags

Posts

  • Интересно бы почитать сравнение с jsUnit
    vasyas

  • Ну, если вы посмотрели и выяснили, что bottleneck в строго определенном месте и это место - доступ к данным, тогда оптимизацией этого места и стоит заняться.
    Merle

  • Улыбнуло :-) Особенно на фоне тех шестилитровых пикапов, на которых эти "экономные" амеры любят ездить.
    Vitalii Tsybulnyk

  • Да, Виталик, ты прав - проблема в извлечении данных. Но тут врядли что-то получиться исправить, скорее придумать иной способ извлечения данных. Мы сейчас думаем над использованием базы данных, возможно встроенной или попробовать заюзать xslt для формирования html файлов. Саша, страница слава богу не популярная и пользуются ей 2-3 человека. А dotTrace смотрели, но ничего нового не увидели - страница слишком проста, чтобы там затерятся 3333-ем поползновениям к источнику данных.
    Подлипенский Павел

  • Да, Паш, именно это и смутило :) Если у вас на одном пользователе такая загрузка, то что будет, если эту страницу откроют 2, 5, 10 пользователей? Возможно, это не самая популярная страница, но что-то мне подсказывает, что такая ситуация потенциально возможна. Это же веб. Если вы еще не пробовали запускать dotTrace, то я вам настоятельно рекомендую это сделать. Я у нас на проекте уже раз пять оптимизировал отдельные страницы приложения и один раз - все приложение в целом. Садился, записывал, разбирался. Как правило, оказывало, что у нас то алгоритм неоптимальный, то локального кеширования где-то нет и вместо этого мы 3333 раза лезем в базу вместо одного, то идет дублирование вызовов. И все это лечится за 5-10 минут, а прирост производительности в определенных ситуациях может достичь двух порядков.
    Merle

  • Думаю, как раз это смутило не только нас, но судя по ночному звонку, заказчика тоже... Если удалось успокоить его 10% ослаблением нагрузки - вероятно это не надолго и стоит воспользоваться передышкой и ускорить процедуру извлечения (обработки) данных, если проблема всё же в ней...
    Vitalii Tsybulnyk

Categories

Calendar

<<  Январь 2009  >>
воповтсрчепясу
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567

Archive

© Copyright 2009

Sign in

Ó÷àñòíèê ïëàíåòû Developers.org.ua

Bookmark and Share

Web Developement Blogs - Blog Catalog Blog Directory