renderPartial, JS files, best practice?

Hi,

the site / forum search is down, so this question may have been asked before.

I’m currently working on a site where much of the content is rendered via ajax and renderPartial (also using jQuery Mobile). A user can sit through a full session on the site with only one full page load, which is login (there are a few others as well).

Now, let’s say I’m on a page, and I click a link. This link requests a new page (ajax, renderPartial) which uses CJuiSlider or similar. Yii would then do some calls to registerScript, and registerScriptFile (and maybe some to register CSS).

When a simple partial view with only a slider is returned (processOutput is enabled) the response is as follows (formatted):




<link rel="stylesheet" type="text/css" href="/assets/49c9df59/jui/css/base/jquery-ui.css" />

<script type="text/javascript" src="/assets/49c9df59/jquery.js"></script>

<div style="height:20px;" id="yw0"></div>

<script type="text/javascript" src="/assets/49c9df59/jui/js/jquery-ui.min.js"></script>

<script type="text/javascript">

/*<![CDATA[*/

    jQuery('#yw0').slider({'min':10,'max':50,'value':37});

/*]]>*/

</script>

Now, if you run the same action several times, these JS and CSS files will be returned every time. This includes jqueryUI and jquery as well. This seems lesst than ideal.

One option would be to manually include the script and CSS I know will be used in the initial page load, then blacklist them in scriptMap as follows:


'clientScript'=>array(

'class' => 'SClientScript',

'scriptMap'=>array(

'jquery.js'=>false,

'jquery.ui.js'=>false,

     'jquery.yiiactiveform.js'=>false,

),



Now, what’s the best practice here? What would you do?

There is an extension I didn’t try, but it looks interesting. And yes, working with lots of ajax in Yii may become a problem, I would like to see some core support for this in the future :)

Yeah, I’ve seen this. Will give it a spin I guess :)

I found a way to handle this easily by filtering the returned content clientside. Check http://www.eirikhoem.net/blog/2011/08/29/yii-framework-preventing-duplicate-jscss-includes-for-ajax-requests/ for more info and source.

Just use $this->renderPartial("view_name",array(),false,true);

You could run into a problem with repeating javascript code and events being called multiple times accidentally, for example.

I used an example somewhere on this forum using jquery (along with renderPartial(name, array, false, true)) to monitor scripts and unload redundancies. (Sorry, I would give credit if I could remember where)




	$.ajaxSetup({

		global: true,

		dataFilter: function(data,type){

			//  only 'text' and 'html' dataType should be filtered

			if (type && type != "html" && type != "text")

			{

				return data;

			}

	 

			var selector = 'script[src]';

	 

			// get loaded scripts from DOM the first time we execute.

			if (!$._loadedScripts) 

			{

				$._loadedScripts = {};

				$._dataHolder = $(document.createElement('div'));

 

				var loadedScripts = $(document).find(selector);

 

				//fetching scripts from the DOM

				for (var i = 0, len = loadedScripts.length; i < len; i++) 

				{

					$._loadedScripts[loadedScripts[i].src] = 1;

				}

			}

		 

			//$._dataHolder.html(data) does not work

			$._dataHolder[0].innerHTML = data;

	 

			// iterate over new scripts and remove if source is already in DOM:

			var incomingScripts = $($._dataHolder).find(selector);

			for (var i = 0, len = incomingScripts.length; i < len; i++)

			{

				

				if ($._loadedScripts[incomingScripts[i].src] && incomingScripts[i].src.indexOf('search') == -1)

				{

					$(incomingScripts[i]).remove();

				}

				else

				{

					$._loadedScripts[incomingScripts[i].src] = 1;

				}

			}

			return $._dataHolder[0].innerHTML;

		}

	});




This is actually the biggest defects in Yii, I saw some tricks and hacks here and there, but and I’ve never seen Qiang telling us something about this issue. And it’s a real issue because my application cannot be as responsive as it should, because each time we render partial through ajax it is downloading the same libraries again and again, more over I could noticed in chrome network inspector, “someone” is adding a random parameter to libraries, like jquery.js?_23423423 so it can be cached at all :-(, does somebody know something about it??