lots of backbone views - performance issues? - javascript

tl;dr: I wonder if having lots (100+ for the moment, potentially up to 1000/2000 or more) of backbone views (as a cell of a table) is too heavy or not
The project I'm working on revolves around a planning view. There one row per user that covers 6 hours of a day, each hour splitted in 4 slots of 15mn. This planning is used to add "reservations" when clicking on a slot, and should handle hovering of the correct slots, and also handle when it is NOT possible to make a reservation - ie. prevent user click on an "unavailable" slot.
There is many reasons why a slot can't be clicked on: the user is not available at this time, or the user is in a reservation; or the app needs to "force" a delay slot between two reservations. Reservations (a div) are rendered in a slot (a cell of a table), and by toying with dimensions, hovers the right number of slots.
All this screen is handled with backbone. So For each slot I'm hovering on, I need to check wether I can do a reservation here or not. As of this moment, I use this by toying with the data attributes on the slots : when a reservation object is added, the slots covered are "enhanced with (among others) the reservation object (the backbone view object).
But in some cases I don't quite have a grasp on now, it mixes up, and when the reservation view is removed, the slots are not "cleaned up" : the previous class is not reset correctly. It is probably something I've done wrong or badly, but this is only going to get heavier; I think I should use another class of Backbone views here, but I'm afraid the number of slots and thereof of views objects will be high and cause performance issue. I don't know mush about js perf so I'd like to have some feedback before jumping on that train. Any other advice on how to do this would be quite welcomed too.
Thanks for your time. If this is not clear enough, tell me, I'll try and rephrase it.

We have a pretty complex backbone.js app with potentially thousands of views at a given time. Our bottlenecks are mostly in memory leaks from views that have not been properly removed or eventdriven rendering that re-renders views needlessly. That said, the actual number of views doesn't seem to affect much. Backbone views are pretty lightweight, so as long as you don't have too much events bound to them, it's not that big of a problem.
You might run into performance issues, but the views probably isn't the problem.
What you might want to do though, if you do use thousands of views is to stash up the initial rendering into one big ´.html()´-call. You can do this by giving each view-element an id based on the view's cid and then you concatenate the view's html strings and afterwards you use setElement on each view to find its element again.

Maybe this helps a litte bit :
https://stackoverflow.com/a/7150279/1067061
btw.: i like your avatar ;)

backbone handles everything is the least performant way for the browser. If it's not fast enough you need to stop creating and destroying templates. Caching a template is almost no help at all.
Instead of calling the render function against, save out a variable to the jquery selector and when the model changes use the cached selector to update the DOM. This will give you the largest jump in performance off the bat.
$title = null,
init = function(){ $title = this.$el.find('h1'); },
onTitleChange = function(event){ $title.html(event.value) }
I'm working on a backbone view that is performant. It can render a collection with 1,000,000 models at over 120FPS. The code is up on Github. https://github.com/puppybits/BackboneJS-PerfView There are a lot of other optimizations that can be done. If you check out the PrefView it has comments on most of the optimizations.

Related

Limitation of Angular and browsers with regards to data loaded

