There are good reasons to use Google's Content Delivery Network (CDN) to serve jQuery and jQuery UI on your site:
- Decreased latency
- Increased parallelism
- Better caching
- Reduced load on your server
(You can read more about them here.)
This tutorial shows you how to use Goggle's CDN to serve jQuery and jQuery UI in Yii.
Edit your Config File ¶
There are three additions to make in your config file:
- Define the JUI Theme you want to use.
- Add a package definition for jQuery under the "clientScript" component in the "components" section
- Set "theme", "scriptURL" and "themeURL" for each JUI Widget you use the "widgetFactory" section; the URLs point to Google's CDN, the theme uses the define from step 1.
define('JUI-THEME','dark-hive');
return array(
// other config
'components'=>array(
'clientScript'=>array(
'packages'=>array(
'jquery'=>array(
'baseUrl'=>'//ajax.googleapis.com/ajax/libs/jquery/1/',
'js'=>array('jquery.min.js'),
)
),
// other clientScript config
),
'widgetFactory'=>array(
'widgets'=>array(
'CJui<WidgetName>'=>array( // where <WidgetName> is the name of the JUI Widget (Tabs, DatePicker, etc.). Each CJuiWidget used must be declared
'scriptUrl'=>'//ajax.googleapis.com/ajax/libs/jqueryui/1/',
'i18nScriptFile' => 'i18n/jquery-ui-i18n.min.js',
'theme'=>JUI-THEME,
'themeUrl'=>'//ajax.googleapis.com/ajax/libs/jqueryui/1/themes/',
),
// Repeat for other CJuiWidgets
),
),
// other component config
),
// other config
);
Note that the URLs are missing the protocol. This allows users browsers to cache both http and https requests from a single download.
That's it - your application will now use Google's CDN to serve jQuery and jQuery UI; to the benefit of you and your visitors. It also means that a single change in the config file will change the theme of all your JUI widgets.
(Thanks to redguy for pointing out the widget factory configuration)
Very nice howto
...but I have simple extension. According to http://www.yiiframework.com/doc/guide/1.1/en/topics.theming (section 'customizing widgets globally') you do not have to pass this yui configuration in params and use it in every widtget (and probably modify your existing code). You can simply configure it in main.php config file:
return array( 'components'=>array( 'widgetFactory'=>array( 'widgets'=>array( 'CJuiDatePicker'=>array( 'scriptUrl'=>'//ajax.googleapis.com/ajax/libs/jqueryui/1/', 'theme'=>'dark-hive', 'themeUrl'=>'//ajax.googleapis.com/ajax/libs/jqueryui/1/themes/', ), //... //other Yui widgets overloaded params goes here... ), ), ), );
quite nice, huh? :)
@reguy
many thanks for this - main article updated
API key required
Do we need a Google API key to load the libraries using script tags?
This guide seems to indicate so: http://code.google.com/intl/nl-NL/apis/libraries/devguide.html
Re: API key required
No - an API key is not required to use the Content Delivery Network
Error with JUI-THEME
It seems that JUI-THEME is an invalid constant because of the dash. You can simply change it, of course, to something like JUI_THEME.
Not correct
This script uses googles latest jquery version. This has several disadvantages:
Your scripts may not support future jQuery versions. So from one day to another your whole site can stop working.
The caching is only done 1h - so caching might even be better if you host it on your page.
Here is a link on this topic search for "1/": 9353 resons for google cdn
I think below the define of JUI theme add a define of jquery version and update all the configs below.
@balrok
You are correct that the code as written will use the latest 1.x version.
If you need to use a specific version (good idea for the reason you say) simply replace the '1' with the version number, e.g. 'baseUrl'=>'//ajax.googleapis.com/ajax/libs/jquery/1.6.2/' will use JQuery V1.6.2
WRT caching: using a CDN means the cache is valid for ALL sites that use the CDN, not just yours, meaning that if the user already has the version of JQuery you are using in their cache there is no trip to the server.
@Yeti
You didn't got my point. I'm not a noob user who don't know how to change the code. I wanted to help improve the article.
If you know how caching works you would understand that the cdn can add metainformation about their content when it will invalidate. Open /1/ and look at the headers you receive (try firebug or curl -D):
Cache Control is "public, must-revalidate, proxy-revalidate, max-age=3600"
Now the same for /1.7.1/ Cache Control is "public, max-age=31536000"
The Bold number say that /1.7.1/ will be cached for a year and /1/ just for an hour.
If you don't trust me read the link I've provided.
It would be nice if the article could either state that /1/ is for the lazy but with some disadvantages or that they should add their jquery version into the code (maybe as define on the top which can also be initially at /1/ but should discuss the advantage of specific versions later).
PS: another (quite old but still valid) link: cdn cache
How to define a fallback?
Hi!
Thanks for the tut (and I also agree with balrok BTW).
Is there a way to define a local fallback in case the CDN is not reachable?
Cheers!
@fleurc
WRT fallback. A JS snippet after the CDN load to test if JQuery is loaded, if not use the local copy.
Something like:
~~~
[js]
~~~
@Yeti
Yeah, I know about this solution, but I was wondering if there was a Yii way to do this (apart from registerScript with this snippet). I guess not...
Thanks anyway!
JqueryUI il8n
I would just like to point out that if you are using languages other than English for JqueryUI widgets, you will also need to include
'i18nScriptFile' => 'i18n/jquery-ui-i18n.min.js',
in your widget factory configuration, otherwise the right url will not be referenced.
I also agree with balrok that it would be a good idea to make a note about the difference between using /1/ for the latest version of JQuery and using a specific version.
Uncaught TypeError: Cannot read property '3' of undefined
If you get this javascript error:
Uncaught TypeError: Cannot read property '3' of undefined
It's because google updated JQuery to version 1.8 and Yii's code is not yet compatible with this version.
Change your baseUrl to:
'baseUrl'=>'//ajax.googleapis.com/ajax/libs/jquery/1.7/',
This will load the 1.7.x JQuery version not the latest 1.x.y version.
Alternative solution
If you're like me and just need to change the versions (no theming or i18), there's a simpler way to do it:
'clientScript' => array( 'scriptMap' => array( 'jquery.js' => '//ajax.googleapis.com/ajax/libs/jquery/1/jquery.js', 'jquery.min.js' => '//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js', 'jquery-ui.min.js' => '//ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js', ), ),
http://www.yiiframework.com/forum/index.php/topic/35594-latest-yii-problems-with-jquery-and-jquery-ui/page__view__findpost__p__171056
Alternative solution
'components'=>array( 'clientScript'=>array( 'packages'=>array( 'jquery'=>array( 'baseUrl'=>'//ajax.googleapis.com/ajax/libs/jquery/2.0.3/', 'js'=>array('jquery.min.js'), ), 'jquery.ui'=>array( 'baseUrl'=>'//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/', 'js'=>array('jquery-ui.min.js'), ), ), ), ... ),
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.