Techniques for writing performance-efficient JavaScript events

Source: Internet
Author: User
Tags html tags new set

How to make an efficient web front-end program is every time I do front-end development will not consciously to consider the issue. A few years ago, Yahoo! Front-End engineers out a book on improving the Web front-end performance, sensational the entire web development technology community, so that the mysterious web front-end optimization problem became the main street cabbage, web front-end optimization into a novice and Daniel can answer simple questions, When the entire industry knows the secret of the answer, then the existing optimization technology can not be generated by the quality of the website you developed, in order to let us develop the site performance than other people's website better, we need more in-depth independent thinking, reserve more excellent skills.

The event system in JavaScript was the first breakthrough I thought of. Why is JavaScript an event system? We all know that the Web front end contains three technologies: how HTML, CSS, and javascript,html and CSS can be combined is a clear glance: Style, class, ID, and HTML tags, this is nothing to say, But how does JavaScript cut into the middle of HTML and CSS, so that the three of them merge? Finally, I found that this entry point is the JavaScript event system, no matter how much complex JavaScript code we write, ultimately through the event system in HTML and CSS, so I was thinking since the event system is the entry point of the three fusion, then a page, In particular, today's increasingly complex web pages will inevitably have a large number of event operations, without these events we have carefully written JavaScript code only fright, upsets. Since there are a lot of event functions on the page, can we write the event function according to our habit, there will be problems affecting efficiency? The answer I'm looking at is really efficient, and it's a serious problem of efficiency.

To clarify my answer, I want to explain the JavaScript event system in detail first.

The event system is a point of entry for JavaScript and HTML and CSS Fusion, which is like the main function in Java, where all the magic begins, so how does the browser complete this cut-in? I've been studying it. There are 3 different ways:

Way One: HTML Event Handling

HTML event processing is to write the event function directly in the HTML tag, because this kind of writing and HTML tags tightly coupled, so 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 complex, it is certainly inconvenient to write code so that we often write the function externally, and the onclick invokes the function name directly, for example:

<input type= "button" id= "btn" name= "btn" onclick= "BTNCLK ()"/>function btnclk () {         alert ("click me!");   }

  

The above is a very beautiful writing, so nowadays still a lot of people will not consciously use it, but perhaps a lot of people do not know, the latter kind of writing actually does not have the former form of robust, this is also I recently in the study of non-blocking loading script technology encountered problems, because according to the principle of front-end optimization, JavaScript code is often located at the bottom of the page, when the page is blocked by the script, the HTML tag referenced in the function may not be executed, this time we click on the page button, the results will be reported "xxx function undefined error", in JavaScript such errors will be the try , catch is captured, so in order to make the code more robust, we will have the following rewrite:

<input type= "button" id= "btn" name= "btn" onclick= "TRY{BTNCLK ();} catch (e) {} "/>

  

See the above code is a disgusting can describe.

Way two: DOM0 -level Event handling

DOM0-level event handling is event handling that is supported by all browsers today, and there are no compatibility issues, and seeing such a sentence will excite everyone who makes the web front end. The rule for DOM0 event handling is that each DOM element has its own event-handling property, which can assign a value to a function, such as the following code:

var btndom = document.getElementById ("btn"), Btndom.onclick = function () {         alert ("click me!");            }

  

Event properties for DOM0-level event handling are defined in the same way as the on+ event name, and the entire property is lowercase. We know that DOM elements are a JavaScript object in JavaScript code, so it's very easy to understand DOM0-level event processing from a JavaScript object's perspective, such as the following code:

Btndom.onclick = null;

  

Then the button's click event is canceled.

Then look at the following code:

Btndom.onclick = function () {         alert ("click me!"),            } Btndom.onclick = function () {         alert ("click me1111!");            }

  

The latter function overrides the first function.

Way Three: DOM2 event handling and IE Event Handling

DOM2 event handling is a standardized event-handling scheme, but IE has a set of features that are similar to DOM2 event handling, but the code does not write as much.

