Yii: render process - performance

I would like to know if someone could explain me what happens exactly when we call a "render".
Let me introduce you my problem:
This is my action:
public function actionIndex()
{
$new_user = new CustomUser;
$new_person = new CustomPerson;
$tab_person = $this->getListPerson();
$this->render('index',array('tab'=>$tab_person,
'user'=>$new_user,
'person'=>$new_person));
}
And this is my index view:
.
.
.
</p> <br/>
<?php $this->renderPartial('person-form', array('person'=>$person,
'user' =>$user ));
?>
So my problem is that the loading page time is very long.
If I put a
die("die");
just befor the render in my actionIndex or at the end of my view (after the renderPartial) the execution is very fast. I'll see "die"(and my index page if I put the statement at the end of it) after 0.3 second. But if I put it after my render or I don't put it, then my page is going to be loaded correctly but in 4-5 secondes.
So I think I didn't understand very well what happens after a render. I repeat if I stop the execution at the end of my view page it's very fast, but at the end of my action it's very slow. I thought about js and css, but after looking into I didn't see anything and Firebug shows me that these files are loaded very quickly.
And if I put the "die()" statment at the end of my layout main.php it's very fast as well.
So I know that render will show the page and wrap it in the layout but is there another thing which maybe could make the action very slow?
If anybody has an idea about my problem I would be very grateful.
Sorry if I did mistakes, English is not my mothertongue.
Thank you for reading me, have a good day :)
Michaƫl

From my understanding it should not load slower. Maybe you have something else loaded on the page.
Try enabling the logs on the screen: http://www.yiiframework.com/wiki/58/sql-logging-and-profiling-in-firebug-yii-1-1/ . See if there is anything executed after the view is rendered.

One reason that this may look confusing, is that it may not be the "rendering" that is slow. It may be that loading models and relations are slow, but by default they are lazy loaded. This means the DB won't be queried until the code that asks for them is hit, which is often in the view.
This might explain why the rendering is slow. So like others said, you need to enable logging, either in the page or log to firebug. You can then check for any slow queries or components.

Related

How to execute code after returning view in Yii2

Normally when you call a page in Yii2, pretty much the last thing that happens is that the view is rendered to the end user's screen. I need to run code after this that might take a second or two and I don't want to have the user wait.
My first thought was to set a global event that gets called after the response is set so I added this to a method:
if (condition is met) {
Yii::$app->on(yii\web\Response::EVENT_AFTER_SEND, function ($event) {
// do stuff
});
}
But this doesn't seem to ever get called. Does anyone know what I'm doing wrong or have a better idea on how to solve this problem? I just need to run code after the view is rendered. I don't really care how it happens.

Vote for comments in posts function with Codeigniter and routing

I am trying to create posts with comments with CodeIgniter and I am trying to add voting for the comments with + and -.
But my problem is not actually this functionallity but more exactly creating the link and the method in controller/model for this.
I understand that there is some kind of link to methods.
If I have something like this:
public function like() {
echo 'Test Function';
}
and when I create link like this one sitename.com/posts/first-post/like theoritecally I will see blank page with "Test Function" text (and of course if I write proper routing rule but I cannor for now).
I can see a blank page with this working echo 'Test Function', but does this mean I have to load every methods and views for the entire page if I want to display the entire webpage with all the elements? I think that I mistake something very serious here but I don't know what.
The example with the "Create news" tutorial in ellislab.com didnt help me. They show something similar I think with /create/ section in the URL and create() methods.
If I have many links with functionallities do I have to add new routing rules for all of them? I really tried to search in Google and everywhere but I didnt find anything related.
Sorry for this lame question.
You need to use Ajax call and on callback you have to increase or decrease the count. For creating a link , once page is loading render the data and provided the default link like
for + http://<site.com>/<controller>/like?totalLike=<36>
for - http://<site.com>/<controller>/unlike?totalunLike=<3>
Once user will click + link then by using Ajax, call the controller method link/unlike and increase or decrease the count and repopulate the link again with fresh counter.
Hope it will resolve your problem.

Performance issue in backbone template

I am having a performance issue with backbone template.
The situation is I have collection of model, each model have a field called 'isSelected'.
I need to render this collection with a template for each individual model. The 'isSelected' field is used for setting the checkbox in the template.
For the sake of discussion, the template is as following.
<div class='thumbnail'>
<input class='checkbox' type='checkbox' {[ if (isSelected) { ]} checked='checked'{[ } ]}
</div>
When I need to make the checkbox all selected, I will update the field to true for each model in the collection.
The code I used is
this.collection.each(function(e) {
e.set("isSelected", true);
});
However, this way is very slow, for a collection contains 25 items, it will take almost 10 sec to make all checkbox 'checked'.
I am expecting that it should least than 1 sec, if i use plain jquery.
Is there any problems with this approach? what's the best approach for this kind problem?
Why don't you set isSelected to true as default in the model? That way you don't have to loop through the collection to set each of them to true.
It's hard to tell what's taking up all the processing time with the amount of code you posted. My first guess would be the render function is being called multiple times. Creating and destroying templates kills performance. If you hard more code posted it might be easy to spot any problem areas.
You should render all of the HTML nodes that could possibility be need. After they are rendered save a jquery selector and use that to toggle the selected.
Most of the time it isn't JS or Backbone that is the bottleneck. It's that JavaScript is triggering the DOM, CSS or reflows constituently and the browser is doing way too much work.
I'm building a PerfView for for backbone. It can render a collection with 1,000,000 models and scroll at 120FPS on chrome. The code is on Github at: https://github.com/puppybits/BackboneJS-PerfView. There's a lot of optimizations in there and comments in the code. One of the techniques in there is sure to solve your issue.

