Techniques for writing highly efficient javascript events

Source: Internet
Author: User

Techniques for writing highly efficient javascript events
How to make efficient web Front-end programs is a problem that I will not consciously consider every time I do front-end development. A few years ago, Yahoo's awesome front-end engineers published a book about improving the web Front-end performance, which caused a sensation in the entire web development technology field, turning the mysterious web front-end optimization problem into a cabbage, web Front-end optimization becomes a simple question that cainiao and Daniel can answer. When the industry knows the answer, the existing optimization technology can no longer overhead the quality of your website. In order to make our website develop better performance than other websites, we need to think deeply and independently, reserve better skills. The Event System in Javascript is the first breakthrough point I have come up. Why is it a javascript Event System? We all know that the web Front-end contains three technologies: html, css, and javascript. it is clear how html and css are combined: style, class, id, and html Tag, but how can javascript be integrated into html and css? Finally, I found that the starting point is the javascript Event System. No matter how complicated javascript code we write, the event system is finally reflected in html and css, therefore, I am thinking that since the event system is the integration of the three, there will inevitably be a large number of event operations on a page, especially on today's increasingly complex web pages, without these events, the javascript code we have carefully compiled is only a warehouse, and the hero is useless. Since there will be a large number of event functions on the page, will there be problems affecting efficiency when we write event functions as we are used? The answer I have studied is true efficiency, and it is still a serious efficiency problem. To clarify my answer, I need to explain in detail the javascript Event System. The Event System is the starting point for integrating javascript, html, and css. This cutting point is like the main function in java. Everything magic starts from here. How does the browser complete this cutting? There are three methods I have studied: Method 1: html event processing is to write the event functions directly in the html Tag, this write method is tightly coupled with html tags, so it is called html event processing. For example, the following code: <input type = "button" id = "btn" name = "btn" onclick = "alert ('click Me! ') "/> If the click Event function is complicated, it is inconvenient to write the code. Therefore, we often write the function externally. onclick calls the function name directly, for example: copy the Code <input type = "button" id = "btn" name = "btn" onclick = "btnClk ()"/> function btnClk () {alert ("click me! ");} Copy the code. The above is a very beautiful way of writing, so many people may unconsciously use it, but maybe many people do not know, in fact, the latter method is not as robust as the former method. This is also a problem I encountered when I recently studied the non-blocking loading script technology, because according to the front-end optimization principle, javascript code is usually at the bottom of the page. When the page is blocked by scripts, the referenced function in the html Tag may not be executed yet. At this time, we click the page button, in the result, "XXX function undefined error" is reported. In javascript, such an error is captured by try and catch. Therefore, to make the code more robust, We will rewrite it as follows: <input type = "button" id = "btn" name = "btn" onclick = "try {btnClk ();} catch (e) {} "/> I can hardly describe the code above. Method 2: DOM0-level event processing: DOM0-level event processing is supported by all browsers today. There is no compatibility problem. seeing such a sentence will make everyone who is working on the web Front-end very excited. The rule for DOM0 event processing is that each DOM element has its own event processing attribute, which can be assigned a function. For example, the following code: copy the code var btnDOM = document. getElementById ("btn"); btnDOM. onclick = function () {alert ("click me! ");} All the event attributes processed by the copy code DOM0 are defined using the" on + event name "method. The entire attribute is a lowercase letter. We know that DOM elements are a javascript Object in javascript code, so it is very easy to understand DOM0-level event processing from the javascript Object perspective. For example, the following code: btnDOM. onclick = null; The Button clicking event is canceled. Let's look at the following code: copy the code btnDOM. onclick = function () {alert ("click me! ");} BtnDOM. onclick = function () {alert (" click me1111! ");} Copy the code and the next function will overwrite the first function. Method 3: DOM2 event processing and IE event processing DOM2 event processing are standardized event processing solutions, but IE browser has developed a set of functions similar to DOM2 event processing, but the code is not exactly the same. Before proceeding to method 3, I must add some concepts. Otherwise, I cannot clarify the meaning of method 3. The first concept is: we often encounter this situation when developing an event stream on a page. The work interval of a page can be expressed in javascript using document, and a div exists in the page, div and so on overwrite the document element. The div contains a button element. The button element overwrites the div and overwrites the document, when we click this button, this click action not only happens on the button, but also the div and document are applied to the click operation, all three elements of logic can trigger click events, and event streams describe the concept of the preceding scenario. Event streams mean the order in which events are received from the page. The second concept: Event bubbling and event capture event bubbling are solutions proposed by Microsoft to solve event stream problems, while event capture is an event stream solution proposed by Netscape, their principles are as follows: bubble events start with div, followed by body, followed by document, and event capture is reversed first by document, followed by body, and finally by the target element div, in contrast, Microsoft's solution is more user-friendly and meets people's operating habits. The solution of Netscape is awkward. This is the consequence of the browser war, once the network view is slow, the problem of event stream is solved at the expense of user habits code. Microsoft has designed a new event System Based on the bubble event. It is often called ie event processing. The ie event processing method is shown in the following code: copy the code var btnDOM = document. getElementById ("btn"); btnDOM. attachEvent ("onclick", function () {alert ("Click Me! ") ;}); Copy the code to add an event in ie using the attachEvent method of the DOM element. Compared with DOM0 event processing, the method of adding an event is changed from attribute to method, therefore, when adding an event, we need to pass the parameter to the method. The attachEvent method receives two parameters. The first parameter is the event type. The name of the event type is the same as the name of the event in DOM0 event processing, the second parameter is the event function. The advantage of the method is that if we add a click event for the same element, as shown below: copy the code btnDOM. attachEvent ("onclick", function () {alert ("Click Me! ") ;}); BtnDOM. attachEvent (" onclick ", function () {alert (" Click Me, too! ") ;}); Copy the code and run it. Both the two dialogs can pop up normally. This allows us to add multiple click events for the DOM element. What if we don't want an event? How can we do this? ie provides the detachEvent Method for event deletion. The parameter list is the same as that of attachEvent. If we want to delete a click event, we only need to pass the same parameters as the added event, the following code is used: btnDOM. detachEvent ("onclick", function () {alert ("Click Me, too! ") ;}); Running, the consequences are very serious, we are confused, the second click is not deleted, what is going on? As I mentioned earlier, the same parameters must be input to delete events. However, in javascript anonymous functions, javascript uses different variable storage internally even if the code of the two anonymous functions is the same, the result is that the Click event cannot be deleted. Therefore, we need to write the code as follows: copy the code var ftn = function () {alert ("Click Me, too! ") ;}; BtnDOM. attachEvent ("onclick", ftn); btnDOM. detachEvent ("onclick", ftn); copy the code to add and delete methods that point to the same object, so the event is successfully deleted. The scenario here tells us that writing events requires a good habit that the operation functions should be defined independently, rather than using anonymous functions. The next step is DOM2 event processing. Its principles are as follows: DOM2 is a standardized event. When a DOM2 event is used, the event transmission starts from the capture method, that is, the document, and then to the body, div is a mediation point. When the event arrives at the mediation point, the event is in the target stage. After the event enters the target stage, the event starts to bubble processing, and the event ends on the document. (The starting point of the capture event and the end point of the bubble event. I will point to document in this article. The actual situation is that some browsers will capture the event from the window, and the window ends the bubble, however, I think that no matter how the browser sets it during development, we pay more attention to document, so I will use document here ). People are used to classify the target stage as a bubble, mainly because the bubble events in development are more widely used. DOM2 event processing is very difficult. Every time an event is pushed, all elements will be traversed twice. This is worse than the ie event. ie only has bubbles, So ie only needs to traverse once, however, missing traversal does not mean that the ie event system is more efficient. Supporting both event systems from the development and design perspective will bring us greater flexibility for development, from this perspective, the DOM2 event is very useful. The DOM2 Event code is as follows: copy the code var btnDOM = document. getElementById ("btn"); btnDOM. addEventListener ("click", function () {alert ("Click Me! ") ;}, False); var ftn = function () {alert (" Click Me, too! ") ;}; BtnDOM. addEventListener ("click", ftn, false); The addEventListener is used to copy the code to add events to DOM2 event processing. It receives three more parameters than ie event processing, the meaning of the first two parameters is the same as that of the ie event processing method. The only difference is that the on prefix must be removed from the first parameter, and the third parameter is a Boolean value, if the value is true, the event is captured and the value is false, with the third parameter, we can understand why the event element should be run twice in DOM2 event processing to be compatible with the two event models. However, pay attention to the following, no matter whether we choose capture or bubble, two traversal times will always be performed. If we choose an event processing method, no event processing function will be promoted in another event processing process, this is the same as the principle of idling when the vehicle is suspended. With the design of the DOM2 event method, we know that DOM2 events can only execute one of the two event processing methods at runtime, and it is impossible for the two event stream systems to simultaneously promote the development, therefore, although the elements are traversed twice, the event function cannot be pushed twice. Note that I do not mean to trigger the event function twice, we can simulate the simultaneous execution of two event stream models, for example, the following code: btnDOM. addEventListener ("click", ftn, true); btnDOM. addEventListener ("click", ftn, false); but this write method is multi-event processing, which is equivalent to clicking the button twice. DOM2 also provides a function to delete events, which is removeEventListener, written as follows: btnDOM. removeEventListener ("click", ftn, false); the same as the ie event, that is, the parameter must be consistent with the parameter for defining the event. However, when removeEventListener is used, the third parameter is not passed, the default value is to delete the bubble event, because if the third parameter is not passed, the default value is false, for example, btnDOM. addEventListener ("click", ftn, true); btnDOM. removeEventListener ("click", ftn); run and the event is not deleted successfully. Finally, I want to say that DOM2 event processing has been well supported in ie9 and ie9 and earlier versions, while ie8 and earlier versions do not support DOM2 events. The following is a comparison of the three event methods. Comparison 1: Method 1: Method 1: Method 1: Method 1: Method 1: Method 2: Method 1: Method 1: html and javascript are combined, you include me and you. To deepen this approach, you can develop html and javascript in hybrid development. In a software term, you can say that code coupling is not good, and code coupling is not good, this is the level of cainiao programmers, so the method is defeated, and the other two methods are defeated. Comparison 2: method 2 and method 3 are similar in writing, sometimes it is hard to say who is good or who is bad. Looking at the above content, we find that the biggest difference between method 2 and method 3 is: method 2: one DOM element, one event, and only one event. Method 3 provides multiple event processing functions for a DOM element event. In DOM2 event processing, method 3 also allows us to precisely control the event stream. Therefore, method 3 is more powerful than method 2, so method 3 is better than method 3. The following is the focus of this article: To solve the performance problem of the Event System, we must find a focus. Here, I will focus on the performance problem of the Event System from two points: reduce traversal times and memory consumption. The first is the number of traversal times. Whether it is capture event streams or bubble event streams, elements are traversed. Instead, elements are traversed starting from the top window or document. If the page DOM element has a deep parent-child relationship, the more elements traverse, such as DOM2 event processing, the greater the damage of traversal. How can we solve the problem of event stream traversal? My answer is no. Some of my friends may have questions. Why? In the event system, there is an event object, which has a method to prevent bubbling or capture events. How can I say no? This friend's question makes sense, but if we want to use this method to reduce traversal, our code should deal with the relationship between the parent and child elements. If there are many page elements nested, this is a task that cannot be completed, so my answer is that the traversal problem cannot be changed, and I can only adapt to it. It seems that reducing traversal will not solve the performance problem of the Event System, so now we only need to consider the memory consumption. I often hear people say that C # is very useful, and it is better for web Front-end development. We can drag a button directly to the page in C # IDE, when the button arrives at the page, javascript code automatically adds an event to the button. Of course, the event function is an empty function, so I think we can place 100 buttons on the page in this way, if no code works, there will be 100 button events for processing, which is super convenient. Finally, we add a specific button event to one of the buttons to let the page run, is this page highly efficient? In javascript, every function is an object, and every object consumes memory. Therefore, this useless 99 event Function Code certainly consumes a lot of valuable browser memory. Of course, we won't do this in the real development environment, but in today's era of ajax popularity and the popularity of single-page development, there are so many events on a single web page, this means that each event has an event function, but each operation will trigger only one event. At this time, all other events are lying down and sleeping, it does not play any role, but also consumes computer memory. We need a solution to change this situation, which is true in reality. In order to clearly describe this scheme, I need to add some background knowledge first. In the DOM2 event processing, I mentioned the concept of the target object and put aside the DOM2 event processing method, the concept of the target object also exists in capture event processing and bubble event processing. The target object is the DOM element of the specific event operation. For example, if you click a button in the operation, the target object is the target object, no matter which event processing method, the event function will contain an event object. The event object has a property target, which always points to the target object, and the event object has a property currentTarget, this attribute points to the DOM elements that capture or bubble events flow. As described above, event streams flow to the document, whether it is capture events or bubble events. If we add click events to the document, the buttons on the page do not add click events, at this time, we click the button and we know that the clicking event on the document will be promoted. Here, the details are that when the clicking event in the document is promoted, the target of the event points to the button instead of the document, then we can write the code like this: copy the Code <input type = "button" id = "btn" name = "btn" value = "BUTTON"/> <a href = "#" id = "aa"> aa </a> document. addEventListener ("click", function (evt) {var target = evt.tar get; switch (target. id) {case "btn": alert ("button"); break; ca Se "aa": alert ("a"); break ;}, false); copy the code and run it. We find that the effect is the same as that of the button event we write separately. But its advantage is self-evident. A function handles the event functions of the entire page, and no event functions are idle, Which is perfect. This solution also has a professional name: event Delegate. JQuery's delegate method is based on this principle. In fact, the efficiency of event delegation is not only reflected in the reduction of event functions, but also the reduction of dom traversal operations. For example, in the above example, we add a function on document, and document is the top-level object on the page, reading it is very efficient. When we get to the specific object event, we do not use dom operations but use the target attribute of the event object. All these can be summarized in one sentence: It is really fast, fast with no reason. Event delegation can also bring us a great by-product. Friends who have used jQuery should use the live method. The live method features that you can add event operations to page elements, even if this element does not exist on the page, you can add its events and understand the event Delegate mechanism. The live principle is quite understandable, in fact, jQuery live is implemented through event delegation, and live is also an efficient way to add events. After understanding the event Delegate, we will find that jQuery's bind method is an inefficient method, because it uses the original event definition method, so we should use bind with caution, in fact, jQuery developers have also noticed this problem. The new version of jQuery contains an on method. The on method contains all the functions of the bind, live, and delegate methods, therefore, I suggest that my friends who read this article discard the previous method of adding events and use the on function to add events. Event delegation has another benefit. In the preceding example, I add an event to the document. Here I want to make a comparison, in jQuery, we are used to putting the definition of DOM element events in the ready method, as shown below: $ (document ). ready (function () {XXX. bind ("click", function () {}) ;}); ready is executed after the DOM file on the page is loaded. It is better than the onload function in advance, one of the benefits is performance improvement. jQuery event definition is also a standard practice. I believe some friends will definitely bind some events outside ready, and finally find that the button will not work, this kind of ineffective scenario sometimes takes a moment, and it will take a while, so we often ignore the principle of this problem. Instead of binding events to the ready function, this operation is actually binding events before the DOM is loaded, in this time period, it is very likely that some elements have not been properly constructed on the page, so the event binding will be invalid. Therefore, the ready defines the event to ensure that the page After an element is loaded, the DOM element event is defined, but the problem can be avoided when event delegation is used. For example, binding an event to a document indicates the entire page, therefore, the loading time can be described as early as possible. Therefore, it is difficult to implement event delegation on the document to prevent invalid events, it is also difficult for the browser to report the problem of "XXX function undefined. To sum up this feature, the event delegated code can run at any stage of page loading. This gives developers more freedom to improve the web page performance or enhance the web page effect. Now, this article is complete. Good night.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.