Сегодня мы поговорим о возможности динамической предзагрузки библиотеки по требованию. Изначально, для использования фреймворка, Вам надо на странице подключать сначала стилевой файл, потом адаптер, которые реализует основной функционал, а в случае использования другой AJAX-библиотеки в качестве основы, сначала и ее дистрибутив. И только потом уже основной файл ExtJS, либо его debug-версию на этапе разработки. Конечно, сократить время загрузки поможет объединение всех файлов в один, сжатие gzip и другие методики. Но…
Но что, если задача достаточно узкая, например, я столкнулся с ней, когда некоторый веб-сайт использует ExtJS для предоставления формы добавления и редактирования материалов. При этом процесс редактирования он достаточно редкий, в смысле что не каждый пользователь постоянно будет им пользоваться, кроме этого, работа с сайтом в режиме без регистрации отличается только отсутствием возможности редактирования. Загружать же сразу все файлы, а это почти 600 Кб, пусть даже тщательно собранной версии специально под проект, с учетом его потребностей, это достаточно накладно, и не хотелось бы грузить их всем пользователям.
Получилась следующая картина. Всем посетителям, которые без регистрации, поисковым ботам и прочим, загружаются стандартные страницы, не использующие никакие возможности редактирования, соответственно, там эти файлы даже не подключаются. В результате имеем легкие страницы, пригодные для просмотра и индексирования.
В случае же зарегистрированного пользователя картина немного изменяется. Ему уже надо сделать доступными инструменты редактирования информации, но все же велика вероятность, что он ими так и не воспользуется, поэтому мы не собираемся и на этом этапе ему загружать всю библиотеку ExtJS. А делаем следующее.
Изначально к странице добавляется стилевой файл из дистрибутива ExtJS. Из скриптов мы используем сборку библиотеки, использующую jQuery и специальный адаптер. Вот эти два файла мы объединим в один, сначала минифицированную версию jQuery, потом Ext-jquery-adapter. И этот скрипт загружается на страницу. Сжатая версия CSS от ExtJS занимает примерно 40 Кб (особенно, если и ее откорректировать под нужды проекта), а минифицированный скрипт, объединяющий необходимые библиотеки — 73 Кб, и это все пока без учета возможностей gzip-сжатия.
В результате мы получаем на странице, во-первых, основные возможности от jQuery, и, главное, самое-самое минимальное ядро от ExtJS, буквально основные функции и возможности корневого класса Ext и его расширения для стандартных объектов JavaScript (например, String, Array и Date при использовании ExtJS получают некоторые «бонусы»).
Если посмотреть в код библиотеки, то там видно, что основной файл, ext-all.js содержит все остальные компоненты, при этом он расширяет уже предварительно загруженный класс Ext. А это означает, что он может быть загружен в произвольный момент уже после загрузки всей страницы и после его исполнения браузером мы получим «на лету» все нужные нам возможности. Главное, что необходимо — это предварительно уже загруженный адаптер и инициализированную основу для скрипта.
А теперь займемся подгрузкой библиотеки. Так как пока нам не доступны функции из ExtJS, мы для ее инициализации используем функционал из jQuery, а именно — встроенную возможность загрузки произвольного JS-кода на страницу и выполнения переданной Callback-функции после успешной обработки данных. В предыдущих версиях jquery можно было загружать только с текущего домена, сейчас разрешена и кроссдоменная загрузка.
Дополнительно нам надо создать переменную-флаг для оповещения приложения о том, была ли загружена полная библиотека или только ее ядро — средствами ExtJS это узнать затруднительно, потому что как бы библиотека загружена, вместе с тем все основные ее возможности ещё недоступны. Поэтому мы создаем глобальную переменную-флаг для хранения информации о состоянии библиотеки.
Кстати, сразу можно конфигурировать Ext, например, установить опции встроенных сборщиков мусора и другие, например путь для констант BLANK_IMAGE_URL, эти возможности ядра доступны сразу после инициализации. Если Вам надо производить дополнительные настройки, например, инициализацию менеджера cookie, то рекомендую вынести все это в отдельную функцию, которую мы потом будем автоматически вызывать после загрузки.
И теперь финал, который совсем простой. Функция _loadExtJS_andRun принимает единственный параметр, callback-функцию, которую необходимо выполнить после загрузки библиотеки. Сначала проверяем наш флаг — если ExtJS уже загружен, пропускаем все действия и сразу вызываем callback. Если нет — используем загрузчик из jQuery, который после успешной загрузки вызовет сначала нашу функцию инициализации (если она есть, в примере я инициализирую State Manager для работы с cookie и QuikTip прямо в коде, но это лучше оформить в виде функции), а потом и callback.
Для реального применения лучше дополнить этот код еще реакцией на вариант, когда загрузка по каким-либо причинам не удалась, например, показать сообщение пользователю.
Так как загрузка большой библиотеки может занять некоторое время, рекомендую использовать прелоадер и показать пользователю, что приложение что-то делает, хотя это будет только при первом обращении к функциональности, требующей возможностей ExtJS.
Самый простой вариант применения — по клику на изображение мы хотим вывести диалоговое окно Ext.Msg.alert, при этом мы не знаем, а наша функция обработки клика и не хочет (да и не обязана) знать, доступен ли ExtJS. Потому мы в обработчике указываем ее как callback-функцию для нашего загрузчика, который самостоятельно проверяет доступность библиотеки, отвечает за ее корректную инициализацию и выполнение нашей функции только тогда, когда все для этого готово.
Но что, если задача достаточно узкая, например, я столкнулся с ней, когда некоторый веб-сайт использует ExtJS для предоставления формы добавления и редактирования материалов. При этом процесс редактирования он достаточно редкий, в смысле что не каждый пользователь постоянно будет им пользоваться, кроме этого, работа с сайтом в режиме без регистрации отличается только отсутствием возможности редактирования. Загружать же сразу все файлы, а это почти 600 Кб, пусть даже тщательно собранной версии специально под проект, с учетом его потребностей, это достаточно накладно, и не хотелось бы грузить их всем пользователям.
Получилась следующая картина. Всем посетителям, которые без регистрации, поисковым ботам и прочим, загружаются стандартные страницы, не использующие никакие возможности редактирования, соответственно, там эти файлы даже не подключаются. В результате имеем легкие страницы, пригодные для просмотра и индексирования.
В случае же зарегистрированного пользователя картина немного изменяется. Ему уже надо сделать доступными инструменты редактирования информации, но все же велика вероятность, что он ими так и не воспользуется, поэтому мы не собираемся и на этом этапе ему загружать всю библиотеку ExtJS. А делаем следующее.
Изначально к странице добавляется стилевой файл из дистрибутива ExtJS. Из скриптов мы используем сборку библиотеки, использующую jQuery и специальный адаптер. Вот эти два файла мы объединим в один, сначала минифицированную версию jQuery, потом Ext-jquery-adapter. И этот скрипт загружается на страницу. Сжатая версия CSS от ExtJS занимает примерно 40 Кб (особенно, если и ее откорректировать под нужды проекта), а минифицированный скрипт, объединяющий необходимые библиотеки — 73 Кб, и это все пока без учета возможностей gzip-сжатия.
В результате мы получаем на странице, во-первых, основные возможности от jQuery, и, главное, самое-самое минимальное ядро от ExtJS, буквально основные функции и возможности корневого класса Ext и его расширения для стандартных объектов JavaScript (например, String, Array и Date при использовании ExtJS получают некоторые «бонусы»).
Если посмотреть в код библиотеки, то там видно, что основной файл, ext-all.js содержит все остальные компоненты, при этом он расширяет уже предварительно загруженный класс Ext. А это означает, что он может быть загружен в произвольный момент уже после загрузки всей страницы и после его исполнения браузером мы получим «на лету» все нужные нам возможности. Главное, что необходимо — это предварительно уже загруженный адаптер и инициализированную основу для скрипта.
А теперь займемся подгрузкой библиотеки. Так как пока нам не доступны функции из ExtJS, мы для ее инициализации используем функционал из jQuery, а именно — встроенную возможность загрузки произвольного JS-кода на страницу и выполнения переданной Callback-функции после успешной обработки данных. В предыдущих версиях jquery можно было загружать только с текущего домена, сейчас разрешена и кроссдоменная загрузка.
Дополнительно нам надо создать переменную-флаг для оповещения приложения о том, была ли загружена полная библиотека или только ее ядро — средствами ExtJS это узнать затруднительно, потому что как бы библиотека загружена, вместе с тем все основные ее возможности ещё недоступны. Поэтому мы создаем глобальную переменную-флаг для хранения информации о состоянии библиотеки.
Кстати, сразу можно конфигурировать Ext, например, установить опции встроенных сборщиков мусора и другие, например путь для констант BLANK_IMAGE_URL, эти возможности ядра доступны сразу после инициализации. Если Вам надо производить дополнительные настройки, например, инициализацию менеджера cookie, то рекомендую вынести все это в отдельную функцию, которую мы потом будем автоматически вызывать после загрузки.
И теперь финал, который совсем простой. Функция _loadExtJS_andRun принимает единственный параметр, callback-функцию, которую необходимо выполнить после загрузки библиотеки. Сначала проверяем наш флаг — если ExtJS уже загружен, пропускаем все действия и сразу вызываем callback. Если нет — используем загрузчик из jQuery, который после успешной загрузки вызовет сначала нашу функцию инициализации (если она есть, в примере я инициализирую State Manager для работы с cookie и QuikTip прямо в коде, но это лучше оформить в виде функции), а потом и callback.
- Ext.BLANK_IMAGE_URL = '/inc/extjs/resources/images/default/s.gif';
- Ext.enableGarbageCollector = true;
- //глобальный флаг загрузки
- _isLoadedExtJS = false;
- function _loadExtJS_andRun(callback)
- {
- if (_isLoadedExtJS == false) //проверяем флаг
- {
- //используем загрузчик из JQuery
- $.getScript('/inc/extjs/ext-all.js', function(data, textStatus){
- if (textStatus == 'success')
- {
- _isLoadedExtJS = true;
- Ext.state.Manager.setProvider(new Ext.state.CookieProvider({
- path: "/",
- expires: new Date(new Date().getTime()+(1000*60*60*24*30))
- }));
- Ext.QuickTips.init();
- //вызвать калбек
- callback();
- }
- });
- }
- else
- {
- callback();
- }
- }
* This source code was highlighted with Source Code Highlighter.
Для реального применения лучше дополнить этот код еще реакцией на вариант, когда загрузка по каким-либо причинам не удалась, например, показать сообщение пользователю.
Так как загрузка большой библиотеки может занять некоторое время, рекомендую использовать прелоадер и показать пользователю, что приложение что-то делает, хотя это будет только при первом обращении к функциональности, требующей возможностей ExtJS.
Самый простой вариант применения — по клику на изображение мы хотим вывести диалоговое окно Ext.Msg.alert, при этом мы не знаем, а наша функция обработки клика и не хочет (да и не обязана) знать, доступен ли ExtJS. Потому мы в обработчике указываем ее как callback-функцию для нашего загрузчика, который самостоятельно проверяет доступность библиотеки, отвечает за ее корректную инициализацию и выполнение нашей функции только тогда, когда все для этого готово.
- style="cursor:pointer;"
- onclick="javascript: void _loadExtJS_andRun(function(){ Ext.Msg.alert('Alert','Hello, World!'); }); "
- src="inc/images/people.png"
- border="0"
- alt="Your Blog Tagline"
* This source code was highlighted with Source Code Highlighter.