I would like to know what is the maximum data that angular framework can handle. Say, I am displaying a chart using angular and some charting framework like chartjs. I'd like to know up to how many data can the browser display properly, with slowness, or up to when it crashes.
Your question has no simple answer, but I will try to flatten it and give a simple answer, or at least simple things to consider...
Angular (at runtime), like many other frameworks is simply JavaScript,
So let us reduce the question to "Limitation of JavaScript and browsers with regards to data loaded",
JavaScript has no upper limit of memory or storage it can handle,
I've seen JavaScript applications that require more than 15GB of RAM,
and they performed well too.
So assume data size itself is not an issue (unless your application is poorly implemented, leaking memory or just not very efficient, of course).
The main challenge as I see it, is displaying and manipulating the information
without causing unnecessary delay or unresponsiveness.
Displaying the information - let's say you have a list (or a table) containing 1,000,000 possible gifts which you then want to display for the user to select.
Adding the list items to the document one by one is tempting, but will require the browser to repaint after each addition (causing a delay or full unresponsiveness until finished), another way is adding the elements to some DOM element (denoted by N) still being kept in memory, then adding all elements corresponding the list items to the element N (still, just an in memory operation), finally adding N to the document containing the entire list - the will be a much better solution for displaying the large amount of data.
Manipulating the information - displaying is indeed not enough. you would like to move, drag, sort and filter the data being displayed. And as mentioned before, it is a bad idea removing many elements directly from DOM. You should instead remove container from the document's DOM to memory, manipulate the data in it, and then add the container right back to the document. Angular does this kind of magic for you.
(Toggling the 'display:none\block' css attribute of many elements has a similar blocking effect as I recall).
A good practice is implementing an application/page showing only the amount of data that can be processed by a human at a single glance. The rest of it should be considered in the application data-layer, in memory, and should be loaded to display given the appropriate need or request.
To conclude, you can deal with huge amounts of data as long as you provide a mechanism that efficiently filter the displayed information.
I hope it helps...
for further reading:
Slow and fast ways of adding elements to DOM
A question emphasizes the lack of memory limit used by JS
CSS display attribute performance
A good discussion about the reasons for slow DOM
About using HTML5 correctly - old but still true
Once the DOM creation procedure is understood - it much easier to display data without affecting performance / user experience

What actually makes update using React faster that regular UI update?

I have already read 10 articles about React and Virtual DOM.
I understand that virtual DOM uses the diffing algorithm and only update the UI that was changed. But I still don't understand why that is faster than updating the actual DOM.
Following is an example:
<div id="test">
Hello React!
</div>
Let's say we created a component and changed it using React. Let's say we changed the text to Hello World!
I can do the same thing using plain JS right ? document.getElementById('test').innerHTML = Hello World!
My question:
Why is React faster ? I feel like React is doing exactly same thing under the hood right ?
I feel like I am missing something fundamental here.
In your case the plain js function will be definetly faster. React is just very good for really complicated UIs. The more complicated your UI gets, you either need to write a lot code to update it or you just rebuild the whole UI on every rerender. However those DOM updates are quite slow. React allows you to completely rerender your data but actually not rerender the whole DOM but just update some parts of it.
Actually the Virtual Dom is not faster than the actual Dom , The real DOM itself is fast, it can search, remove and modify elements from the DOM tree quickly. However the layout and painting elements in html tree is slow. But React virtual DOM is not faster. The real benefit from Virtual DOM is it allows calculation the different between each changes and make make minimal changes into the HTML document.
Now why react is better when it come to manipulating the DOM?,your browser does a lot of work to update the DOM. Changing the DOM can trigger reflows and repaints; when one thing changes, the browser has to re-calculate the position of other elements in the flow of the page, and also has to do work re-drawing.
The browser has its own internal optimization to reduce the impact of DOM changes (e.g. doing repaints on the GPU, isolating some repaints on their own layers, etc), but broadly speaking, changing a few things can trigger expensive reflows and repaints.
It's common even when writing everything from scratch to build UI off the DOM, then insert it all at once (e.g. document.createElement a div and insert a whole tree under it for attaching to the main DOM), but React is engineered to watch changes and intelligently update small parts of the DOM to minimize the impact of reflows and repaints
A few reasons off the top of my head:
React uses a virtual DOM, which are just JS objects, to represent the DOM. The "current" version of the virtual DOM are objects with references to the actual DOM elements while the "next" vDOM are just objects. Objects are incredibly fast to manipulate because they are just memory changes whereas real DOM changes require expensive style layout, paint and rasterization steps.
React diffs the current vDOM against the next vDOM to produce the smallest number of changes required to make the real DOM reflect the next vDOM. This is called reconciliation. The fewer changes you make to the DOM, the faster layout calculations will be.
React batches DOM changes together so that it touches the real DOM as few times as possible. It also uses requestAnimationFrame everywhere to ensure that real DOM changes play "nicely" with the browser's layout calculation cycles.
Finally (probably React's least appreciated feature), React has increasingly sophisticated scheduling step to distinguish between low- and high-priority updates. Low priority updates are UI updates that can afford to take longer e.g. data fetched from servers whereas high-priority updates are things that the user will notice right away e.g. user input fields. Low priority updates use the very new requestIdleCalback API to ensure that they run when the browser's main thread is actually idle and that they frequently yield back to the main thread to avoid locking up the UI.
why that is faster than updating the actual DOM.
It is not faster. Explicit and controllable DOM updates are faster than anything else.
React may schedule better update graphs on sites similar to facebook but with the cost of diff processing O(D*N). On other sites React could be just a waste of CPU power.
No silver bullet here - each framework is optimal for the site it was created for initially. For others you will be lucky if particular framework is at least sub-optimal.
Real and complex Web App UIs are not using any "framework" but their own primitives: GMail, Google Docs, etc.
You might just use vanilla-js as you described:
document.getElementById('test').innerHTML = Hello World!
that's great, but super hard for medium \ big projects.
why? because react handle all your dom interaction and minmize it (as much as it could), when you would use vanilla-js most of your code would be just manipulation on the dom, extract data and insert data, with react you can put those worries aside and put all your afforts to create the best site\project.
more over, the virtual dom makes all the calculation behinde the sense, when you would try to do it manulay you have to deal with all the calculation every time (when you update an list and when you update another one), most probably from some point most of your code would be calculation about the dom updates
sound familiar? well, just for that you already got react.
Don't Repeat Yourself
if someone already done it, reuse it.
Separation Of Concerns
one part of your project should manipulate the ui, another should manipulate the logic
and the list can go on and on, but in conclusion the most important thing, vanilla-js is faster, in the end with the virtual dom and without it, you would have to use vanilla-js in the end. make your life simpler, make your code readable.
React is NOT faster then PURE Javascript.
The big difference between them is :
Pure Javascript: if you can master the Javascript language and have time to spend to find the best solution (with the lowest impact in browser performance) you definitively got an UI render system more powerful then React (because you have created a specific engine oriented to your necessity)
React: if you want to spend more time in data structure with no worries on UI update performance React (or Vue.js the future candidate for UI developing) is the best choice

How to speed up AngularJS rendering with big scopes?

I'm developping an angular app right now for my company, but I reached a point where the app became extremely slow so I tried tunning it by using onetimebind everywhere I can, track by ...but it's faster to load at first but still laggy, it is composed of a pretty much huge nested objects, I've counted the total number of objects, it starts at 680 and can go up to +6000 for normal use of the app, oh yeah I should precise that the app is generating a form and pretty much +90% of the objects in the scope belongs to an input and are updated each time the client click(radio) keyup/change(text).
It also have like 5/6 arrays composed of objects and the array gets bigger/smaller accodring to the clients choice, and that's where it gets laggy, each time I add an object to the array, it takes like a second to render it, so I tried using nested controllers thinking that if the child of an object is updated Angular will render only this child and not all the others, but somehow the app got even slower and laggier :s (it's a bit faster when I use ng-show instead of ng-if but the memory used jumps from ~50Mb to ~150Mb)
I should also precise that the form is in a wizard style, and not all the inputs are displayed at once, the number of inputs that are displayed are between 10%-20% of the total inputs
Has anyone encountred this problem before? does anyone know how to deal with big scopes?
Sad to say, but that's intrinsic of the view rendering in angular.
An update in the model triggers a potential redraw of the entire view. No matter if you have elements hidden or not. The two way data binding can really kill performances. You can consider evaluate if you need to render the view only once, in that case there are optimizations, but I'm assuming that your form change dynamically, therefore a 2 way data binding is necessary.
You can try to work around this limitation but encapsulate sub part of the entire MVC. In this way a contained controllers only update the specific view associated to that scope.
You may want to consider using react (that has as first goal to address exactly your use case)
Have a look at this blog post for a comparison of the rendering pipeline between angular and react Js.
http://www.williambrownstreet.net/blog/2014/04/faster-angularjs-rendering-angularjs-and-reactjs/

