JavaScript front end optimization code

Time:2022-6-28
catalogue
  • Optimization of if judgment
    • 1. The simplest method: if judgment
    • 2. A better way: switch
    • 3. Better method: strategy mode
  • Optimization of includes
    • For loop
      • Array de duplication
        • 1. The most traditional method: use the indexof subscript attribute of the array to query.
        • 2. Optimization: use the set method of ES6.
      • Arrow function
        • Creation of DOM
          • Memory leak
            • 1. Undeclared variables or variables created with this (this points to window) can cause memory leaks
            • 2. In Vue single page applications, the declared global variables are not cleared when switching pages
          • Anti shake and throttling
            • Load JS asynchronously

              Optimization of if judgment

              JavaScript conditional statements are inevitably used in our normal development, but our code is often not well written. A series of if else or multiple nested judgments will make the code very bloated. The following examples are used for optimization.

              Demand: now there are four products, namely mobile phones, computers, televisions and game consoles. Of course, the prices of each product are different.

              1. The simplest method: if judgment

              let commodity = {
                Phone: 'mobile phone',
                Computer: 'computer',
                Television: 'TV',
                Gameboy: 'game console',
              }
              
              function price(name) {
                if (name === commodity.phone) {
                  console.log(1999)
                } else if (name === commodity.computer) {
                  console.log(9999)
                } else if (name === commodity.television) {
                  console.log(2999)
                } else if (name === commodity.gameBoy) {
                  console.log(3999)
                }
              }
              Price ('mobile ') // 9999

              Disadvantages: the code is too long, and maintenance and reading are not friendly

              2. A better way: switch

              let commodity = {
                Phone: 'mobile phone',
                Computer: 'computer',
                Television: 'TV',
                Gameboy: 'game console',
              }
              const price = (name) => {
                switch (name) {
                  case commodity.phone:
                    console.log(1999)
                    break
                  case commodity.computer:
                    console.log(9999)
                    break
                  case commodity.television:
                    console.log(2999)
                    break
                  case commodity.gameBoy:
                    console.log(3999)
                    break
                }
              }
              Price ('mobile ') // 9999

              3. Better method: strategy mode

              The strategy pattern can effectively avoid multiple conditional choice statements by using the techniques and ideas of combination, delegation and polymorphism. It provides perfect support for the open closed principle, encapsulates the algorithms in an independent strategy, and makes them easy to switch, understand and expand.

              
              const commodity = new Map([
                ['phone', 1999],
                ['computer', 9999],
                ['television', 2999],
                ['gameBoy', 3999],
              ])
              
              const price = (name) => {
                return commodity.get(name)
              }
              price('phone') // 1999

              Optimization of includes

              Includes is a newly added API in ES7. Unlike indexof, includes directly returns a Boolean value, while indexof returns an index value. Arrays and strings have the include method.

              Requirement: we will implement an identity authentication method to return the corresponding authentication result by passing in the identity ID

              traditional method

              function verifyIdentity(identityId) {
                if (identityId == 1 || identityId == 2 || identityId == 3 || identityId == 4) {
                  Return 'your identity is legal, please pass!'
                } else {
                  Return 'your identity is illegal.'
                }
              }

              Includes optimization

              function verifyIdentity(identityId) {
                if ([1, 2, 3, 4].includes(identityId)) {
                  Return 'your identity is legal, please pass!'
                } else {
                  Return 'your identity is illegal.'
                }
              }

              For loop

              In JavaScript, we can use for (), while (), for (in) and for (in) loops. In fact, the efficiency of for (in) in these three loops is extremely poor. Because it needs to query hash keys, it should be used as little as possible.

              The for loop is the most traditional statement. It takes the variable I as the index to track the access position and operate on the array.

              var arr = ['a', 'b', 'c']
              for (var i = 0; i < arr.length; i++) {
                console. Log (arr[i]) // the results are a, B, C
              }

              There is a problem with the above method: when the length of the array reaches the million level, arr.length will be calculated onemillion times, which is quite performance consuming. Therefore, the following methods can be adopted for improvement.

              var arr = ['a', 'b', 'c']
              for (var i = 0, length = arr.length; i < length; i++) {
                console. Log (arr[i]) // the results are a, B, C
              }

              At this time, arr.length only needs to be calculated once, which optimizes the performance.

              For in is generally used to traverse the attributes of an object, but the attributes need to be enumerable to be read. At the same time, for in can also traverse the array. When traversing the array, it traverses the subscript value of the array.

              var obj = { 0: 'a', 1: 'b', 2: 'c' }
              for (var key in obj) {
                console. Log (key) // the results are 0, 1 and 2 respectively
              }
              
              var arr = ['a', 'b', 'c']
              for (var key in a) {
                console. Log (key) // the results are 0, 1 and 2 respectively
              }

              The for statement looks a bit like a for in statement, but unlike the for statement, it can only loop arrays instead of objects.

              var arr = ['a', 'b', 'c']
              for (var value of arr) {
                console. Log (value) // the results are a, B, C
              }

              The for-of loop is better than the for in loop. For-of can be used to iterate over members as long as it has a data structure with an iterator interface. It reads the key value directly. For in needs to enumerate all attributes of the object, including custom added attributes. In addition, the key of for in is of string type, and there is a conversion process, which costs a lot.

              Therefore, in the development process, the circular array should try to avoid using for in.

              Array de duplication

              Array de duplication is often encountered in the actual development and processing of data. There are many methods, which are not illustrated here.

              1. The most traditional method: use the indexof subscript attribute of the array to query.

              
              function unique4(arr) {
                var newArr = []
                for (var i = 0; i < arr.length; i++) {
                  if (newArr.indexOf(arr[i]) === -1) {
                    newArr.push(arr[i])
                  }
                }
                return newArr
              }
              console.log(unique4([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4]))
              // [1, 2, 3, 5, 6, 7, 4]

              2. Optimization: use the set method of ES6.

              Set itself is a constructor used to generate a set data structure. The set function can accept an array (or other data structures with Iterable interface) as a parameter for initialization. The set object allows you to store any type of value, whether it is an original value or an object reference. It is similar to an array, but the values of members are unique, and there are no duplicate values.

              function unique4(arr) {
                return Array. From (new set (ARR)) // use array From converts a set structure to an array
              }
              console.log(unique4([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4]))
              // [1, 2, 3, 5, 6, 7, 4]

              Arrow function

              The syntax of arrow function expressions is more concise than function expressions. Therefore, it is more recommended to use arrow function in development. Especially in Vue projects, it is not necessary to reassign a variable to this when using the arrow function.

              //Using functions
              var arr = [5, 3, 2, 9, 1]
              var arrFunc = arr.map(function (x) {
                return x * x
              })
              console.log(arrFunc)
              
              //Using arrow functions
              var arr = [5, 3, 2, 9, 1]
              var arrFunc = arr.map((x) => x * x)

              Note that the arrow function does not bind arguments. Instead, use the rest parameter.

              //Arguments cannot be used
              let fun1 = (b) => {
                console.log(arguments)
              }
              fun1(2, 92, 32, 32) // Uncaught ReferenceError: arguments is not defined
              
              //Use rest parameters
              let fun2 = (...c) => {
                console.log(c)
              }
              fun2(3, 82, 32, 11323) // [3, 82, 32, 11323]

              Creation of DOM

              When creating multiple DOM elements, first append the elements to the documentfragment, and finally uniformly add the documentfragment to the page.

              Conventional methods;

              
              for (var i = 0; i < 1000; i++) {
                var el = document.createElement('p')
                el.innerhtml = i
                document.body.appendChild(el)
              }

              Optimize multiple append with documentfragment

              
              var frag = document.createDocumentFragment()
              for (var i = 0; i < 1000; i++) {
                var el = document.createElement('p')
                el.innerhtml = i
                frag.appendChild(el)
              }
              document.body.appendChild(frag)

              Better: use an innerHTML assignment instead of building DOM elements

              
              var html = []
              for (var i = 0; i < 1000; i++) {
                html.push('<p>' + i + '</p>')
              }
              document.body.innerHTML = html.join('')

              Memory leak

              The memory that is no longer used by the system process and is not released in time is called a memory leak. When the memory consumption becomes higher and higher, the system performance will be affected at first, and the process will crash at last.

              Causes of memory leaks

              global variable

              1. Undeclared variables or variables created with this (this points to window) can cause memory leaks

              
              function fn() {
                a = "Actually, I'm a global variable"
              }
              fn()
              
              function fn() {
                this.a = "Actually, I'm a global variable"
              }
              fn()

              resolvent:

              • Avoid creating global variables
              • Using strict mode, add use strict to the JavaScript file header or the top of the function.

              2. In Vue single page applications, the declared global variables are not cleared when switching pages

              <template>
                <div>
                  Here is the home page
                </div>
              </template>
              
              <script>
                export default {
                  mounted() {
                    window.test = {
                      //Here, the DOM object of this page is referenced in the global window object
                      name: 'home',
                      node: document.getElementById('home')
                    }
                  }
                }
              </script>

              Solution: dispose of the reference when the page is unloaded.

              destroyed () {
                window. Test = null // dereference when the page is unloaded
              }

              closure

              Cause of memory leakage caused by closures: closures can maintain local variables in functions so that they cannot be released.

              
              function fn() {
                var a = "I'm a"
                return function () {
                  console.log(a)
                }
              }

              Solution: define the event handler function externally and remove the closure, or delete the reference to DOM in the external function that defines the event handler function.

              Timer or event listening

              Some pages in the project will inevitably encounter the need for timers or event monitoring. However, when leaving the current page, if the timer is not cleared timely and reasonably, the business logic will be confused or even the application will be stuck. In this case, it is necessary to clear the timer event listening, that is, in the life cycle function of page unloading (closing), clear the timer.

              methods:{
                resizeFun () {
                  this.tableHeight = window.innerHeight - document.getElementById('table').offsetTop - 128
                },
                setTimer() {
                  this.timer = setInterval(() => { })
                },
                Cleartimer() {// clear timer
              		clearInterval(this.timer)
                  this.timer = null
              	}
              },
              mounted() {
                this.setTimer()
                window.addEventListener('resize', this.resizeFun)
              },
              beforeDestroy() {
                window.removeEventListener('resize', this.resizeFun)
                this.clearTimer()
              }

              Anti shake and throttling

              In the process of front-end development, we often need to bind some continuously triggered events, such as resize, scroll, MouseMove, etc., but sometimes we don’t want to execute functions so frequently in the process of continuously triggering events. At this time, anti shake and throttling are used.

              Case 1: remote search requires dynamic data acquisition through the interface. If the interface is requested every time the user inputs, it will waste bandwidth and performance.

              
              <Select :remote-method="remoteMethod">
                  <Option v-for="item in temoteList" :value="item.value" :key="item.id">{{item.label}}</Option>
              </Select>
              
              <script>
              function debounce(fn, wait) {
                let timeout = null
                return function () {
                  if (timeout !== null) clearTimeout(timeout)
                  timeout = setTimeout(fn, wait)
                }
              }
              
              export default {
                methods:{
                  remoteMethod:debounce(function (query) {
                      // to do ...
                  }, 200),
                }
              }
              <script>

              Case 2: when the scroll event is triggered continuously, the handle function is not executed immediately. When the scroll event is not triggered within 1000 milliseconds, the handle function will be triggered once.

              
              function debounce(fn, wait) {
                let timeout = null
                return function () {
                  if (timeout !== null) clearTimeout(timeout)
                  timeout = setTimeout(fn, wait)
                }
              }
              function handle() {
                console.log(Math.random())
              }
              window.addEventListener('scroll', debounce(handle, 1000))

              Load JS asynchronously

              By default, the browser loads JS scripts synchronously. In the process of parsing HTML, it will stop when it encounters the <script> tag. After the script is downloaded, parsed and executed, it will continue to parse and render downward.

              If the JS file size is large, the download time will be very long, which is easy to cause browser congestion. The browser page will show a “white screen” effect, and users will feel that the browser is “stuck” and will not respond. At this point, we can make the JS script load and execute asynchronously.

              
              <script src="path/to/home.js" defer></script>
              <script src="path/to/home.js" async></script>

              In the above code, <script> tags have defer and async attributes respectively. When the browser recognizes these two attributes, JS will load asynchronously. In other words, the browser will not wait for the script to be downloaded and executed before executing backwards, but will directly continue to execute backwards

              The difference between defer and async:

              • Defer: the DOM structure is completely generated and other scripts are executed (after rendering). When there are multiple defer scripts, they will be loaded and executed in the order in which the page appears.
              • Async: once the download is completed, the rendering engine will interrupt the rendering, execute this script, and then continue rendering (execute after the download). When there are multiple async scripts, they cannot be loaded and executed in the order in which the page appears

              The above is the details of JavaScript front-end optimization code. For more information about JavaScript optimization, please pay attention to other developeppaer related articles!