Closed mtorres0612 closed 8 years ago
+1. Very low performance on any animated transitional behaviour
@mtorres0612 Have a look here #8218 and here https://github.com/angular/material/issues/864#issuecomment-200325064
This works wonders on my side for performance problems.
Try to disable animations aswell as ripple effects.
They can be disabled on the root element
<body md-no-ink>
@berndvdveen - thanks for the info. found any workaround on this? @graphefruit - thank you for the information! In line with this, what am I expecting? a 100% lag-free AM website in IE11?
If in that case yes, then here are the details of my test:
What else should I apply?
Thank you in advance guys.
@mtorres0612 100% lag-free? I don't know, try it and you'll see. I reduced my load times from 11 seconds to 4-5 seconds on page navigation in my cordova-app on WP8.
With this fixes you disable all transitions (which I disabled in this CSS, need to be changed in RC-4 because of private classes). Also you disable all ripple-effects which is causing terrible performance problems. Transitions you can find with the Google-Chrome debugger "Animations".
For sure you'll get performance, and thats what you want right?
Update:
Also make sure you decimate watchers (one-time-bindings) and disable the debug-information: $debugInfo
With this line you cant access the scope via JavaScript angular.element(document).scope()
This takes lot of times but will pay.
@mtorres0612 Here is my CSS fix, also box-shadows remove improving the performance drastically, because the box-shadows need to be rerenderd. If you want box-shadows take borders. This animations don't contain all elements maybe you need to find some more alone.
/*
******************************************
******************************************
Disable animations
******************************************
******************************************
*/
/** disable transitions and animations for tab-contents**/
md-tab-content.md-right:not(.md-active) {
animation: none;
-webkit-animation: none;
}
md-tab-content.md-left:not(.md-active) {
animation: none;
-webkit-animation: none;
}
md-tab-content.md-left:not(.md-active) * {
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
md-tab-content.md-right:not(.md-active) * {
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
.md-tab {
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
/**disable slider animation for thumbs **/
md-slider .md-focus-thumb {
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
animation: none !important;
-webkit-animation: none !important;
}
md-slider ._md-thumb{
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
md-option{
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
/*Disable transition for opening menu.*/
/**disable on dialogs**/
md-dialog._md-transition-out {
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
md-dialog._md-transition-in {
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
/**Disable on ripple buttons**/
.md-ripple.md-ripple-placed {
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
.md-ripple-container, .md-ripple-placed {
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
/**Disable checkbox **/
md-checkbox ._md-icon {
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
md-tabs-wrapper md-next-button, md-tabs-wrapper md-prev-button
{
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
md-pagination-wrapper {
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
._md-subheader-wrapper:not(.md-sticky-no-effect) {
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
._md-sticky-clone[sticky-state=active]:not(.md-sticky-no-effect) ._md-subheader-inner {
-webkit-animation: none !important;
animation: none !important;
}
/**Disable on all other buttons**/
.md-button {
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
/**Disable fading labels**/
md-input-container label {
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
/** Disable slider animations**/
md-slider ._md-thumb-container, ._md-focus-ring, ._md-track-fill, ._md-thumb {
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
md-input-container .md-char-counter, md-input-container .md-input-message-animation {
transition: none !important;
}
/* Disable dropdown animations*/
md-select-menu {
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
md-select-menu md-content {
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
._md-select-menu-container._md-leave {
transition: none !important;
transition-duration: 0ms !important;
transition-delay: 0ms !important;
}
md-tab-content {
-webkit-transition: none !important;
-moz-transition: none !important;
-ms-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
md-ink-bar.md-right {
-webkit-transition: none !important;
-moz-transition: none !important;
-ms-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
md-ink-bar.md-left {
-webkit-transition: none !important;
-moz-transition: none !important;
-ms-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
md-tab-content.md-right {
-webkit-transition: none !important;
-moz-transition: none !important;
-ms-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
md-tab-content.md-left {
-webkit-transition: none !important;
-moz-transition: none !important;
-ms-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
/*
******************************************
******************************************
Disable box shadows
******************************************
******************************************
*/
md-card {
border: 1px solid rgba(0, 0, 0, .14) !important;
box-shadow: none !important;
-webkit-box-shadow: none !important;
-moz-box-shadow: none !important;
}
md-dialog {
border: 1px solid rgba(0, 0, 0, .14) !important;
box-shadow: none !important;
-webkit-box-shadow: none !important;
-moz-box-shadow: none !important;
}
md-select-menu {
border: 1px solid rgba(0, 0, 0, .14) !important;
box-shadow: none !important;
-webkit-box-shadow: none !important;
-moz-box-shadow: none !important;
}
.md-button.md-raised {
border: 1px solid rgba(0, 0, 0, .14) !important;
box-shadow: none !important;
-webkit-box-shadow: none !important;
-moz-box-shadow: none !important;
}
md-toast .md-toast-content {
/**no border needed here**/
box-shadow: none !important;
-webkit-box-shadow: none !important;
-moz-box-shadow: none !important;
}
@graphefruit - sorry for the very late reply. I was given other tasks that's why I failed to respond swiftly. Anyway, thank you for your information on this! Will test it immediately with my application. Will let you know the status of this the soonest.
Cheers
+1
@graphefruit - again, sorry for the long wait. Finally! I've tested again my application after adding above CSS tweaks. Noticeable results:
UI:
Performance:
DEMO:
Credits to you @graphefruit on this one. What a great tweak.
While this is great, still hoping that AM fully performs normally in IE11, just as the way it behaves in Chrome and Firefox. IE sucks, says my mentor years ago.
Cheers,
@mtorres0612 Your welcome, I'm glad it helped out. Some more points here:
Did you overwrote $MD_THEME_CSS
aswell with: $provide.constant('$MD_THEME_CSS', '');
And copy the content into an own stylesheet and include it?
Did you also disable the debugInfo?
Also track your watchers and try to reduce them (PS: This is not working if you're disabling the debug information $compileProvider.debugInfoEnabled(true);
)
var logWatches = function () {
setInterval(function () {
(function () {
var root = angular.element(document.getElementsByTagName('body'));
var watchers = [];
var f = function (element) {
angular.forEach(['$scope', '$isolateScope'], function (scopeProperty) {
if (element.data() && element.data().hasOwnProperty(scopeProperty)) {
angular.forEach(element.data()[scopeProperty].$$watchers, function (watcher) {
watchers.push(watcher);
});
}
});
angular.forEach(element.children(), function (childElement) {
f(angular.element(childElement));
});
};
f(root);
// Remove duplicate watchers
var watchersWithoutDuplicates = [];
angular.forEach(watchers, function (item) {
if (watchersWithoutDuplicates.indexOf(item) < 0) {
watchersWithoutDuplicates.push(item);
}
});
console.log("Watcher:" + watchersWithoutDuplicates.length);
})();
}, 1000);
}
If you want to know what is realy watched have a look on watchersWithoutDuplicates
Also it looks like in your last demo that some ripple/animation effects are still in use. If you want to get rid of them, install chrome and track down the animations. Have a look for it here: https://www.youtube.com/watch?v=U9xfYbKxosI
Update: Also use one-time-bindins in your ng-repeat, the trick is to set your repeat variable to undefined, and define an ng-if. The undefined doesn't dismiss the watcher, when the variable is out of the undefined state, the watcher gets destroyed.
ng-if="::(array!=undefined?true:undefined)" ng-repeat="obj in ::array"
If you cant use a one-time-binding in your ng-repeat, do it below in your bindings
<div>{{::value}}</div>
Also if you got large sets to render use virtual-repeat instead of normal ng-repeat.
If needed we can do a short hangout cast aswell.
Greetings Graphefruit
@graphefruit - hi! sorry for the year-long response, just busy 9gagging (kidding). Thank you for the information. I won't be providing screencasts since it is hard to illustrate the changes just by showing gifs (in this state).
$provide.constant('$MD_THEME_CSS', '');
. Also manually added the styles removed in the process$compileProvider.debugInfoEnabled(false);
Observations/Results:
Thoughts:
Again, thank you @graphefruit for your efforts to accommodate inquiries from a newbie.
Cheers,
@ThomasBurleson @crisbeto - Thank you for acknowledging this one :+1:
@mtorres0612 Your welcome, glad I can help. After I'm still digging for performance I found some more points:
setInterval
,setTimeout
made less promise-calls and speed up.angular.js
to see which one triggers self.defer = function(fn, delay) {
var timeoutId;
outstandingRequestCount++;
timeoutId = setTimeout(function() {
delete pendingDeferIds[timeoutId];
completeOutstandingRequest(fn);
}, delay || 0);
pendingDeferIds[timeoutId] = true;
return timeoutId;
};
$httpProvider.useApplyAsync(true);
https://docs.angularjs.org/api/ng/provider/$httpProvider.md-button {
border-radius:0px!important;
}
.md-toast-content {
border-radius: 0px !important;
md-dialog {
border-radius: 0px !important;
}
md-card {
border-radius:0px;
}
Repaint: Specally IE has repaint problems. Your JavaScript can affect this aswell.
So maybe you force the layout to repaint all day long (if you set them or get them) e.g. repaint
There are 20 more articles for position:fixed
etc.
Greetings
PS: Did you found some other things aswell? After you said you came down from 30% to 5-10%?
@graphefruit - thank you for this wonderful information!
Here's a quick feedback of how I implemented the 4 items you mentioned:
BEFORE:
self.defer = function(fn, delay) {
var timeoutId;
outstandingRequestCount++;
timeoutId = setTimeout(function() {
delete pendingDeferIds[timeoutId];
completeOutstandingRequest(fn);
}, delay || 0);//EXISTING
pendingDeferIds[timeoutId] = true;
return timeoutId;
};
AFTER:
self.defer = function (fn, delay) {
var timeoutId;
outstandingRequestCount++;
timeoutId = requestAnimationFrame(repeatOften(timeoutId, fn));//MODIFIED; INSIDE repeatOften ARE THE 2 STATEMENTS INSIDE SETTIMEOUT BEFORE
pendingDeferIds[timeoutId] = true;
return timeoutId;
};
RESULTS:
($httpProvider.useApplyAsync)
played a significant role here, for meTHOUGHTS:
<div>
is adjusting its height upon switching Tabs@graphefruit - again thank you for this. Big fan here so I've been checking this asap on my wee time
Cheers,
@crisbeto - next week, let's discuss how to get the IE perf improvements into ngM1 for v1.1.0.
Hello @ThomasBurleson if I can help you here just give me a bump.
@graphefruit - can you email with direct message thomasburleson@gmail.com. I have some ideas to suggest...
Hi,
May I know the current status of this? Just for information purposes.
I'm thankful my project has been deferred, for a while. Not sure when it will commence, but much better if the application will be ready/stable/cross-browser compatible.
Thank you in advance! Happy to be part of this masterpiece :)
Cheers,
Hi @mtorres0612 , My actual understanding is that there will be a documentation and small code fixes (ripple effect e.g.) The user needs to insert this data in his app/website himself then. Have a look here: https://github.com/angular/material/commit/ea62bc2de4dc09e0d7095b6f96d0746d20baa14a
Tab performance has been significantly improved. Fixed.
Hi @ThomasBurleson ,
My conclusion was that the main problem at least in my applications are the layout calculations. Somehow, ie11 is overwhelmed by the css of angular material. Even if you make a md-list of 40 items with icons inside them where a click on the icon opens a md-dialog with a hello world string, it will be slow. I am not sure that in the scope of angular material 1 there is something which can be done, but hope that this may be addressed in material 2. Another option would be that microsoft will release a better html engine which will be on the scale of webkit but i am not really optimistic :-)
Thanks a lot, David
@david-gang I would really appreciate a codepen/demo of IE being slow, otherwise it's hard to pinpoint the issue. We decided to close this because the only instance I've found IE to be really slow was on 1.0.9 and a certain config of md-tabs, but that was addressed by @topherfangio and isn't an issue in 1.1.
Hi,
Sure :-)
http://codepen.io/david-gang/pen/RRJjxG
If you open this in ie11 and click on the icons you willl see slowness. This is basically a md-list with not too much content.
Thanks, David
Alright, this should be easier to benchmark. I'll reopen it.
Just a side notice: I found out that the CSS files realy had more then 55k lines (material + theme) Thats realy a huge factor for the IE11 engine. After I test stripped the CSS down to actually 4k lines (painly road), even my android and iOS app are starting even more faster. Sadly the rendering process for 20 list-items still need more then 2 seconds on a Windows Phone 10.
@crisbeto - let's open a new issue with David's codepen. @graphefruit - please submit a new issue with your recent comment/issue. I think the mdList may need an overhaul.
I've overhauled our application using world's finest Angular Material. It works fast on Chrome and Firefox.
Below is the gif which illustrates the behavior of our application if run in Chrome:
Below is the gif which illustrates the behavior of our application if run in IE 11:
Issue Details:
Angular Versions / Relevant Script used:
Additional Information: