106

Is there a way to find out how much memory is being used by a web page, or by my jquery application?

Here's my situation:

I'm building a data heavy webapp using a jquery frontend and a restful backend that serves data in JSON. The page is loaded once, and then everything happens via ajax.

The UI provides users with a way to create multiple tabs within the UI, and each tab can contain lots and lots of data. I'm considering limiting the number of tabs they can create, but was thinking it would be nice to only limit them once memory usage has gone above a certain threshold.

Based on the answers, I'd like to make some clarfications:

  • I'm looking for a runtime solution (not just developer tools), so that my application can determine actions based on memory usage in a user's browser.
  • Counting DOM elements or document size might be a good estimation, but it could be quite inaccurate since it wouldn't include event binding, data(), plugins, and other in-memory data structures.
David Mulder
  • 26,123
  • 9
  • 51
  • 114
Tauren
  • 26,795
  • 42
  • 131
  • 167
  • You should investigate the type of users for your webapp to determine if they do or don't have memory issues while using your webapp. Or are you having memory/performance issues with your webapp yourself? – Prutswonder Mar 27 '10 at 17:48
  • @Prutswonder: No i'm not having troubles, but I was just curious if such a tool exists. Just thought that rather than just setting a fixed limit on the tabs, that a dynamic method might be cool. – Tauren Mar 28 '10 at 18:05
  • I just added some additional details to the question to help clarify that I'm looking for a runtime solution, not a build-time solution. – Tauren Mar 28 '10 at 18:28
  • 2
    Just a question, if something was already cached, will that still count? – ajax333221 Mar 22 '12 at 01:11

10 Answers10

79

2015 Update

Back in 2012 this wasn't possible, if you wanted to support all major browsers in-use. Unfortunately, right now this is still a Chrome only feature (a non-standard extension of window.performance).

window.performance.memory

Browser support: Chrome 6+


2012 Answer

Is there a way to find out how much memory is being used by a web page, or by my jquery application? I'm looking for a runtime solution (not just developer tools), so that my application can determine actions based on memory usage in a user's browser.

The simple but correct answer is no. Not all browsers expose such data to you. And I think you should drop the idea simply because the complexity and inaccuracy of a "handmade" solution may introduce more problem than it solves.

Counting DOM elements or document size might be a good estimation, but it could be quite inaccurate since it wouldn't include event binding, data(), plugins, and other in-memory data structures.

If you really want to stick with your idea you should separate fixed and dynamic content.

Fixed content is not dependant on user actions (memory used by script files, plugins, etc.)
Everything else is considered dynamic and should be your main focus when determining your limit.

But there is no easy way to summarize them. You could implement a tracking system that gathers all these information. All operations should call the appropriate tracking methods. e.g:

Wrap or overwrite jQuery.data method to inform the tracking system about your data allocations.

Wrap html manipulations so that adding or removing content is also tracked (innerHTML.length is the best estimate).

If you keep large in-memory objects they should also be monitored.

As for event binding you should use event delegation and then it could also be considered a somewhat fixed factor.

Another aspect that makes it hard to estimate your memory requirements correctly is that different browsers may allocate memory differently (for Javascript objects and DOM elements).

Kostas Stamos
  • 175
  • 1
  • 3
  • 16
gblazex
  • 49,155
  • 12
  • 98
  • 91
  • Doesn't `innerHTML.length` take memory or RAM or CPU ( or anything else, I've no idea ) to process also? – mrReiha Jun 03 '15 at 22:00
  • Browser support for this feature is NOT IE9+ or anything besides Chrome. Window.performance.memory is Chrome only. https://docs.webplatform.org/wiki/apis/timing/properties/memory – Blunderfest Feb 08 '16 at 13:24
  • You are right, I thought memory was part of the navigation timing standard and the `window.performance` object. The old "supported by" entries were applicable for that standard. `window.performance.memory` is considered a *non-standard* extension by Chrome. – gblazex Feb 09 '16 at 11:29
  • To enable real time memory monitoring via window.performance.memory, you need to start Chrome with the --enable-precise-memory-info flag. – kluverua Jul 03 '18 at 14:59
  • Update: Opera also supports this. Source: Mozilla. https://developer.mozilla.org/en-US/docs/Web/API/Performance#Browser_compatibility – HoldOffHunger Aug 23 '18 at 17:33
41

You can use the Navigation Timing API.

Navigation Timing is a JavaScript API for accurately measuring performance on the web. The API provides a simple way to get accurate and detailed timing statistics—natively—for page navigation and load events.

window.performance.memory gives access to JavaScript memory usage data.


Recommended reading

Sindre Sorhus
  • 62,972
  • 39
  • 168
  • 232
23

This question is 5 years old, and both javascript and browsers have evolved incredibly in this time. Since this now possible (in at least some browsers), and this question is the first result when you Google "javascript show memory useage", I thought I'd offer a modern solution.

memory-stats.js: https://github.com/paulirish/memory-stats.js/tree/master

This script (which you can run at any time on any page) will display the current memory useage of the page:

var script=document.createElement('script');
script.src='https://rawgit.com/paulirish/memory-stats.js/master/bookmarklet.js';
document.head.appendChild(script);
Dustin Brownell
  • 817
  • 7
  • 10
  • 1
    This seems to be reporting the JS memory usage and not the page memory usage, Chrome's built-in Task Manager says Gmail is using 250MB while memory-stats.js reports 33.7MB – brandito Feb 21 '18 at 04:43
  • There is no license listed for bookmarklet.js's github page, so it's presumably copyrighted, intellectual property. That leaves a degree of uncertainty in depending on that project. – HoldOffHunger Aug 23 '18 at 17:26
