There are several different scenarios that can crash your browser - not to mention the bugs. :P
Lengthy execution
To time consuming execution of a script can make it get blocked, but not necessarily cause a lock.
Example:
for (var i = 2; i > 0; i++) {}
The above code does not cause the page to lock or occupy the processor, but since the execution of Javascript in the browser is performed synchronously, this means that the browser is prevented from performing other actions on that page.
If the browser has some protection against this, it will identify that the script is taking too long to return (timeout) and offer an option to the user to "kill" the process of that page or tab. Otherwise you will have to terminate the browser as an all.
Memory consumption
However, the sample question code is not only locked in an infinite loop, but also generates an infinite amount of output to the console.
Unless you have disabled the console, the data will be stored somewhere in the memory until there is no more space available and then you will have a failure in the process. If the console is being displayed in the Developer Tool, this is even worse because the browser has to update the user interface, performing various calculations of positioning of the texts, among other things.
Browsers can use different techniques to prevent a full crash, such as Chrome, which uses a process per page or tab, which means that if a tab crashes, just "kill" and the consumed memory will be recovered without prejudice to the system and other pages or tabs.
Note that this is just one of many ways to consume a lot of memory. For example:
- Memory leaks can be introduced by indefinitely adding values to objects or lists, or maintaining references to elements that are not even on the page.
- Working with very large strings, concatenating loops and similar things can also kill memory.
- Using recursiveness without a proper limit will also lock the script.
Avoiding such problems
The truth is that there is no practical and safe way to avoid this kind of problem because there are many different constructions in language that can lead to such situations.
However, the best approaches I know are:
- Write modular code (AMD, SE6) where functions and variables are isolated as much as possible.
- Test your code in an automated and unitary way (Qunit, Jasmine).
- Use tools of linting (Eslint), that is, that they analyze their code statically, according to pre-established rules, looking for bad practices and possible misunderstandings.
- Use the functional paradigm when possible
Specifically on item #3, Eslint has a list of rules defined among which there are some that can detect loops without stopping conditions, such as this. If there are any frequent mistakes that are not there, you can write your own rule.
Why modular code
Something important is that the more confused your code, the less effective the tests and static analysis. That’s why item #1 on my list above is in this position.
For example, many people use global scope variables in bonds. The behavior of this type of code is absurdly complex to predict.
function f1() {
for (i = 0; i < 10; i++) f2();
}
function f2() {
for (i = 0; i < 5; i++) whatever();
}
In the above example, f1
flame f2
for each execution of the loop. However i
is not a local variable, so f2
will always end with i = 5
and the tie in f1
will never end.
Why functional paradigm
The Brunorb mentioned something very important above, which is the use of routines like forEach
instead of manually doing the loop.
The functional programming paradigm is known to avoid several inherent problems of the imperative paradigm, such as this case.
The idea is to use special routines that encapsulate the logic of traversing a given data structure, after all they are implemented once, tested and have very little chance of suffering regressions. From diss you can perform actions on each element of the data structure using a function callback.
It is only important to consider that although this helps not to err with the counter of a loop, it still does not fully protect against misuse of global variables or that are shared with other functions, as in the example above.
If you have any improvement suggestions you can leave a comment.
– gato
I think it deals by breaking the infractive tab :D How it detects I don’t know, if it does. In general browsers have a tool that allows giving pause/put a breakpoint on the run, after all JS runs on a VM, with plenty of control if you’re in developer mode.
– Maniero
I’m learning WEB programming and this effect is more devastating than in Desktop kkkk, I think it doesn’t even detect, maybe some IDE alerts about it, but I don’t know.
– gato
maybe it’s of interest : How to release frozen/locked thread?
– Guilherme Lautert
Here I did not leave long, but although the page stay stuck, just close on the X tab that is fine. The cool thing is that Opera 12 handles it better (I tested it now to be sure) than the current version, which uses the same engine as Chrome. The current hangs. In 12 gets a little slow the browser, but everything works. I even scroll on the page with loop running, open console, etc., which basically indicates this as an answer: it only depends on the implementation of each browser.
– Bacco