Pull to refresh

Comments 45

Интересно! :) Благодаря Вашему посту открыл для себя GWT. Раньше не знал, что есть такая замечательная библиотека. Смотрю теперь на Web иначе.
это очень странно потому что GWT уже долго есть, и пиарится достаточно не плохо самим гуглом…
Да это моя зеленость сказывается :) Надо же с чего-то начинать.
Помимо сжатия можно попробовать правильные хедеры выставлять статичным файлам (304 Not Modified) — js, css, картинкам.
Существенно снизит трафик (и сэкономит деньги на cloudfront) и ускорит повторную загрузку.

По поводу кэширования — есть забавный способ кэшировать через css но я не до конца уверен, во всех ли браузерах он работает:

.b-cache {
background: url(image1);
background: url(image2);
background: url(image3);
background: url(image4);
background: none;
}

Вечером сегодня протестирую этот способ.

В остальном всём кстати очень может помочь плагин Google Page Speed.
По поводу 304, у амазона это автоматически сделано. На Tomcat для статических файлов 304 работает по умолчанию. У Apache 2.2.9-10+lenny4 тоже 304 при повторной закачке.

По поводу кэширование через background — на сколько мне известно это хороший способ при небольшом количестве картинок.
При большом количестве картинок всплывают некоторые особенности
1) Невозможно остановить закачку
2) Невозможно контролировать количество потоков(прибито гвоздём в браузере)
Как следствие это может вызвать проблемы при большом количестве файлов(600 файлов — 10Мб).

Например все выделенные потоки для данного домена у браузера заняты, и запросы посланные js будут поставлены в очередь. В то время как картинки могли бы и подождать 0,01 секунды. А получается что будет ждать пользователь тк ресурсы браузера исчерпаны.

У нас эта проблема решена 2раза :)
1) разнос статики и динамики на разные сервера (статика у Амазона)
2) сокращение конкурирующих потоков в канале на стороне пользователя, чрез контролирование количества потоков прелоадера

У подхода с использование js есть свой минус, неработает при отсутствии js. Для нашего проекта данный пункт не актуален по причине аяксовости приложения — те если js у клиента отключен, это не наш клиент.

В приведённом кусочке js есть неявная возможность контролировать количество потоков. Изменив количество вызовов функции cacheImage(); в 8-ой строке.
«могущество java технологий создаваемых десятками тысяч гениальнейших программистов уже второе тысячелетие подряд» — я что-то пропустил в учебнике по истории? :)
UFO just landed and posted this here
Вобщем-то нет ))
Конец прошлого и начало этого — итого: второе подряд
согласен, а в целом вполне себе полезное чтиво, если не учитывать, что каждый считает своим долгом самому проводить тесты по оптимизации :) от себя спасибо за лишний час жизни, не потраченый на yuicompressor.
Здесь надо обратить на ключевую фразу «файла прошедшего через обфускацию средствами GWT», те если скрипт рукописный то он возможно очень сильно поможет
Ну Java же не на пустом месте возникла :) А гениальные Java-программисты наверняка были и до её появления — только проявить себя не могли :)
Вы решили показать пример того как не надо писать код? with не рекомендуемый зачем-то.
В самой статье довольно сумбурный ход мыслей.
беспользный комент, хотя возможно и отражет сложившуюся ситуацию
Вы забыли обозначить ошибки, по этой причине я не могу вам аргументированно ответить или исправить ошибку
Вместо системного последовательного подхода у вас какой-то метод народного тыка, который случайно привел к каким-то сомнительным результатам, которые так же сложно оценить не имея того, с чем можно сопоставить и к чему стремились.
Это обходилось через вставку анонимной функции в onload и onerror которая вызывала родительскую функцию, те получалась рекурсия не позволяющая высвободить уже неиспользуемую память. Это проявилось в IE через ошибку «out of memory».

Вы про attachEvent/addEventListener не слышали?
А зачем массив с картинками в глобальную область видимости класть?
А with(img) зачем использовать?
Всем, кто начинает изучать Javascript: вот отличный пример того, как НЕ НАДО делать.
А with(img) зачем использовать?

Все про это говорят, но я так и не понял: чем плох with? По-моему — вполне даже ничего.
Тем, что with работает совсем не так, как, очевидно, предполагает автор. Оператор with изменяет правила разрешения имен, что может приводить к крайне нетривиальным коллизиям, а не просто дает доступ к полям объекта.
См. books.google.ru/books?id=xn5aJpEJSEYC&lpg=PP1&ots=FK-RQ9KMPz&dq=flanagan%20javascript&pg=PA99#v=onepage&q=&f=false, глава 6.18
1) отрицательно сказывается на производительности (виртуальной машине приходится заводить выделенное пространство имен)
2) не дает возможность корректно разрешить логику скрипта для внешних анализаторов (в частности, тот же YUI Compressor просто отказывается имена переменных в таких скриптах заменять)
3) Ничем не лучше (в данном случае и в общем) использования закэшированных переменных.

Собственно, все это ведет к тому, что with считается таким же моветоном, как и eval
Вы про attachEvent/addEventListener не слышали?

Если я правильно понимаю документацию, и моя документация не устарела то этот подход не позволяет освободить память от предыдущего контекста, как следствие out of memory остаётся в силе
А зачем массив с картинками в глобальную область видимости класть?

fixed
А with(img) зачем использовать?

fixed
Всем, кто начинает изучать Javascript: вот отличный пример того, как НЕ НАДО делать.

что-то ещё :)
попробуйте duris.ru, все картинки автоматически предзагружаются за один запрос ;)
здорово, но помоему это немного не то :)
а почему бы и нет :), можно разбить на части. ну не АЯКСом их грузить, мне кажется это слишком, я хоть и ярый fullajax-er, но указанная реализация нерациональна, хотя тоже имеет право на жизнь.
я ниже описал выход. Просто конкретно DURIS здесь может быть упомянут как подход. С тем же успехом можно упомянуть про Web Optimizer — ибо в нем тоже есть data:URI + mhtml + разделение файлов :)
ну почему только же как подход и как решение :), Web Optimizer заточен под PHP, в данном случае его трудно применить
отличная статья. Показательная. На тему того, как НЕ надо решать проблемы, но как они решаются в 99% случаях :)

Обычно, если не знают, как справиться с проблемой, то читают фундаментальные основы (например, той же клиентской оптимизации). Выясняют, как работает Tomcat. Выясняют, какая выгода от конкретных методик и приемов. А потом выбирают наиболее действенные и начинают их использовать. Здесь же был обратный подход: у нас есть непонятная в решении проблема, давайте ее бить всем, что под руку попадется — авось, сработает. Ну да, с пятого раза сработало. Повезло :)

По поводу картинок: 9Мб / 600 ~= 15 Кб. Если у вас на странице заканчиваются потоки (а при таком объеме они 100% будут заканчиваться), то реально стоит смотреть в сторону решений а-ля DURIS — через data:URI (mhtml) объединяем картинки в чанки (по 100Кб, например, которые еще и архивироваться умеют, общие потери на размер = 5-10%, выигрыш от канала +50%), затем на каждую страницу выливаем свое количество чанков (через файлы стилей, например).

Может быть, также сильно помогут множественные хосты: не увидел этого в заметке — они используются?
отличная статья. Показательная. На тему того, как НЕ надо решать проблемы, но как они решаются в 99% случаях :)

Обычно, если не знают, как справиться с проблемой, то читают фундаментальные основы (например, той же клиентской оптимизации). Выясняют, как работает Tomcat. Выясняют, какая выгода от конкретных методик и приемов. А потом выбирают наиболее действенные и начинают их использовать. Здесь же был обратный подход: у нас есть непонятная в решении проблема, давайте ее бить всем, что под руку попадется — авось, сработает. Ну да, с пятого раза сработало. Повезло :)

Я забыл сказать что я администратор :), и с Томкатом немного знаком. Правда больше приходилось работь с Apache 1.3 те больше работал с C/C++ программами. Сейчас же преключаюсь на Java
По выгодам я вроде показал где и от чего сколько, если вы с чем-то несогласны я готов изучить этот вопрос и внести изменения или конструктивно ответить.

По поводу картинок: 9Мб / 600 ~= 15 Кб. Если у вас на странице заканчиваются потоки (а при таком объеме они 100% будут заканчиваться), то реально стоит смотреть в сторону решений а-ля DURIS — через data:URI (mhtml) объединяем картинки в чанки (по 100Кб, например, которые еще и архивироваться умеют, общие потери на размер = 5-10%, выигрыш от канала +50%), затем на каждую страницу выливаем свое количество чанков (через файлы стилей, например).

Спасибо за разъяснение, эта часть очень полезна и я её обязатьельно изучу. К соожалению высказывание автора выше не было стольже понятным.

Может быть, также сильно помогут множественные хосты: не увидел этого в заметке — они используются?