8

I don't know of any way that you could actually find out how much memory is being used by the browser, but you might be able to use a heuristic based on the number of elements on the page. Uinsg jQuery, you could do $('*').length and it will give you the count of the number of DOM elements. Honestly, though, it's probably easier just to do some usability testing and come up with a fixed number of tabs to support.

tvanfosson
  • 524,688
  • 99
  • 697
  • 795
  • 3
    @tvanfosson: not a bad idea, but this isn't going to give me information about non-DOM memory, such as .data() and in memory data structures. But it could give a good estimation of the overall weight which I could use. – Tauren Mar 28 '10 at 18:07
4

Use the Chrome Heap Snapshot tool

There's also a Firebug tool called MemoryBug but seems it's not very mature yet.

Pablo Fernandez
  • 103,170
  • 56
  • 192
  • 232
  • @Pablo: Thanks. I'll certainly be using dev tools, but was hoping to find something that I could use during runtime to find the memory usage in each user's browser. – Tauren Mar 28 '10 at 18:19
3

If you want to just see for testing there is a way in Chrome via the developer page to track memory use, but not sure how to do it in javascript directly.

Zachary K
  • 3,205
  • 1
  • 29
  • 36
3

I would like to suggest an entirely different solution from the other answers, namely to observe the speed of your application and once it drops below defined levels either show tips to the user to close tabs, or disable new tabs from opening. A simple class which provides this kind of information is for example https://github.com/mrdoob/stats.js . Aside of that, it might not be wise for such an intensive application to keep all tabs in memory in the first place. E.g. keeping only the user state (scroll) and loading all the data each time all but the last two tabs are opening might be a safer option.

Lastly, webkit developers have been discussing adding memory information to javascript, but they have gotten in a number of arguments about what and what should not be exposed. Either way, it's not unlikely that this kind of information will be available in a few years (although that information isn't too useful right now).

David Mulder
  • 26,123
  • 9
  • 51
  • 114
1

Perfect question timing with me starting on a similar project!

There is no accurate way of monitoring JS memory usage in-app since it would require higher level privileges. As mentioned in comments, checking the number of all elements etc. would be a waste of time since it ignores bound events etc.

This would be an architecture issue if memory leaks manifest or unused elements persist. Making sure that closed tabs' content is deleted completely without lingering event handlers etc. would be perfect; assuming that it's done you could just simulate heavy usage in a browser and extrapolate the results from memory monitoring (type about:memory in the address bar)

Protip: if you open the same page in IE, FF, Safari... and Chrome; and than navigate to about:memory in Chrome, it will report memory usage across all other browsers. Neat!

Oleg
  • 24,465
  • 8
  • 61
  • 91
0

What you might want to do is have the server keep track of their bandwidth for that session (how many bytes of data have been sent to them). When they go over the limit, instead of sending data via ajax, the server should send an error code which javascript will use to tell the user they've used too much data.

Cam
  • 14,930
  • 16
  • 77
  • 128
  • @incrediman: that's kind of a cool idea too, but I don't think it would work without building in a lot of tracking features -- just a byte count wouldn't work. The problem is that the data in a tab is a list that the user will filter and sort in many different ways. Each time they make changes, new data will be retrieved from the server and replace the current dom elements. Plus, what's do say they don't hit "reload", and start with a fresh page? I'd have to track 304s and such then as well, but I intend to just serve static html, all data comes from a REST service. – Tauren Mar 28 '10 at 18:15
  • This approach does not account for elements created or destroyed with createElement() or remove(), which would affect client memory usage. But it is interestingly different from other answers (by measuring server-side, and not client-side, your measurements don't change the memory, the way other answers would). – HoldOffHunger Aug 23 '18 at 17:48
0

You can get the document.documentElement.innerHTML and check its length. It would give you the number of bytes used by your web page.

This may not work in all browsers. So you can enclose all your body elements in a giant div and call innerhtml on that div. Something like <body><div id="giantDiv">...</div></body>

Midhat
  • 17,454
  • 22
  • 87
  • 114
  • 4
    The length of the generated `innerHTML` string is unlikely to be *usefully* corrolated with the memory the browser uses (e.g., in its internal object model) to render that HTML. – T.J. Crowder Mar 27 '10 at 17:49
  • and why is that? My rationale is that if some text is loaded in the browser, it has to be stored in the memory. SO it does give some measure of the memory used by the browser to render the page. – Midhat Mar 27 '10 at 17:52
  • 4
    Think about it this way. If you say "I'd like to give you 10 million dollars", that's 8 words. On the other hand, if you said "I'd like to sneeze on your napkin", that's 7. Is the first only 8/7 more valuable than the second? – intuited Mar 27 '10 at 18:00
  • as far as memory is concerned, both contain 30ish characters, Are we talking about the storage or the semantics of the data here – Midhat Mar 27 '10 at 20:42
  • 1
    This is similar to @tvanfosson suggestion of getting the count of DOM elements. Your's is probably a bit more accurate because different dom elements can contain different amounts of text. But it still doesn't get any information about data(), click handers, in memory data structures and objects, and so forth. My app uses lots of these features. – Tauren Mar 28 '10 at 18:21
  • 1
    There can be JS variables in scope that point to detached DOM nodes, that will not be part of the document element. Also you could write code to just load a really long string into a variable, consuming gigabytes of memory, without affecting the text on the page. – Josh Ribakoff Nov 10 '15 at 00:47