I have to add some concepts before I can explain the way it is, otherwise it is impossible to clarify the meaning of mode three.

  The first concept is: event flow

In the page development we often encounter this situation, a page of the working range in JavaScript can be represented by document, the page has a div,div and so on the document element, the DIV has a button element, The button element is covered in the Div, also equal to cover the document, so the problem comes, when we click on this button, this click Behavior in fact not only occurs on the button, Div and document are the action of the Click Operation, By logic, these three elements are all capable of promoting a click event, and the event flow is the concept of describing the above scenario, which means that the order of events is received from the page.

Second Concept: Event bubbling and event capture

Event bubbling is a solution that Microsoft has proposed to solve the event flow problem, and event capture is the event flow solution proposed by Netscape, which has the following principles:

Bubble event starts with Div, followed by body, finally document, event capture is the reverse of the first document, followed by the body, and finally the target element Div, in contrast, Microsoft's program more humane in line with people's operating habits, Netscape's program is very awkward, This is the consequence of the browser war, and Netscape was slow to resolve the flow of events at the expense of user-accustomed code.

Microsoft has designed a new set of event systems in conjunction with bubbling events, which the industry is accustomed to calling IE event processing, as shown in the following code:

var btndom = document.getElementById ("btn"); Btndom.attachevent ("onclick", function () {         alert ("click me!");});

Add events under IE through the DOM element's Attachevent method, and the way the events are added is changed from the property to the method by the DOM0 event processing, so we add the event 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 event name in the DOM0 event handler, the second argument is the event function, and the advantage of using the method is that if we are adding a click event for the same element, as follows:

Btndom.attachevent ("onclick", function () {         alert ("click me!");}); Btndom.attachevent ("onclick", function () {         alert ("click Me,too!");});

  

Running, the two dialogs will pop up normally, allowing us to add several different click events to the DOM element. What if we don't want an event? What do we do, IE provides the DetachEvent method for the Delete event, like the parameter list and attachevent, if we want to delete a click event, just pass and add the same parameters as the event, as shown in the following code:

Btndom.detachevent ("onclick", function () {         alert ("click Me,too!");});

  

Run, the consequences are very serious, we are confused, the second click Incredibly did not be deleted, what is the matter? I talked about deleting events to pass in and adding events to the parameters, but in the anonymous function of JavaScript, two anonymous functions, even if the code is exactly the same, JavaScript will be stored internally using different variables, the result is that we see the phenomenon can not delete the Click event, So our code is going to write this:

var ftn = function () {         alert ("click Me,too!");}; Btndom.attachevent ("onclick", ftn); Btndom.detachevent ("onclick", ftn);

  

This method of adding and removing means pointing to the same object, so the event was deleted successfully. the scene here tells us that writing events to have a good habit that the operation function to be defined independently, do not use anonymous functions as a habit.

Next is the DOM2 event handler, which works as follows:

DOM2 is a standardized event that uses the DOM2 event, where the event is first started from the capture mode, from document to Body,div, to a mediation point where the event is at the target stage and the event starts bubbling when the event enters the target phase. The last event ends on document. (Capturing the starting point of the event and the end of the bubbling event, I am pointing to document, the reality is that some browsers will start from Window capture, window end bubbling, but I think the development time regardless of how the browser itself, we focus on document more development significance, So I use document all the same here. It is customary to classify the target phase as part of the bubble, mainly because of the wider use of bubbling events in development.

DOM2 event processing is very frustrating, each time the event to promote the time will be all elements traversed two times, this and IE event performance is much worse, ie only bubbling, so ie only need to traverse once, but the traversal is less does not mean that IE's event system more efficient, From the point of view of development and design to support two kinds of event system will give us the development of more flexibility, from this point of view, DOM2 event is very desirable. The code for the DOM2 event is as follows:

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);

  