Да такое есть и встатье есть упоминание.
я к тому, что подход просто неправильный показан. Gzip дает выигрыш в 80%. После него стоит жать YUI / JSMin скрипты и CSS Tidy / YUI стили. Но выигрыш в этом случае будет не больше 5-8%. 800Кб * 0,05 = 40 Кб. Естественно, что более действенным методом оказался выброс неиспользуемых скриптов. Но это работает далеко не всегда (и советовать выбрасывать неиспользуемую функциональность вредно: это ведет ко всяким «урезанным» версиями jQuery / Mootools и т.д.). Хотя куда проще взять тот же Sizzle / YASS, прикрутить к нему пара реально нужных модулей и запустить все это в продакшен.

Далее. Тема «нагрузки на сервер от сжатия» совершенно не раскрыта. Я так понимаю, что Java — это backend? Тогда скрипты и стили можно замечательно жать при деплое, а сам Amazon (я более чем уверен) может gzip-ипить самостоятеьно. Или у вас запросы напрямую к Tomcat для HTML-динамики? Тогда стоило упомянуть про альтернативные методы, типа minify — когда мы из HTML-кода выбрасываем все, причем именно в момент деплоя рабочей версии на рабочий сервер, чтобы «на лету» этим не заниматься.

Далее. Тема кэширования (клиентского) тоже совершенно не раскрыта. Не понятно, насколько у вас обновляется поток пользователей. Если 80% возвращаются в течение месяца-двух, то такой же процент проблем можно было решить несколькими строчками в конфиге и несколькими правилами при деплое (чтобы кэш корректно сбрасывать).

Я могу долго так продолжать. Просто мне грустно, что микроскопом гвозди забивают. Что экономят: сначала работодатели, не желающие решать задачи с помощью тех сотрудников, которые для этого предназначены, например, клиентских архитекторов; а затем и сами сотрудники, потому что сроки поджимают, потому что попалась «новая интересная задача», потому что такой подход к самообразованию — неструктурированный. Грустно от того, что независимо от количества информации на тему клиентской оптимизации (сотни, если уже не тысячи статей, несколько полноценных книг, десятки докладов) все равно 90% разгона будет осуществляться именно так, «на коленке», на скорую руку, чтобы только работало. А что это не масштабируемо, что это будет не актуально через год, например. Что это, ускоряя в одном месте, будет замедлять в другом — никого не волнует.

Просто грустно.
> Хотя куда проще взять тот же Sizzle / YASS

А я вот считаю, что полноценная машина селектров редко когда нужна (ообенно свойства типа :nth-child), по моему так проще написать пару своих функций типа findByClass(), findFirstChild() (ессно с поддержкой штук типа getByClassName/querySelectorAll, если они есть в браузере), этого хватает в 90% случаев, а код намного лечге и быстрее.

собственно YASS по такой технологии и написан. Вы бы ознакомились что ли
Нет, не по такой. Я пишу, что мне достаточно часто только поиска по имени класса/тега, без поддержки сложных селекторов, и уж тем более без истемы динамической загрузки яваскрипт-файлов с зависимостями (хотя конечно иногда это может и пригодиться).
CSS1-ветка — это именно то, что Вы описываете. Я что-то упустил?
Может, я не ясно выразился. Мне хватает поиска по таким селекторам: tag, .class и tag.class. Про ветку css1 я не знал, но даже там строка для поиска парсится, а в моем случае парсер просто излишен.
я к тому, что подход просто неправильный показан. Gzip дает выигрыш в 80%. После него стоит жать YUI / JSMin скрипты и CSS Tidy / YUI стили. Но выигрыш в этом случае будет не больше 5-8%. 800Кб * 0,05 = 40 Кб. Естественно, что более действенным методом оказался выброс неиспользуемых скриптов. Но это работает далеко не всегда (и советовать выбрасывать неиспользуемую функциональность вредно: это ведет ко всяким «урезанным» версиями jQuery / Mootools и т.д.). Хотя куда проще взять тот же Sizzle / YASS, прикрутить к нему пара реально нужных модулей и запустить все это в продакшен.


По этому поводу написано, и даже приведён листинг. В моём случае при использовании yui размер увеличился. Подробности в тексте.

Далее. Тема «нагрузки на сервер от сжатия» совершенно не раскрыта. Я так понимаю, что Java — это backend? Тогда скрипты и стили можно замечательно жать при деплое, а сам Amazon (я более чем уверен) может gzip-ипить самостоятеьно. Или у вас запросы напрямую к Tomcat для HTML-динамики? Тогда стоило упомянуть про альтернативные методы, типа minify — когда мы из HTML-кода выбрасываем все, причем именно в момент деплоя рабочей версии на рабочий сервер, чтобы «на лету» этим не заниматься.

1) Да можно жать, на эту тему есть в статье заметка, в конце
2) Амазон не жмёт контент, но позволяет пользователю сжать, закачать и выставить соответствующие заголовки. И этот момент я действительно не упоянул.
3) Статика хранится на S3 динамика на Tomcat. К Tomcat идут только rpc запросы и там хранятся файлы который изменются при обновлениях. Например js (с очень большой вероятностью это в дальнейшем изменится). Я действитель забыл на это указать. И это важный момент.
— про minify почитаю

Я могу долго так продолжать. Просто мне грустно, что микроскопом гвозди забивают. Что экономят: сначала работодатели, не желающие решать задачи с помощью тех сотрудников, которые для этого предназначены, например, клиентских архитекторов; а затем и сами сотрудники, потому что сроки поджимают, потому что попалась «новая интересная задача», потому что такой подход к самообразованию — неструктурированный. Грустно от того, что независимо от количества информации на тему клиентской оптимизации (сотни, если уже не тысячи статей, несколько полноценных книг, десятки докладов) все равно 90% разгона будет осуществляться именно так, «на коленке», на скорую руку, чтобы только работало. А что это не масштабируемо, что это будет не актуально через год, например. Что это, ускоряя в одном месте, будет замедлять в другом — никого не волнует.

Очень хорошо. Пределов совершенству нет. Я внимательно читаю.
Это из раздела экономики и ограниченности ресурсов. Я незнаю лучшего пути и если Вы его предложете я готов по нему пойти :)
По поводу мастабируемости можно по подробнее.
Замедление в другом месте(сжатие на коннекторе) сейчас наиболее дёшево, и через год это станет не актуальным. По одной из 2х причин.
1) Эта установка будет стоять за кэширующим балансировщиком (он закэшируетс файлы с расширением js, html, xml, ..., как следствие сжатие на коннекторе будет производиться один раз)
2) Это будте сделано средствами приложения (в моём понимании на этом этапе это не требуется, тк есть более важные задачи и ограниченные ресуры)

«невешать нос Гардемарины… » :)
проблема в том, что я уже иду по лучшему пути. И, возможно, смогу доказать через год-другой Вашему менеджеру, что текущий путь не верен и текущий подход не применим. И что на Ваших услугах можно сэкономить. Потому что считаю, что производительностью должны заниматься профессионалы. И стоить это должно копейки (или даже бесплатно). Как это совместить — уже другой, намного более интересный вопрос :)
К сожалению хабрапочта работает через раз, и отправить в личку не удалось.

Готов дать Вам контакты моего руководства прямо сейчас, и я не беспокоюсь остаться без работы. Моя работа станет ещё более интересной и насыщенной.

С уважением к Вам и вашим трудам.
зы: оч жаль что не вличку
Хотя куда проще взять тот же Sizzle / YASS, прикрутить к нему пара реально нужных модулей и запустить все это в продакшен.

С другой стороны, в последствии когда придется (из жизненного опыта говорю) дорабатывать/расширять функционал проекта, такая экономия приводит в основном к изыбретению большого количества костылей: уже есть достаточно увесистый кусок кода базирующийся на некой легковесной библиотеке (а то и самопальной недобиблиотеке-lite-0.3-alpha :)), старых возможностей не хватает, а прикрутить универсальный jQuery (Mootools, пр.) уже как-то не к селу, не к городу.
Как раз недавно тоже столкнулись с проблемой производительности в проекте. Страница грузилась конечно не 1,5 минуты, ну а секунд 30-35. Приложение построено на WebSphere Portal и java-технологиях. Сделали почти тоже самое, кроме предзагрузки изображений.
— кэширование стратики на сервере
— оптимизация изображений
— компрессия js и css
— перенос картинок на другой хост

700 Кб яваскрипта?? Ничего личного, но по моему, фигня ваш проект, с точки зрения качества, а яваскрипт надо писать ручками, а не генерировать кодогенераторами. И да, я не люблю Яву, и чрезмерное использвоание стороннего кода, как выясняется не зря :)
UFO just landed and posted this here
Спасибо, очень полезная ссылка
Sign up to leave a comment.

Articles