Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Идея сайта... Стоит двигацца дальше?! (https://javascript.ru/forum/project/3686-ideya-sajjta-stoit-dvigacca-dalshe.html)

x-yuri 18.07.2009 13:28

по поводу xml: http://bash.org.ru/quote/1989 :haha:

B~Vladi 21.07.2009 11:19

Значт так... Будем занимацо арифметикой;)

У нас есть JSON и XML&XSL. Рассмотрим ситуацию с моим сайтом. Контент и дополнительный функционал подгружается по запросу пользователя, а не всё в куче. Это логично, по-другому не придумаешь. Сюда значт входят:

XML
XSL
CSS (если надо, а надо практически всегда)
JS (если надо, а надо не всегда)

Дальше берём один раздел, к примеру "коды". Все страницы этого раздела используют 1 XSL, т.е. структура XML одинаковая, т.е. CSS нам нужен 1. Получается, что CSS и XSL мы в счёт брать не будем, т.к. они жестко закешируются при первом их запросе + для CSS запрос посылаться не будет. То же самое и с JS. При первом запросе закешируется, а потом даже запрашивать не будем. Идём дальше. При оптимизации структуры XML и XSL, получаемый XHTML будет на 10-30% тяжелее исходного XML. Выигрыш тут зависит от структуры XML и объёма создаваемой вёрстки (не считая обычной оптимизации в виде чистки мусора в коде). Считать мои килобайты пока рано, т.к. это не окончательный вариант, но уже что-то показывает... Погодите чуток). Получается, что при 2-3-4 и т.д. запросе контента этого раздела, мы устанавливает всего 1(!) соединение с сервером и экономим получаемый трафик на 10-30%. Для наглядности можно, конечно, это перевести в килобайты - кому надо - считайте. Если передавать это как JSON или обычный текст, мы наоборот будем терять эти проценты.

+ ко всему этому, сам XML тоже жёстко кешируется и при одинаковых запросах передаватся ничего не будет.

В случае же с JSON о преимуществах кэша можно забыть...

Вывод такой - использовать надо то, что актуально в каждом конкретном случае. JSON хорош там, где необходимо получить голые данные при одноразовых (индивидуальных) запросах. XML & XSL хороши там, где нужен именно контент (информация, а не данные). Такая связка даёт нам преимущества в виде кэша и уменьшение передаваемых байт. Это мой ответ на вопрос "одной личности" о том, почему же я это использую.

Хочу сделать последний акцент - именно XML & XSL, т.к. сам по себе XML только увеличивает объём из-за разметки и не подходит для "тупо данных".

ЗЫ: Если я что упустил/не учёл - пишите.

Solo 22.07.2009 19:24

Нормально. Думаю стоит. Присмотритесь к фреймворку Ext JS

B~Vladi 23.07.2009 12:18

Цитата:

Сообщение от Solo
Присмотритесь к фреймворку Ext JS

Спасибо, но этот сайт я делаю сам;)

x-yuri 23.07.2009 14:32

Цитата:

Сообщение от B~Vladi
Получается, что CSS и XSL мы в счёт брать не будем, т.к. они жестко закешируются при первом их запросе + для CSS запрос посылаться не будет.

что-то xsl у тебя постоянно запрашивается и не кэшируется

Цитата:

Сообщение от B~Vladi
При оптимизации структуры XML и XSL, получаемый XHTML будет на 10-30% тяжелее исходного XML

проценты это, конечно, круто, но пока что у тебя передается байт 200 в запросах (не нашел страницу с контентом). Пока что 30% это 200 -> 260. Офигительно сэкономили

Цитата:

Сообщение от B~Vladi
Если передавать это как JSON или обычный текст, мы наоборот будем терять эти проценты

теоретически да, на практике нужно считать. Например, при каком объеме с помощью xml можно будет устранить заметную задержку

Цитата:

Сообщение от B~Vladi
+ ко всему этому, сам XML тоже жёстко кешируется и при одинаковых запросах передаватся ничего не будет.

а JSON типа нет

Цитата:

Сообщение от B~Vladi
Это мой ответ на вопрос "одной личности" о том, почему же я это использую

я ж ничего плохого в виду не имел

Еще стоит вспомнить, что не все сайты ведут программисты. И обычные пользователи наверняка не будут создавать xml-файлы, а тем более xsl, и еще и оптимизировать их под траффик

Вывод:
+ может быть получиться сэкономить на трафике, пока непонятно насколько
- нужно разобраться как его использовать (xml, xsl), хотя преимущества пока не очевидны

B~Vladi 23.07.2009 15:44

Цитата:

Сообщение от x-yuri
что-то xsl у тебя постоянно запрашивается и не кэшируется

Пока не шлю заголовков принудительного кеширования.
Цитата:

Сообщение от x-yuri
Еще стоит вспомнить, что не все сайты ведут программисты. И обычные пользователи наверняка не будут создавать xml-файлы, а тем более xsl, и еще и оптимизировать их под траффик

Это всё понятно. Но в редких случаях такое возможно, если создавать только xml.
Цитата:

Сообщение от x-yuri
а JSON типа нет

По логике вещей не должен, т.к.
Цитата:

Сообщение от B~Vladi
JSON хорош там, где необходимо получить голые данные при одноразовых (индивидуальных) запросах.

Цитата:

Сообщение от x-yuri
нужно разобраться как его использовать

эээ... Кому нужно разобратся?! не понял...

x-yuri 23.07.2009 15:57

Цитата:

Сообщение от B~Vladi
По логике вещей не должен, т.к.

JSON хорош там, где необходимо получить голые данные при одноразовых (индивидуальных) запросах.

откуда такая информация? Откуда такая логика?

Цитата:

Сообщение от B~Vladi
эээ... Кому нужно разобратся?! не понял...

тем, кто его не знает

B~Vladi 23.07.2009 16:26

Цитата:

Сообщение от x-yuri
тем, кто его не знает

Можно написать интерфейс для таких...
Цитата:

Сообщение от x-yuri
откуда такая информация? Откуда такая логика?

Моя:thanks: А разве не так?

x-yuri 23.07.2009 16:39

какое отношение имеет "где хорош JSON" к его кэшированию? Причем то, что JSON хорош только для голых данных, а тем более при одноразовых_запросах, это еще доказать нужно

B~Vladi 23.07.2009 17:00

Цитата:

Сообщение от x-yuri
это еще доказать нужно

Да никому это не нужно... Все будут делать так, как считают нужным. XML&XSL имеют право на использование в сети и с этим не поспоришь. Вот и пробуем использовать... Выходит не совсем всё так плохо, чтобы отказываться от этого...

Riim 23.07.2009 17:06

21 страница, еще немного и можно в типографию нести :) .

Kolyaj 23.07.2009 17:07

Цитата:

Сообщение от Riim
21 страница

У кого 21, а у кого 6 :)

B~Vladi 23.07.2009 17:22

Цитата:

Сообщение от Riim
21 страница, еще немного и можно в типографию нести

:D
И наблюдать, как ты растёшь:blink:

B~Vladi 03.08.2009 17:11

Так, народ, какой функционал должен быть на странице новостей?! Сайт->Новости.

1. Чем вы обычно пользуетесь на простых сайтах в странице "новости" и пользуетесь ли вообще?
2. Можно текст новостей прятать, а при клике по заголовку показывать...
3. Стоит ли разбивать на страницы?! Добавляцо будет далеко не каждый день:)
4. Стоит ли делать выборку по дате?

Ну в таком духе кароч.

x-yuri 03.08.2009 17:27

1) лично я - ничем
2) можно, а можно и без этого. Это более актуально, если новостей будет много на странице. Альтернативный вариант, сделать список названий новостей (типа содержание), но это нестандартно, да и не нужно имхо все это
3) стоит, не важно как часто будут появляться. Или ты не будешь показывать старые новости? Тогда можно не делать
4) это как? Показывать новости только за последние N дней? Если так, то тебе виднее. Если думаешь, что пользователя старые новости интересовать не будут, тогда делай

B~Vladi 03.08.2009 17:43

Не хочется заваливать страницу всеми новостями и оставить возможность просмотреть всю историю изменений...

Цитата:

Сообщение от x-yuri
лично я - ничем

Я тоже... вот и думаю зачем она вообще?! Хотя нада...
Цитата:

Сообщение от x-yuri
можно, а можно и без этого.

Думаю да... лишнее уже...
Цитата:

Сообщение от x-yuri
стоит, не важно как часто будут появляться

Тогда, кроме самих страниц что ещё нужно?! Кол-во показов?
Цитата:

Сообщение от x-yuri
Показывать новости только за последние N дней?

Вроде как да... понятное дело что никто заморачиваться не будет...

B~Vladi 03.08.2009 17:48

И ещё... в настройках сайта думаю сделать такие параметры:

1. Оптимизировать прорисовку (для слабых машин и браузеров)
2. Сохранить активное окно
3. Отключить скрипты
Тут нада ещё добавить чего нибудь...

И две кнопки:
1. Применить (применяется только для текущей сессии)
2. Сохранить (действует для всех сессий)

B~Vladi 06.10.2009 13:24

Написал свой Event для сайта.
Перепробовал кучу вариантов и остановился на идее библиотеки от Ильи Кантора, но с некоторыми отличиями.
Вот, собственно код:
var Event=(function(){
	var allList=new Array;
	var errors=new Array;
	var handler=function(evt){
		evt.errors=new Array;
		if(!evt.fix){
			evt.errors=new Array;
			if(!evt)evt=event;
			if(!evt.preventDefault)evt.preventDefault=function(){evt.returnValue=false;}
			if(!evt.stopPropagation)evt.stopPropagation=function(){evt.cancelBubble=true;}
			if(!evt.target)evt.target=(evt.srcElement.nodeType==1)?evt.srcElement:evt.srcElement.parentNode;
			if(!evt.relatedTarget&&evt.fromElement)evt.relatedTarget=(evt.fromElement==evt.target)?evt.toElement:evt.fromElement;
			if(evt.pageX==null&&evt.clientX!=null){
				var html=document.documentElement,body=document.body;
				evt.pageX=evt.clientX+(html&&html.scrollLeft||body&&body.scrollLeft||0)-(html.clientLeft||0);
				evt.pageY=evt.clientY+(html&&html.scrollTop||body&&body.scrollTop||0)-(html.clientTop||0);
			}
			if(!evt.which&&evt.button)evt.which=(evt.button&1?1:(evt.button&2?3:(evt.button&4?2:0)));
			evt.fix=true;
		}
		var ele=this.ele||this;
		for(var i=0;i<allList.length;i++){
			if(allList[i].ele==ele){
				for(var s=0;allList[i]&&allList[i].list[evt.type]&&s<allList[i].list[evt.type].length;s++){
					if(allList[i].list[evt.type][s]){
						var objCall=allList[i].list[evt.type][s];
						try{
							if((objCall.handler||objCall).call(this,evt)===false){
								evt.stopPropagation();
								evt.preventDefault();
							}
							if(evt.stopCall===true)break;
						}catch(e){
							errors.push(e);
							if(!objCall.onerror)break;
							if(objCall.onerror.call(evt,e)===false)break;
						}
					}
				}
				if(Event.debug&&errors.length)Event.debug(errors);
				delete errors;
				return;
			}
		}
	}
	return{
		Add:function(obj,type,call){
			var ele=obj.ele||obj;
			if(ele.setInterval&&(ele!=window&&!ele.frameElement))ele=window;
			for(var i=0;i<allList.length;i++){
				if(allList[i]&&allList[i].ele==ele){
					if(!allList[i].list[type]){
						allList[i].list[type]=[call];
						if(ele.addEventListener)ele.addEventListener(type,allList[i].handler,false);
						else if(ele.attachEvent)ele.attachEvent('on'+type,allList[i].handler);
						return;
					}
					for(var c=0;c<allList[i].list[type].length;c++)if(allList[i].list[type][c]==call)return;
					allList[i].list[type].push(call);
					return;
				}
			}
			var objListener={ele:ele,handler:function(evt){handler.call(obj,evt)}};
			objListener.list=new Object;
			objListener.list[type]=[call];
			allList.push(objListener);
			if(ele.addEventListener)ele.addEventListener(type,objListener.handler,false);
			else if(ele.attachEvent)ele.attachEvent('on'+type,objListener.handler);
		},
		Del:function(ele,type,call){
			for(var i=0;i<allList.length;i++){
				if(allList[i].ele==ele){
					if(type&&call){
						for(var s=0;s<allList[i].list[type].length;s++){
							var objCaller=allList[i].list[type][s];
							if(objCaller&&(objCaller.handler||objCaller)==(call.handler||call)){
								delete allList[i].list[type][s];
								return;
							}
						}
					}else if(type){
						ele['on'+type]=null;
						delete allList[i].list[type];
					}else{
						for(var type in allList[i].list){
							if(ele.removeEventListener)ele.removeEventListener(type,allList[i].handler,false);
							else if(ele.detachEvent)ele.detachEvent('on'+type,allList[i].handler);
						}
						delete allList[i];
					}
					return;
				}
			}
		},
		Init:function(ele,type){
			if(document.createEvent&&ele.dispatchEvent){
				var evt=document.createEvent('HTMLEvents');
				evt.initEvent(type,true,true);
				ele.dispatchEvent(evt);
			}else ele.fireEvent('on'+type,event);
		}
	}
})();