DOM2 Event Processing Add event using AddEventListener, it receives three parameters than IE event processing one, the first two meaning and IE event processing method of two parameters, the only difference is the first parameter to remove the prefix, the third parameter is a Boolean value, If its value is true, then the event is handled according to the capture, the value is False, the event is bubbling processing, there is a third parameter we can understand why DOM2 event processing in the event element to run two times, the purpose is to be compatible with the two event models, but here to be aware, Whether we choose to capture or bubble, two times traversal is always done, if we choose an event processing method, then another event processing process will not trigger any event handler function, which is the same as the car hanging empty block idling. Through the design of the DOM2 event method, we know that the DOM2 event can only perform one of two event handling methods at runtime, it is not possible to promote the two event flow system at the same time, so although the element is traversed two times, the event function can never be sent two times, note that I do not mean to promote the hair two times is an event function, In fact, we can simulate the simultaneous execution of two event flow models, such as the following code:

Btndom.addeventlistener ("click", Ftn,true); Btndom.addeventlistener ("click", Ftn,false);

  

But this notation is multi-event processing, equivalent to the two times we clicked the button.

DOM2 also provides a function to delete events, this function is RemoveEventListener, the following syntax:

Btndom.removeeventlistener ("click", Ftn,false);

  

Using the same arguments as the IE event, the parameters are consistent with the parameters that define the event, but when the RemoveEventListener is used, the third parameter does not pass, the default is to delete the bubbling event, because the third parameter does not pass the default is False, for example:

Btndom.addeventlistener ("click", Ftn,true); Btndom.removeeventlistener ("click", FTN);

  

Run, the event was found to have not been deleted successfully.

Finally, I would like to say that the DOM2 event processing in IE9 including IE9 above the version has been well supported, IE8 the following is not supported DOM2 events.

Below we compare three kinds of event modes, compare the following:

Comparison one: The way one is compared with the other two ways

Method One is the combination of HTML and JavaScript, you have me I have you, the way to deepen this is the HTML and JavaScript mixed development, with a software term expression is code coupling, code coupling is not good, and is very bad, this is the level of novice programmers, So the way one failed, the other two ways to win the victory.

Comparison two: Way Two and way three

They are two of the same way, sometimes it is really difficult to say who is good who is bad, looking at the above content we found that the biggest difference between the way two and mode three is: the use of 21 DOM elements an event has and only once, and the way three can let DOM element an event has more than one event handler, in the DOM2 event processing, Mode three also allows us to precisely control the way the event flows, so the function of mode three is more powerful than the way two, so in contrast to the three notch above.

Here is the focus of this article: the performance of the event System , to solve the performance problem must find a point of focus, here I from two points to think about the performance of the event system, they are: Reduce the number of traversal and memory consumption.

The first is the number of traversal, whether it is capturing the event flow or bubbling event flow, will traverse the elements, but all from the top of the window or document start traversal, if the page DOM elements of the parent-child relationship is very deep, then the more elements traversed, such as DOM2 event processing, the greater the degree of traversal hazards, How to solve this event flow traversal problem? My answer is no, there are some friends here may have doubts, how can there be no? There is an event object in the event system, which has a method to block bubbling or capturing events, and what do I say? This friend's question is very reasonable, but if we want to use this method to reduce traversal, then our code will deal with the relationship between the parent-child element, the relationship between the sun and the elements, if the page elements nested many, this is impossible to complete the task, so my answer is unable to change the traversal of the problem, only to adapt to it.

It appears that reducing traversal is not a solution to the performance of the event system, and now only the memory consumption is considered. I often hear people say that C # is very useful, for the Web front-end development It is better to use, we can directly in the C # IDE Drag a button to the page, a button to the page after the JavaScript code will automatically add an event for the button, of course, the event function is an empty function, So I think we can in this way in the page to place 100 buttons, a code does not have 100 button event processing, super convenient, finally we add a button to one of the buttons of the event, let the page run up, will everyone this page efficiency is high? In JavaScript, each function is an object, and each object consumes memory, so this useless 99 event function code certainly consumes a lot of valuable browser memory. Of course we do not do this in the real-world development environment, but in today's Ajax epidemic, single page development of the crazy popularity of the era, a page of events are very much, which means we each event has an event function, but every time we operate will only promote an event, when other events are lying down to sleep, Does not have any effect and consumes the memory of the computer.

