123

Is there any particular advantage/disadvantage in JavaScript memory consumption between using location.href = url as opposed to location.assign(url)?

I guess I'm wondering if it takes more memory to access the method as opposed to setting the property.

Michał Perłakowski
  • 88,409
  • 26
  • 156
  • 177
Doug Weaver
  • 1,581
  • 2
  • 9
  • 8
  • 2
    http://stackoverflow.com/a/1865840/638649 answer may be what you are after – matchew Apr 24 '12 at 17:29
  • @JuanMendes: I've inherited an intranet app built on a that leaks like it was made of paper (a rate of about 50mb an hour). I'm trying to conserve memory anywhere I can. – Doug Weaver Apr 24 '12 at 17:41
  • @matchew: I saw that earlier but it didn't really address any memory issues, if in fact there are any. – Doug Weaver Apr 24 '12 at 17:43
  • 1
    I think the question then is not about how much memory is used, but whether there is a leak associated with using `location.assign` and `location.href = ''` – Ruan Mendes Apr 24 '12 at 18:42
  • 9
    Future readers: I'd strongly consider that: 1. `location.href` vs `location.assign()` doesn't impact performance unless your app is changing location hundreds of times a second; and 2. if your app _is_ doing that, **that is the real problem you need to fix**. – Jordan Gray Jan 28 '19 at 12:35
  • 1
    What Jordan Gray said. Unless you're doing this an obscene amount of times (what use case could possibly require this??) then you are focusing on performance when you absolutely shouldn't be. – J. Munson Apr 01 '20 at 20:50

7 Answers7

58

I know this is old, but I stumbled on this when I was looking for a way to check my unit tests were redirecting to the correct url.

I would go with window.location.assign() if you are more concerned with testing. Using a function allows you to mock said function and check the url input parameters.

So, using jest:

window.location.assign = jest.fn();

myUrlUpdateFunction();

expect(window.location.assign).toBeCalledWith('http://my.url');

// Clean up :)
window.location.assign.mockRestore();
kieranroneill
  • 849
  • 7
  • 9
  • 7
    Keep in mind, the `mockRestore()` call here won't restore the original native function. To do it in a proper way you'd need to use `jest.spyOn()` function - https://jestjs.io/docs/en/jest-object#jestspyonobject-methodname – Johny Nov 02 '18 at 13:16
57

I personally prefer calling the function instead, because calling a function gives me a better impression that something is running and that is not only a value of a variable that is changing.

But probably yes, it may be true that location.href = url; is faster than location.assign(url), although it may depend on the JavaScript engine implementation, according to my tests. [Dead link to tests removed.]

Andrew
  • 3,825
  • 4
  • 30
  • 44
Pere
  • 1,647
  • 3
  • 27
  • 52
34

I always used and never had problems with:

location.href = url;

Calling a function should be slightly slower than accessing the property, but in terms of memory there should not be a big difference in my humble opinion.

Pere
  • 1,647
  • 3
  • 27
  • 52
Tobias Krogh
  • 3,768
  • 20
  • 14
  • Works for me. I didn't figure I'd be saving much but I didn't know if there was something I was overlooking. Thanks. – Doug Weaver Apr 24 '12 at 17:49
  • 9
    Wrong ! Even if there could have a difference, thing is that if 'href' is a property, document.location is not (there is a get/set underneath). Secondly, we just talk about µS, maybe less. Thirdly, depending on the context, using `assign()` seems a lot more testable than assigning `href` (at least with jsdom) And finally, it seems that calling `assign()` is a just bit slower https://jsperf.com/location-href-vs-location-assign/14. – Jerome Mar 28 '18 at 14:23
  • 1
    @Jerome agreed that it's better to use `locaiton.assign()` because it's testable. Assigning `location.href` never felt right. – silvenon Apr 01 '20 at 09:44
  • 1
    Purely philosophically. It is always a better use method than direct access. – AntiCZ Aug 12 '21 at 06:45
  • I agree - purely philosophical. While getter / setter for testing is absolutely possible (e.g. using `Object.defineProperty`) at the same time using get / set for properties has become very common in TypeScript - while remaining testable of course! But this totally drifts aside from the initial question about the memory consumption between property access and method call :) – Tobias Krogh Oct 27 '21 at 04:59
5

Is there any particular advantage/disadvantage in JavaScript memory consumption between using location.href = url as opposed to location.assign(url)?

NO

There is exactly zero difference.

The reason for this is simple. Every time your browser loads a new page, it starts a fresh new Javascript 'VM' with the scripts for that page running in that VM. When running either of the statements in your question, you are instructing the browser to load a new page, which means destroying the current VM (and freeing up any memory associated with it) and loading a completely new VM for the new page.

Save for any weird browser bugs the net effect is always the same. Your scripts are running in a brand new VM with the exact same memory consumption.

ulocation

If you are working with the location object in the browser and you want to be able to run this code on Node JS (e.g. for testing or for isometric code), you can use ulocation, a universal/isometric implementation of the Location object. Full Disclosure: I am the author of that package.

Stijn de Witt
  • 40,192
  • 13
  • 79
  • 80
  • what about `location.assign("#foo")` ? – Cauterite May 23 '17 at 03:55
  • Yes you are right that might be the one exception, theoretically. However, most likely, the same code is actually used below the surface whether you call location.assign or assign to the property. The property setter most likely simply calls assign. That's how I would build it. :) – Stijn de Witt Oct 08 '18 at 11:46
4

actually there is a difference i think

  1. location.href is a property which mean it is faster than calling a function but most importantly href property make user able to go back when clicking on back button on the browser
  2. location.replace() the user will not be able to go back to the current page.
  3. location.assign() the user will able to go back through back button like href but location.assign is better in terms of testing and mocking
Andrew Naem
  • 162
  • 12
  • Assigning a property *is* calling a function. Properties are backed by getters and setters, which are functions. Even if they were not functions.... There is no real performance difference. I always see programmers debating stuff like this. Whether calling a function this way or that way is faster. Or whether defining a variable outside of the loop or in the for clause matters. Let me tell you, after 20 years of development my conclusion is there is no difference that will matter to your performance. Your not indexed database queries and your nested loops are the culprit... – Stijn de Witt Jul 03 '23 at 11:15
3

Tested my machine/browser, http://jsperf.com/location-href-vs-location-assign/2, for Chrome 40.0.2214.93 32-bit on Windows Server 2008 R2 / 7 64-bit

location.assign was 15% slower than location.href.

  • 116
    Yes, what you constantly do in a web app is navigating to a new location 500 times per second... that's why you should take performance into consideration. – meandre May 31 '16 at 10:41
0

I'd like to add a difference that I experienced using both while working in React which the above answers missing.

Analyze the following snippet in React:

return (<>location.href = "www://example.com"</>)

Vs

return (<>location.assign("www://example.com")</>)

In the fonmer case you'd actually see the string www://example.com getting typed on the DOM for a split second since it renders the text before this redirection happens.

To avoid that We need to use the latter location.assign()

ABGR
  • 4,631
  • 4
  • 27
  • 49
  • 2
    This is a completely wrong method to go about doing a redirect. The `.assign` should be called above the `return` statement, and `return` should return `null` or `<>>`. – David Wheatley Nov 25 '21 at 13:49