Схематическая структура массива allList:

[{
  ele: DOMelement,
  handler: listener,
  list: [fnc1,fnc3,fnc2,...]
},
...
]

Отличия от библиотеки Ильи:

* Все присоединённые обработчики хранятся в приватном массиве allList, не засоряя тем самым DOM-узлы.

* Добавлен метод Init для кроссбраузерной генерации события. Предпологается доработка.

* Возможность вызывать обработчик в контексте любого объекта.

Ну и так... по-мелочи:)

Вобщем, использовать так:
Event.Add(ele,type,fnc);

ele - DOM-узел, либо объект, имеющий свойство ele, которое возвращает DOM-элемент. Обработчик будет вызван в контексте этого объекта. Таким образом, можно передавать произвольные параметры в обработчик, что иногда бывает очень удобно, например:
Event.Add({ele:ele,data1:'value1',data2:'value2'},type,fnc);

type - тип события.
fnc - обработчик.

Удалять так
Event.Del(ele,type?,fnc?);

ele - DOM-узел, которому необходимо удалить обработчик.
type - тип события. Необязательно.
fnc - обработчик. Необязательно.

Если указан тип и обработчик - из указанного узла удалится только этот обработчик.
Если обработчик не указан - из элемента удалятся все обработчики указанного типа.
Если указан только элемент - удаляются все обработчики.

Так же реализованы "мини-фичи", упоминаемые в статье:

* Если в обработчике объекту event установить свойство stopCall - вызов опоследующих обработчиков прекратится.
* Возвращаемые оператором return значения попадут в свойство lastResult объекта event для следующего обработчика. Так же если будет передано false - это вызовет методы stopPropagation и preventDefault для события.
* Если в обработчике возникает ошибка, она будет занесена в массив errors объекта event.

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

x-yuri 06.10.2009 13:52

читабельность пострадала

B~Vladi 06.10.2009 13:55

Цитата:

Сообщение от x-yuri
читабельность пострадала

Эм... ну можно скопировать в свой IDE и применить форматирование, если оно есть:)

B~Vladi 06.10.2009 14:03

Ещё есть мысль добавить обработку типов события, например, если передано mousewheel, то для Gecko подставлять DOMMouseScroll ну и т.д. Проблема только в том, что я не знаю всех таких типов. Вот, что у меня есть:
mousewheel - DOMMouseScroll
activate - DOMFocusIn
deactivate - DOMFocusOut

Если кто-нибудь знает подобные случаи - нипишите, плиз!!!:help:

Kolyaj 06.10.2009 14:06

Цитата:

Сообщение от Илья Кантор
1. Поясню отличие для читателей комментария. Callback (в смысле Dean'а) - означает, что один инициировавший исключение обработчик события не дает выполняться следующим. А события - это когда обработчики выполняются независимо от результата друг друга.

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

Поэтому такое поведение это не недостаток, а преимущество. IMO.

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

З.Ы. Если кто не понял, это камент из статьи Ильи о добавлении обработчиков событий.

B~Vladi 06.10.2009 14:08

Цитата:

Сообщение от Kolyaj
В продкшн-режиме же система должна быть максимально устойчивой к ошибкам

Да, и я так же считаю, поэтому и прикрутил:)