Refreshing Partial View in MVC 3

I have a partial view that I have included on my _Layout.cshtml. It simply has a javascript function that changes an image based on the state of my system. I don't need to reload any data, I don't need to go to the code of the controller for anything, I simply need to reload that partial view.
I tried many of the examples that I found here but couldn't get any of them to work. I felt as if they were too complex for what I was doing anyway. Any guidance would be appreciated.
Thanks,
Steve
If the partial is loaded into the layout directly then there's no straightforward way to refresh it, because it's basically a part of the complete rendered page.
Your best bet is to render the partial using $.load or whatever equivalent you have available by hitting a controller method and rendering the result into a container (like a div). You would have to do this within a script that is loaded with the layout itself, by observing document.ready or something like that. Once you have that in place then it's trivial to keep reloading or refreshing the contents by hitting the controller method as many times as you need. For example in jQuery:
$(document).ready(function () {
RefreshPartial();
window.setInterval(RefreshPartial, 10000);
});
function RefreshPartial() {
$('#container').load('/some/controller/endpoint', {parameters});
}
This will call the controller method, and set the inner contents of the element identified with #container. You can call RefreshPartial as many times as you want.
Partial views only exist on the server. The only way to "refresh" the partial is to go back to the server to get it again.
Obviously, you must be doing something in the partial that needs refreshing. Whatever that is, should be callable from javascript to do the refresh.

Pros and cons of AJAX-loaded content

It's pretty nice to sort a dataset by a number of filters and get the results shown instantly, right?
My solution to do this would be to POST the "filter" (read forms) parameters to a page called dataset.php, which returns the appropriate dataset in compiled HTML, that can be loaded straight into my page.
So, besides this being a total no-no for SEO and for people having deactivated Javascript, It appears as a quite good solution to easily build on in the future.
However, I have yet not the experience to consider it a good or bad overall solution. What should be our concerns with an AJAX-fetched dataset?
So, besides this being a total no-no for SEO and for people having deactivated Javascript, It appears as a quite good solution to easily build on in the future.
Not entirely true, there are solutions out there like jQuery Ajaxy which enable AJAX content with History tracking while remaining SEO and javascript disabled friendly. You can see this in action on my own site Balupton.com with evidence it's still SEO friendly here.
However, I have yet not the experience to consider it a good or bad overall solution. What should be our concerns with an AJAX-fetched dataset?
Having Ajax loaded content is great for the user experience it's fast quick and just nice to look at. If you don't have history tracking then it can be quite confusing especially if you are using ajax loaded content for things like pages, rather than just sidebar content - as then you break away from consistency users are experienced with. Another caveat is Google Analytics tracking for the Ajax pages. These shortcomings, those you've already mentioned as well as some others mentioned elsewhere are all quite difficult problems.
jQuery Ajaxy (as mentioned before) provides a nice high level solution for nearly all the problems, but can be a big learning curve if you haven't worked with Controller architecture yet but most people get it rather quickly.
For instance, to enable history trackable ajax content for changing a set of results using jQuery Ajaxy, you don't actually need any server side changes. You could do something like this at the bottom of your page: $('#results ul.pages li.page a').addClass('ajaxy ajaxy-resultset').ajaxify();
Then setup a Ajaxy controller like so to fetch just the content we want from the response:
'resultset': {
selector: '.ajaxy-resultset',
request: function(){
// Hide Content
$result.stop(true,true).fadeOut(400);
// Return true
return true;
},
response: function(){
// Prepare
var Ajaxy = $.Ajaxy; var data = this.State.Response.data; var state = this.state;
// Show Content
var Action = this;
var newResultContent = $(data.content).find('#result').html();
$result.html(newResultContent).fadeIn(400,function(){
Action.documentReady($result);
});
// Return true
return true;
}
}
And that's all there is too it, with most of the above being just copy and pasted code from the demonstration page. Of course this isn't ideal as we return the entire page in our Ajax responses, but this would have to happen anyway. You can always upgrade the script a bit more, and make it so on the server side you check for the XHR header, and if that is set (then we are an ajax request) so just render the results part rather than everything.
You already named the 2 big ones. Now all you need to do is make sure all the functionality works without javascript (reload the page with the requested dataset), and use AJAX to improve it (load the requested dataset without reloading the page).
This largely depends on the context. In some cases people today may expect the results to be delivered instantly without the page refreshing itself. It does also improve overall user-experience - again, this largely depends on the context.
However, it does also have its pitfalls. Would the user have a need to return to the previous pages after the ajax content was delivered? Since this may not be as simple as pressing the Back button in the browser.

Resources