The Now Platform® Washington DC release is live. Watch now!

Help
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
jesseadams
ServiceNow Employee
ServiceNow Employee

Service Portal was created to provide a streamlined, responsive user experience across different browsers and devices. It leverages modern web technologies like AngularJS to create a beautiful interactive experience for your users. But if you're using Internet Explorer 11 as your standard browser, you may have seen that this does not always work out as planned.

IE11, unfortunately, does not always manage memory very well — especially when using modern web technology. There are several known bugs in IE11 that cause memory leaks, and these memory leaks lead to slowness in your browser, ultimately causing your browser to crash when you open a page. I think we can all agree there is no worse user experience than your browser crashing when you open a page. We're going to look at why these issues happen and what you can do in your own Service Portal to minimize the impact of these issues.

So first, let's start with the ugly truth. IE11 has known memory leak bugs. If you're curious about what those are and what is published about them, this discussion with maxarderius is a good place to start: https://community.servicenow.com/thread/224646

The unfortunate reality is that Microsoft no longer supports IE11 aside from security-related fixes, so these issues are not going to be addressed. The good news, though, is that in general, even though these memory leaks exist it will take a long time for them to really become noticeable issues to a user. However, some websites and pages will exacerbate the issue much more quickly. In order to minimize the impact these issues have on a portal and ensure it is not one of those pages, we need to understand what development patterns will cause memory issues in IE11 and how to avoid them.

In general, there are four big problem areas when working with Internet Explorer:

  1. iFrames
  2. Full page refreshes in an Angular app
  3. Global variables
  4. Manual jQuery (DOM manipulation, event handlers, etc… )

The technical details for each of these is going to boil down to the same thing: Garbage collection in IE11 does not clean up all of the objects stored in memory from these four areas when you refresh a page, whereas Chrome and Firefox do this pretty well. The result is that as you navigate around and/or refresh the same page over and over, some of the objects are kept in memory. Over time this builds up to a point where eventually the process will crash because its memory usage is too high.

How to minimize memory leaks in Service Portal

While we can't fix the bug in IE11 itself, ServiceNow (along with many other web developers who have to work around these issues) has put a lot of time into finding ways we can reduce the impact of these issues. We've found that by following a few best practices, you can greatly reduce the amount of memory that is leaked to a point where most users will likely not notice it.

  1. Avoid using iFrames. This one is pretty simple. iFrames are known to be one of the largest contributors to memory leak issues when using IE11, so just don't use them. Our recommendation here is that if you need to open another page from your portal, use target="_blank" in your link to open that page in a new tab. While this isn't a seamless of an experience for your users, it sure beats the page crashing when they click on the link. I think we can agree that's a much worse experience!
  2. Avoid full page refreshes. This is usually the second largest contributor to memory leaks if you're handling navigation in your portal in a way other than using standard hrefs. Service Portal is designed to be a single page application from the get-go. If you click around your portal, you'll see that the header and footer for your portal don't actually reload — just the content inside of the "page". That's because Service Portal is a single page application by design. So generally, full page refreshes wont be much of an issue for you if your navigation is done using hrefs. What we've found, however, is that if you're doing your navigation using $window.location or some other means (like building your own AngularJS routing), Service Portal's single page functionality doesn't work as intended and you'll see full page refreshes whenever you're navigating around the portal. Since we know Internet Explorer doesn't handle full page refreshes very well for AngularJS apps, we should avoid this. There may be some use cases where you want to use $window.location so that you can tie navigation to an ng-click to call some function in the controller in order to perform some action when the user navigates away from the page. In those cases, one alternative that you may want to consider when working in IE is using the AngularJS $locationChangeSuccess event. This event is broadcast upon a successful change to the URL — so, you can listen for this event and run whatever logic you need to run when the user navigates away from the page here, then use a standard href for the link. That allows you to avoid the full page refresh while still tying some JavaScript logic into navigation.
  3. Avoid global variables. Another thing to keep in mind is that when you create global variables or store objects in the $rootscope, these objects will persist throughout the entire lifecycle of the Angular app. Since IE11 does not seem to release memory very well on a full page refresh in an Angular app, these objects will often hang around and, in some cases, can be held in memory multiple times. Now, unless you're doing this a ton, global variables wont be a massive contributor to memory leak issues but eliminating them wherever possible can help minimize the memory leaked by your portal.
  4. Release DOM references. Anytime you reference a DOM element directly inside a JavaScript closure, you need to set that reference to null as soon as you no longer need it. If you don't, the garbage collector will see that we're still referencing that element and will keep it stored in memory believing it is still needed. This is referred to as a detached DOM node. These can cause memory leaks in any browser but we need to be especially careful when working with IE11. The best advice here is this: If you declare a variable referencing a DOM element, set the variable to null in that same function as soon as you don't need it anymore. Another alternative is to never assign them to a variable to begin with.
  5. De-register Event handlers. Very similar to DOM references, some event handlers need to be manually de-registered to prevent them from sticking around and eating your memory. Angular event listeners should be cleaned up automatically as needed, but jQuery listeners will not be and need to be de-registered manually. In this case you should clean them up manually when the $scope is destroyed. To do this, you'll need to listen for the $destroy event and use:

$scope.$on('$destroy', myEvent);

By employing these techniques when developing your portal, you can significantly reduce the impact of IE11's memory leak bugs on your portal. While there will always be some memory being leaked in most cases, by following these practices you can reduce it to a negligible amount and greatly improve user experience. If you want some more info on some of the techniques discussed here I have provided a list of helpful resources below.

2 Comments