Backbone.js render performance and repaints

I'm building a backbone.js application. It has quite a few interactive calculator type forms. I need values in these forms to update live when users type values into inputs. I was thinking two approaches:
Strategies:
1) rerender the view upon each interaction using underscore templates
OR
2) render once, find every point of display in jQuery and update them on each interaction
My question: What do you think is best practice both from a maintainability point of view and from a browser performance standpoint. Minimizing repaints etc seems like a good idea to me but attaching all those listeners and pairing them to bits of the view also seems a bit yuck.
Any advice greatly appreciated,
Jack
Well, This is certainly a bit subjective question and can not be answered either way. It really depends upon the complexity of both the strategies which again depend on your app logic. Still here are a few thoughts:
You can have multiple elements sitting parallel to each other and each element has its own content (view). Depending upon logic, hide the rest of them and show only one. This avoids re-rendering of the view multiple times but yes you have to write some logic of maintaining multiple views (Hide all, show one). So this approach is fine as long as you have 2-3 views and your app needs switching between these views multiple times.
Re-painting a view may not be a costly operation depending upon how you do it. Just cache the selector and do all the changes in it and update the DOM only once which is the most common practice. So you are good if you are re-rendering a view again if it costs only one DOM operation.
From code maintainability perspective, definitely go with Strategy #1, Re-rendering of view.

Swap out views with Backbone?

I've looked around but have yet to find a great solution the the following problem:
I have a Backbone View tied to an el on the page that is a container element for what I'll call a "sidebar" in the traditional sense (for explanation's sake). This sidebar element's inner-html needs to change completely depending on the route. However, the position on the page never changes, and will always fill this container.
Now, for an initial prototype, I had a 1:1 relationship between this container and the view placed in it (I only coded up one route). Now however, said view needs to change based on the route as I've mentioned.
Being that these different views have entirely different html markup, response to events, etc... I had thought that I'd make sense to have a higher level view that'd swap in sub-views. Of course, one solution that would work would be to handle everything in the same view, but the necessary logic would be cumbersome (and pretty damn unwieldy).
Currently, here's what I'm thinking (and have partially implemented):
Have a top-level view for this page element.
Depending on the route, swap in the necessary sub-view.
These subviews are rendered with dust.js, where the .html template for just this component on the page is lazy-loaded via AJAX, compiled, and cached. Subsequent renders just consist of calling the cached "compiled" function with a new context.
Additionally, I was going to initialize and cache each of the subview Views within the top-level View, such that I'm only instantiating, setting up event handlers, etc.. once.
Then, depending on the route, look up the associated subview View (cached), and swap it in in-place of the current view.
Now, as I've mentioned, I have this mostly coded up and... semi-working. However, what I'm struggling with is how to have each of these subviews exist independently and handle the swapping, but keep all of the event handlers and current state to continuing to live whether the component is currently displayed or not.
Basically:
How to avoid completely destroying / re-instantiating subviews each time they're required. Maybe this operation isn't as expensive as I'm thinking it is and I should simply do the latter.
Being that the top-level View (the "manager", if you will) is tied to the container $el, how to swap in the subviews.
I'm sure there's a simple, elegant solution. I just haven't found it yet, unfortunately.
As far as point 1 is concerned I don't think it is too expensive to let the view be created each time.
For point 2 - I would recommend using Backbone.Marionette https://github.com/derickbailey/backbone.marionette. It has the concept of a Layout which lets you define different regions of your app and render/manage them individually.
I would recommend Backbone.Marionette not just for point 2 but for the way in which it allows you to manage interaction is in my opinion much better than standard Backbone.

Categories

Resources