We need a programme to change this situation, which is true in reality. In order to clearly describe this scheme, I would like to add some background knowledge, in the DOM2 event processing I mentioned the concept of target object, put aside the DOM2 event processing, in the capture event processing and bubbling event processing also has the concept of target object, the target object is the event of the specific operation of the DOM element, For example, the button in the button action is the target object, regardless of which event processing method, the event function will contain an event object, which has a property target,target is always pointing to the target object, the event object has a property is Currenttarget, This property points to the DOM element that the capture or bubbling event flows to. We know from the above that, whether it is capturing events or bubbling events, the event flow will flow to document, if we add a click event on the document, the button on the page does not add click events, when we click on the button, we know that the Click event on the document will be sent, One of the details here is to promote the document Click event, the target of the event is a button instead of document, then we can write 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.target;         Switch (target.id) {case                   "BTN":                            Alert ("button");                            break;                   Case "AA":                            alert ("a");                            break;         }},false);

Run, we found that the effect was the same as we wrote the button event individually. But its benefits are self-evident, a function of the entire page of the event function, and no event function is idle, simply perfect, this program also has a professional name: Event delegation. The delegate method of jquery is based on this principle. In fact, the efficiency of event delegation is not only reflected in the reduction of event function, it can also reduce the DOM traversal operation, for example, in the above example we add a function on the document, the document is the top-level object in the page, reading it is very efficient, To a specific object event we do not use the DOM operation but the target property of the event object, all of which can be summed up in a nutshell: Fast, no reason.

Event delegation can also give us a good by-product, the use of jquery friends should have used the live method, the live method is characterized by you can add event action for the page element, even if the element currently does not exist in the page, you can also add its events, understand the event delegation mechanism, The principle of live is very good understanding, in fact, jquery Live is through the event entrusted to do, while live is an efficient way to add events.

Understanding the event delegate, we will find that jquery's Bind method is an inefficient method, because it uses the original event definition, so bind we have to use caution, in fact, jquery developers also notice this problem, the new version of jquery has an on method, The On method contains all the functions of the bind, live, and delegate methods, so I recommend that friends who have read this article discard the previous way of using Add events and use the on function to add events.

There is another benefit to the event delegate, the example of the event delegate above, I am adding an event to the document, here I want to make a comparison, in jquery we are accustomed to the DOM element event definition in the Ready method, as follows:

$ (document). Ready (function () {    xxx.bind ("click", Function () {});});

The READY function is executed after the page DOM document has been loaded, it executes before the OnLoad function, which is a lot of advance benefits, one of the benefits is also a performance improvement, jquery such an event definition is a standard practice, I believe that some friends must also put some event bindings outside of Ready, Finally found that the button will be invalid, this invalid scene sometimes Flash, a little later, so we often neglect the principle of the problem, not the ready function binding event, this operation is actually before the DOM loading completed before the binding event, and this time period, it is possible that some elements are not in the construction of the page, So the event binding is invalid, so the ready definition event is to ensure that all elements of the page are defined in the event of the DOM element after it has been loaded, but the event delegate can be used to avoid problems, such as binding events to document,document on behalf of the entire page. So it is the earliest time to load, so in the document to implement event delegation, it is very difficult to happen the event is invalid, it is difficult to get the browser to report "xxx function undefined" problem. Summarize this feature: event delegate code can be run at any stage of page loading, which gives developers more freedom to improve web page performance or enhance Web page effects .

All right, this article is finished. Good night.

Techniques for writing performance-efficient JavaScript events

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.