Оптимизация долларовой либы за счет prototype
на самом деле это кросспост из vingrad'а, причем не я автор, но может кто-то захочет прокомментировать:
Один из минусов любой долларовой библиотеки -- это создание лишнего объекта на каждый юзаемый в коде нод. В браузерах поддерживающих prototype для Node мы могли бы просто расширить поведение html-элементов, но поскольку в мсие они растут их com-объектов, этот способ как-бы отпадает. Старая идея имитировать prototype через behavior: url(HTMLElement.htc) страдает непреодолимым недостатком -- чрезвычайно медленной работой на большом DOM. Способ, который хочу обсудить, имеет целью убрать создание лишнего объекта за счет расширения prototype в w3c браузерах, (но создания еще одной лишней функции-обертки в мсие). Собственно сама идея: (function () { var doc = document, css = doc.styleSheets, win = window, etc; var BucksObject = function (node) { // унифицированное свойство node для доступа к ноду this.node = node.constructor === String ? doc.getElementById(node) : node; }, bucksPrototype = { method : code, etc }; if(window.Node && Node.prototype) { // расширение Node для стандартных браузеров window.$ = function (node) { if( node.constructor === String ) { node = doc.getElementById(node) }; // унифицированное свойство node для доступа к ноду node.node = node; return node; }; expand(Node.prototype, bucksPrototype); // копирует только отсутствующие свойства } else { // создание объекта-обертки для браузеров без Node.prototype window.$ = function (argument) { return argument instanceof BucksObject ? argument : new BucksObject(argument) }; // создать обертки для всех методов for (var name in bucksPrototype) { bucksPrototype[name] = (function(method){ return function () { return method.apply(this.node, arguments) }})(bucksPrototype[name]); }; BucksObject.prototype = bucksPrototype; }; })() |
Цитата:
|
А что тут комментировать? Вполне очевидное допиливание модели, по которой работает, в частности, Prototype.js.
|
Цитата:
upd: я тут подумал, в общем, все это вообще печально может кончиться. |
$(…).method(function() { this.method ? // в IE здесь будет лежать ссылка на узел, без дополнительных методов обёртки, // когда в других браузерах методы будут доступны, не хорошо получается. }); |
Riim,
Цитата:
Octane, есть такое дело, надо просто иметь это ввиду. Основное желание: ускорить работу в w3c браузерах, пусть и за счет небольшого падения производительности в msie. |
Цитата:
|
Цитата:
|
Цитата:
{item: Element} мы можем однозначно определить, в контексте какого объекта вызывается метод, проверив это в любом браузере, то в данном варианте нужно помнить о особенности браузера, а ведь одной из задач фреймворка является обеспечение кросс-браузерности, а значит в некоторой степени освобождение программиста от каких-то дополнительных проверок. Конечно, можно написать в документации, чтобы всегда юзали $(this) для получения кастомных методов, но это почти убивает идею получения прямой ссылки на элемент. Цитата:
|
Octane, как я понимаю, проблема (учитывать что this не содержит расширенных методов) будет только у автора фреймворка, ведь стоит задача не имитировать prototype в msie, а несколько ускорить работу/уменьшить потребление памяти в остальных браузерах.
Цитата:
|
Цитата:
$(…).customMethod1(arg, function () { // Проверим, на что там у нас this ссылается if (this.customMethod2) { // Ага, есть такой метод, можно его дальше использовать. // Но в IE то этого метода нет, надо этот момент всегда в голове держать! } });А если будем передавать эту обертку в IE и вызывать callback в нужном контексте, чтобы были доступны кастомные методы, то доступ к узлу придется осуществлять через this.node, белиберда получается, в нативных метода просто this, в фреймворке $(…), $(…).node и this.node, а еще и просто this не в IE… попробуй разберись. Цитата:
|
Нда, Вы почти убедили меня :) Конечно, apply-методы с каллбеками не так уж и часто нужны и может можно будет обойтись без них. Надо будет посмотреть :)
|
Часовой пояс GMT +3, время: 15:42. |