I'm currently updating an angularJS 1 app to angular 4 and have stumbled upon a huge performance loss in angular 4 compared to angular 1. Imagine this template:
<dt *ngIf="auftrag?.project?.termin.aProperty">Title of aProperty</dt>
<dd *ngIf="auftrag?.project?.termin.aProperty">{{order?.project?.termin?.aProperty}}</dd>
There are 56 properties on the "order" object that should be displayed when they are set and not displayed at all when they are not set. So I have at least 112 ngIf conditions on 112 elements that need to be inserted into the DOM separately, plus some additional DOM elements and some *ngFor uses around it to make it look good.
In the old angular1 app this takes 60ms of raw scripting time on my machine to render (according to Chrome timeline).
In Angular 4 RC5 this takes around 250ms of raw scripting time (give or take a few more or less) and around 180ms after compiling it with AOT. Whats worse is, that I have a noticable delay to render this template on an iPhone while the angular 1 version feels like its instantaneous.
The angular4 component is already using OnPush changedetection. There is no difference in performance when I use angular 2.4.10.
In Angular1 I used "ng-show" as a performance improvement on every element. The angular2 equivalent in setting a "hidden" class when the condition is false doesn't change much in the scripting time (like so: < dt [class.hidden]="!order.cProperty>...< /dt>)
When I look into Chrome timeline of my angular 4 app, most of the time is spent in ZoneTask.invoke but it has almost no self-time. In fact there is almost no task which as any self-time. I don't really know whats going on here.
Where is the time spent? How can I make it faster?
Related
I'm in the need of an Excel like grid in an attempt to convert an "application" written in Google Calc to a real application. I've got one implementation using Vaadin, but it (also) suffers from a long page construction. The screenshot below uses a CSS flex grid with individual divs, and given 6 weeks, there are over 5000 individual divs.
Constructing this page takes over 20 seconds, not something users will be happy about. I'm working on a version based on a table, but it does not seem to improve much. In the end the same amount of cells need to be constructed, whether they are DIVs or TDs does not seem to matter much.
Is there a way to construct such a grid in a more speedy way? I'm more than happy to solve "where did the user click?" on the server side. To be aware of: besides the number of cells themselves, each also has specific content, so just getting a grid shown is not enough.
Each component (div, or something else) is managed by the server. So when you have 5000 of them it's quite slow. You need to reduce the number of components managed by the server.
I can't give you a better answer since I don't know the requirements. But the idea is to try to combine some elements.
You have an example of a table generated ( instead of each element one by one) here: https://cookbook.vaadin.com/grid-details-table.
You can also create or own component. There is also a paid add-on: spreadsheet which seems to fit your needs. It's still in preview: https://vaadin.com/roadmap
The problem here is the complexity of the UI itself. Rendering 5000+ cells will be slow what ever method you use and what ever framework you use. There will be big amount of elements in the DOM and you need to load also lot of data upfront. And as you see the result is huge, and it wont fit most screens. So I would recommend further design of the UI. Is it really necessary to show all the weeks at once? Your UI's complexity will already reduce a lot if you show only one week at the time and add buttons to browse the weeks forwards and backwards. But even with that optimization you will have lot of columns. I would consider adding another browsing direction by day. Further knowledge of the actual purpose of the UI will naturally give more insight how to develop it further.
I am developing an aframe project on my MacBook pro, late 2013. When running the project, the fan of my computer always spins fast, regardless which browser I use (firefox, safari, chrome) and the project size (also happens with a project just containing a simple a-box).
aframe-stats show me that my project (1028244 vertices, 342748 faces) still runs with 20 fps.
Is it somehow possible to limit the frame rate to 10fps in order to keep my computer quite? Or any other way to limit the flop-consumption of the aframe project? I already tried a native approach with sudo cputhrottle plugin-container 10 but that did not just throttle the aframe-renderer but the whole firefox browser. Can I pull the break somewhere in the JavaScript or the Browser settings?
It's difficult to say without your project code. Large data sets will simply crank out even a high spec macbook pro. I have found it helpful to pause any rendering whenever possible to quiet the users' machines.
I personally removed automated next animation frame rendering in favor of waiting for controls and objects to change.
For example:
this.controls.addEventListener( 'change', function(e){ addToRenderStack(); });
A simple function addtorenderstack puts in a new value in a list for a render, with the expectation that the render will occur at some point in the future and not right away. the list can also be used to log who requested the render in the call stack, and narrow down performance hogs.
addtorenderstack places a render request in a list. In the requestanimationframe loop, if the list has any length, a render is called on the scene. The stack is immediately cleared rather than processed one by one. If controls or animations continue to make render requests, the list will have a length again and request animationframe will process them in the same way with another render.
In this way, the code only renders when absolutely required. This saved me much grinding on framerate and the fans only come on during intensive operations and then shutdown when its complete, much like a typical 3d game experience.
Your mileage may vary depending on what's happening in your app. I work in engineering so often the view of the 3d world is stopped as an engineer examines or shows a model.
In brief: I've got a page with KO-code that operates absolutely cool in Google Chrome, Firefox, Safari, etc. But the performance is gone in Internet Explorer. I tried IE10, IE11. It takes from 10 to 25 seconds to render about 150 rows.
Details: There page represents a work queue for users, where their tasks are shown. The requirement is not to use any paging on that page. Each row of the table has at least a dozen of variants to display (links, buttons, inputs, css styling, handling user events, custom js plugins, etc.). The average number of rows on prod is 100-200+. User is able to apply different filters and sortings.
Things I've already tried:
reduced the number of computed properties (changed to pureComputed, where possible)
reduced the number of using the template, if and ifnot bindings (according to profiler they are the most time consuming task) - I use the visible, where possible
tried to use the knockout-fast-foreach custom binding (https://github.com/brianmhunt/knockout-fast-foreach)
profiled the code with IE and Chrome tools to eliminate the memory leaks
profiled the code with ko.bindingReport.js (https://gist.github.com/kamranayub/65399fa247a6c182bc65)
The approaches specifed above tuned the code (according to ko.bindingReport.js) almost two times faster in Chrome. But IE is still too slow - about 10 seconds for rendering.
Chrome:
Internet Explorer:
Folks, any ideas?
"The table binding provides a fast method for displaying tables of data using Knockout. table is about ten times faster than nested foreach bindings."
This claims to be 10x faster.
https://github.com/mbest/knockout-table
You reduced the amount of computed observables, but did you also reduce the amount of observables? I'm not seeing a lof of editable fields. The ones that are not being edited on the page probably don't need to be an observable? This has boosted my performance quite a lot of times.
All in the title.
I want to do whatever will be fastest.... I would think that 5 CSS generated circles would load faster than having to load an external image, whether its a sprite or not... but I'm looking for somebody who's more educated to offer an opinion!
The circles (to scale, presently generated with CSS):
http://puu.sh/3VZHO.png
First to answer your question as to which is faster... The CSS solution is quicker. But why?
The first reason CSS is faster is because of HTTP Requests.
Every time you have, let's call it an object, that object has to be loaded from the server. To do this the browser must send an HTTP request to the server for said file, the server has to check if you have permissions to access said file, if you do, it retrieves it's location, and sends it back to the browser. This happens multiple times and takes hundredths of a second to perform. Seems pretty quick, but the more of these you have to perform the slower your site will become.
CSS is fastest because the CSS for those 5 circles is contained inside one file style.css
The multi-circle image sprite is slower than CSS because now, not only does the server have to send you style sheet for the rest of the site, it also has to send the your image sprite. Think of this as ordering a quantity of 2 of the exact same thing from amazon from the same seller. Amazon will package both items into one big box because its cheaper. Where ever possible you want to piggy back things like this because it's "cheaper" on load times.
As a further explanation, if you were to load the 5 circles all as separate graphics, 5 individual jpgs/pngs/gifs etc. This would take EVEN longer because it would have to perform 6 HTTP Request as opposed to 2, or even 1 (the css solution).
The second reason CSS is faster is because of shear file-size.
Let's assume the CSS for your circles has 8 lines of CSS code for each circle, that's 40 total lines. That represents just bytes of information compared a couple kilo bytes. To put that better into perspective you are talking 100-400 bytes compared to 4,000-8,000 bytes.
The clear winner? CSS
Other Considerations
That said... There are other factors which should weight in on your decision. Not all browsers support border-radius. See this link for details on what does support border-radius: Can I Use
Since IE8 and below does not support border-radius anyone using IE8 or earlier will render your circles as boxes instead. You can help this along by using something like Modernizr to fill in some of those gaps. But now, even if you use a build of Modernizr that helps only border-radius, you've added 7+kb of data and an extra HTTP Request with this file, which sort of defeats your purpose. That is of course unless there are other things you can use Modernizr for other than border-radius, or if you have a lot more utilizing border-radius than just those 5 circles. Suddenly the extra data and HTTP request can be easily justified.
Ultimately your decision should be based on your target audience. What browser are they most likely to be using, if they are mostly using IE9+, Chrome, Firefox etc. Then go for it. If a significant number of your visitors are IE8 and below you should consider providing a fallback. For example using that image sprite for IE8 and below only.
It all depends also in your needs.
I think the border-radius is not rendered correctly in old IE versions, so...maybe the image sprite is the best solution. But I repeat it all depends. Maybe your clients are in a place where internet is slow (css is best) or maybe they won't update their IE and are stuck in IE6 or 7 (sprites).
You could use both, using one stylesheet for IE with sprites and one for css border-radius.
Check the paint times via the chrome dev tools.
Should give you a good idea.
B
When using an application developed with backbone.js Chrome freezes for about 7-10 seconds when adding to the DOM the content of a large document that has been retrieved with an AJAX call. Chrome's event timeline shows that the main issue is a single 'layout' event that takes about 6-8 seconds (times measured in a modern MB Air if that matters)
The content being loaded is about 800kbs of uncompressed HTML, 15000 DOM nodes, memory usage after the content is loaded is about to 30-35 Mbs; it's a large document but such a long freeze just doesn't feel right.
is such a large "layout" time to be expected for a document like that, or is this a sign of other issues? (like too complex CSS rules, bad HTML structure, etc.)
what other factors besides document size may have an impact in the performance of the 'layout' event?
besides the obvious and probably right solution of breaking the content in pieces, is there any trick that can be done to make it easier for the browser to compute the layout event? (I am thinking in something like placing the monster content inside an iframe or a div with fixed positioning, or avoiding specific CSS features inside the content)