preface
These are the ones I’ve collected, used and JSBench tested on the web. If you have any more, feel free to leave them in the comments section
External manifestation of memory problems
- Pages load lazily or pause frequently
- The page continues to have poor performance
- Page performance deteriorates over time
Criteria for defining memory problems
- Memory leak: Memory usage continues to rise
- Memory bloat: Performance issues on most devices
- Frequent garbage collection: Analyzed by memory variation graph
The separation of the DOM
- Interface elements live in the DOM tree
- DOM node when garbage object
- Separate state DOM nodes
TimeLine Record Memory-Performance panel
<! doctypehtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="Width =device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button id="btn">new</button>
<script>
const arr = []
function test () {
for (let i = 0; i < 1000000; i++) {
document.body.appendChild(document.createElement('p'))
}
arr.push(new Array(1000000).join('x'))}document.getElementById('btn').addEventListener('click', test)
</script>
</body>
</html>
Copy the code
Heap map monitor Memory – Memory panel
<! doctypehtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="Width =device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button id="btn">new</button>
<script>
const arr = []
function test () {
for (let i = 0; i < 1000000; i++) {
document.body.appendChild(document.createElement('p'))
}
arr.push(new Array(1000000).join('x'))}document.getElementById('btn').addEventListener('click', test)
</script>
</body>
</html>
Copy the code
How do I determine frequent garbage collection
- Frequent ups and downs in Timeline
- Frequent data increases and decreases in task manager
Performance optimization
Be careful with global variables
- Global variables are defined in the global execution context and are at the top of any scope chain
- The global execution context remains in the context execution stack until the program exits
- The presence of a variable with the same name in a local scope obscures or contaminates the whole world
// Global variables
var i, str = ' '
for (i =0; i< 1000; i++) {
str += i
}
// Local variables (faster)
for (let i =0; i< 1000; i++) {
let str = ' '
str += i
}
Copy the code
Caching global variables
- Global variables that cannot be avoided in use are cached locally
// Non-cached
const obj = {
name: 'jcode'.age: 18
}
function fn () {
console.log(obj.name)
console.log(obj.name)
console.log(obj.name)
console.log(obj.name)
console.log(obj.name)
}
fn()
// Cache mode (faster)
const obj = {
name: 'jcode'.age: 18
}
function fn () {
const o = obj
console.log(o.name)
console.log(o.name)
console.log(o.name)
console.log(o.name)
}
fn()
Copy the code
Add by prototype
- Methods needed to add an instance object to a prototype object
// Defined on the prototype instance
function Person () {
this.sayHi = function () {
console.log('sayHi')}}const p1 = new Person()
// Define on prototype (faster)
function Person () {}
Person.prototype.sayHi = function () {
console.log('sayHi')}const p1 = new Person()
Copy the code
Avoid closure traps
- Each closure call destroys as many useless variables as possible
<! doctypehtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="Width =device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button id="btn" class="dd">add</button>
<script>
function foo () {
var el = document.getElementById('btn')
el.onclick = function () {
console.log(el.id, el.className)
}
el = null
}
foo()
</script>
</body>
</html>
Copy the code
Avoid attribute access methods
- Object orientation in JavaScript
- JS does not require attribute access methods, all attributes are externally visible
- Using attribute access methods only adds another layer of redefinition without access control
// Access attributes indirectly by defining methods (slow)
function Person () {
this.name = 'jcode'
this.age = 18
this.getAge = function () {
return this.age
}
}
const p1 = new Person()
const a = p1.getAge()
// Access attributes directly (faster)
function Person () {
this.name = 'jcode'
this.age = 18
}
const p1 = new Person()
const b = p1.age
Copy the code
For loop optimization
var arr = [1.2.3.4.5.6.7]
for (var i = 0; i < arr.length; i++) {
console.log(i)
}
/ / faster
var arr = [1.2.3.4.5.6.7]
for (var i = 0, len = arr.length; i < len; i++) {
console.log(i)
}
Copy the code
For loop optimally sorts
- ForEach (fastest) > for(optimized for) > for in
Node addition optimization
- The addition of nodes inevitably involves backflow and redraw
for (var i = 0; i < 10; i++) {
var oP = document.createElement('p')
oP.innerHTML = i
document.body.appendChild(oP)
}
// Document fragmentation adds (faster)
const fragEle = document.createDocumentFragment()
for (var i = 0; i < 10; i++) {
var oP = document.createElement('p')
oP.innerHTML = i
fragEle.appendChild(oP)
}
document.body.appendChild(fragEle)
Copy the code
Clone optimized node operation
<! doctypehtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="Width =device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<p id="box1">old</p>
<script>
for (var i =0; i < 5; i++) {
var oP = document.createElement('p')
oP.innerHTML = i
document.body.appendChild(oP)
}
// Clone the way (faster)
var oldP = document.getElementById('box1')
for (var i =0; i < 5; i++) {
var newP = document.cloneNode(false)
newP.innerHTML = i
document.body.appendChild(newP)
}
</script>
</body>
</html>
Copy the code
Literal replacement for new Array
var arr = newArray(3)
arr[0] = 1
arr[1] = 2
arr[2] = 3
/ / faster
var arr = [1.2.3]
Copy the code
Reduce the level of judgment
- Return as early as possible to end the statement
- Switch provides better performance
Reduce the scope chain lookup level
Reduce the number of data reads
function (ele, cla) {
return ele.className === cls
}
// Do a cache, faster
function (ele, cla) {
let clsName = ele.className
return clsName === cls
}
Copy the code
Literals and constructors – Literals are fast
- The reference types are similar
- The underlying data types vary considerably
const obj = new Object()
obj.name = 'jcode'
// The literal way is faster
const obj = {
name: 'jcode'
}
Copy the code
Reduce circulatory body activity
- Try to lift immutable operations out of the loop body
// Faster than the normal for loop
const test = () = > {
var i
var arr = [1.2.3]
var len = arr.length
for (i = 0; i < len; i++) {
console.log(arr[i])
}
}
/ / faster
const test = () = > {
var arr = [1.2.3]
var len = arr.length
while (len--) {
console.log(arr[len])
}
}
Copy the code
Reduce the number of declarations and statements
var name = 'jcode'
var age = 19
/ / faster
var name = 'jcode',
age = 19
Copy the code
Use event binding
Using event delegate
<ul id="ul">
<li>jcode</li>
<li>18</li>
</ul>
<script>
var list = document.querySelectorAll('li')
function showTxt (ev) {
console.log(ev.target.innerHTML)
}
for(let item of list) {
item.onclick = showTxt
}
// The following is more efficient
var ul = document.getElementById('ul')
ul.addEventListener('click', showTxt, true)
function showTxt (ev) {
var obj = ev.target
if (obj.nodeName.toLowerCase() === 'li') {
console.log(obj.innerHTML)
}
}
</script>
Copy the code
References:
Language finch: www.yuque.com/xixieguibug…