Kolyaj 06.10.2009 14:43

А отлавливать их как предлагается?

B~Vladi 06.10.2009 14:49

Цитата:

Сообщение от Kolyaj
А отлавливать их как предлагается?

try catch...
А есть другие варианты?! В массив попадает сообщение из catch.

B~Vladi 06.10.2009 14:54

Добавил строчку
delete evt.lastResult;

для того, чтобы всплывающие события не наследовали это свойство.

Ещё вопрос: можно как-нибудь оптимизировать массив allList? Чтобы уменьшить количество циклов и проверок...

Kolyaj 06.10.2009 14:58

В прикладном коде как отлавливать? Мониторить массив по setTimeout?

B~Vladi 06.10.2009 14:59

Цитата:

Сообщение от Kolyaj
В прикладном коде как отлавливать?

Блин, не понимаю... В каком коде?! В обработчике отлавливается... где ещё надо?!

Kolyaj 06.10.2009 15:02

Обновил
Цитата:

Сообщение от Kolyaj
Мониторить массив по setTimeout?

Как мы узнаем, что произошла ошибка?

B~Vladi 06.10.2009 15:02

Цитата:

Сообщение от Kolyaj
Мониторить массив по setTimeout?

Зачем... Вызываем обработчик... Если ошибка - catch заносит сообщение в массив. Вызываем следующую ф-цию... По-коду же видно...
Цитата:

Сообщение от Kolyaj
Как мы узнаем, что произошла ошибка?

catch сработает...

Kolyaj 06.10.2009 15:04

Вот я повесил обработчик события на document. Внутри обработчика ошибка, но я о ней не узнаю, т.к. она подавляется.

B~Vladi 06.10.2009 15:07

Такой пример:
Event.Add(ele,'click',caller);
function caller(){
error();
}
function error(){
document.createElement();
}

Даже если исключение происходит не в обработчике - оно ловится в try и добавляется в errors. Т.е. ошибку мы поймаем в любом случае.
Цитата:

Сообщение от Kolyaj
т.к. она подавляется.

Она не подавляется... интерпретатор сам останавливает выполнение функции... А узнать об ошибке можно из errors.

x-yuri 06.10.2009 15:09

а как ты узнаешь, что ошибка попала в errors? setTimeout или событие?

B~Vladi 06.10.2009 15:13

Цитата:

Сообщение от x-yuri
а как ты узнаешь, что ошибка попала в errors? setTimeout или событие?

Это можно узнать из следующего обработчика из списка, еси оно вызывается, а так же из всплывающих событий, т.е. объект event там тот же (event.errors).
Добавил run в код библиотеки, чтобы можно было потестить на форуме.

e1f 06.10.2009 15:14

x-yuri,
Да, хорошо бы API вида
Event.Add(ele, type, {
    callback: fnc,
    onerror: function() {
        //do something...
    }
});

B~Vladi,
а если нет уже ни всплытия, ни другого обработчика?
Event.Add(document, 'click', function(){}) //это первый и последний бинд клика на документ, и в нем мб ошибка

B~Vladi 06.10.2009 15:16

Цитата:

Сообщение от e1f
Да, хорошо бы API вида

Аха, это мысль!
Именно такого вида?!
А если в onerror ошибка?:D

e1f 06.10.2009 15:19

Цитата:

Сообщение от B~Vladi (Сообщение 31880)
А если в onerror ошибка?:D

А если в коде самого фреймворка ошибка? ;)
Частично может помочь window.onerror

B~Vladi 06.10.2009 15:26

Цитата:

Сообщение от e1f
А если в коде самого фреймворка ошибка?

jQuery и тот нередко падает от кривых параметров;)

e1f 06.10.2009 15:34

B~Vladi,
бывает, чего греха таить :)

B~Vladi 06.10.2009 15:49

Добавил предложенное API. Теперь можно передавать обработчики как простой функцией, так и:
{handler:fnc,onerror:fnc}

Если же onerror небыло передано и возникла ошибка, она добавится в массив errors объекта event. Так пойдёт?!
При удалении тоже можно передавать как объект, так и функцию:)

Давайте ещё предложения!:)


Часовой пояс GMT +3, время: 20:16.