Analysis and Optimization of a short section of jquery code

Source: Internet
Author: User
ArticleDirectory
    • Find the reason
    • Basic Optimization
    • Note Selector
    • Don't let JavaScript do anything.
    • Final supplement

When I got home today, I saw someone in the QQ Group asking for help to optimize jquery.CodeAfter a brief look, I found that if jquery is used only, but I don't know how to implement it, it is really easy to use problems. This is why I have never liked jquery recently. The API settings of this framework may mislead people.

The code to be optimized is roughly like this, and it is not convenient to directly copy the code of other people, which means:

  $. FN. beautifytable = function (options) {// define the default configuration item, and overwrite return this with options. each (function () {var table = $ (this), tbody = table. children ('tbody'), TR = tbody. children ('tr '), Th = tbody. children ('th'), TD = tbody. children ('td '); // class table with separate content. addclass (option. tableclass); th. addclass (options. headerclass); // 1 TD. addclass (options. cellclass); // 2 // The class tbody of the parity row. children ('tr: even '). addclass (options. evenrowclass); // 3 tbody. children ('tr: odd '). addclass (options. oddrowclass); // 4 // Alignment Method tr.children('th,td'hangzhou.css ('text-align ', options. align); // 5 // Add the mouse to hover the tr. BIND ('mouseover', addactiveclass); // 6 tr. BIND ('mouseout', removeactiveclass); // 7 // click to change the color tr. BIND ('click', toggleclickclass); // 8}) ;};  

In general, this code is good, with clear thinking, clear logic, and a clear explanation of what you want to do. However, according to the author, when there are 120 rows in the table, ie indicates that the script has been running for too long. Obviously, from the perspective of performance, this function is not efficient, or even extremely low.

Find the reason

As a result, we started to analyze the Code. This is a standard jquery plug-in function and has a typicalReturn this. Each (function (){...};);Code in the form. If the author writes this code without thinking about it, he should be aware of what a function of jquery has done.

Jquery. most of the functions under FN are called by an each. The so-called each essentially traverses the selected elements and performs specified operations on an element. Let's take a look at the code above and how much traversal is done. Here we assume that only 120 rows are selected, each row has 6 columns, and the header of one row is added:

    1. Traverse th and add headerclass with 6 elements.
    2. Traverse TD and add cellclass. The number of elements is 6*120 = 720.
    3. Find the odd number from all Tr and traverse all tr at a time. The number of elements is 120.
    4. Traverse the odd Tr and add evenrowclass. The number of elements is 120/2 = 60.
    5. Find the even number from all TR, and traverse all tr at a time. The number of elements is 120.
    6. Traverse the even number of TR and add oddrowclass. The number of elements is 120/2 = 60.
    7. Traverse all th and TD and add text-align. The number of elements is 120*6 + 6 = 726.
    8. Traverse all Tr and add a Mouseover event. The number of elements is 120.
    9. Traverse all Tr and add a mouseout event. The number of elements is 120.
    10. Traverse all Tr and add a click event. The number of elements is 120.

For convenience, we simply assume that it takes 10 ms to access an element during traversal. How long does this function take? This function has a total of 2172 elements, which takes 21720 ms, that is, 21 seconds. Obviously, ie must have reported that the script has been executed for too long.

Basic Optimization

Knowing the cause of low efficiency, we need to solve it fundamentally. Naturally, we need to find ways to merge loops. At first glance, follow the numbers in the notes in the above Code, at least the following points can be merged:

    • 3 and 4 can be combined into a loop, from 120 + 60 + 120 + 60 to 120, reducing by 240.
    • 1, 2, and 5 can be combined into a loop, from 6 + 720 + 726 to 726, reducing by 726.
    • 6, 7, and 8 can be combined into a cycle, from 120 + 120 + 120 to 120, reducing by 240.
    • Further, 3, 4, and 6, 7, and 8 can be combined into a loop, which is reduced by 120.

To sum up, we reduced the number of element operations by 240 + 726 + 240 + 120 = 1326, totaling 13260 Ms. After optimization, our function time is changed to 21720-13260 = 8460 ms, that is, 8 s.

Note Selector

There may be a question here. In terms of table structure, all th and TD elements must be within tr, so why don't we put the three steps 1, 2, and 5 in the same cycle of TR to form a nested loop? Isn't that faster?

There are two main reasons for not doing this:

First, no matter where the three elements 1, 2, and 5 are put, the access to all th and TD elements is not reduced.

On the other hand, the $ ('th, TD ') selector is translated into two calls to the getelementsbytagname function in sizzle. It gets all th for the first time and all TD for the second time, then merge the set. Because getelementsbytagname is a built-in function, it can be considered that this function does not carry loops, that is, the complexity is O (1). The same set is merged using array-related functions, is the memory operation, the complexity is also O (1 ).

Otherwise, if the $ ('th, 'td) selector is used in the loop of the tr element, the getelementsbytagname is called twice on the tr element, no matter which element calls the function, the function execution time is the same, so it is used in loop TR, instead of 119*2 more function calls, the efficiency is not increased or decreased.

It can be seen that the basic knowledge of the sizzle selector is also an important aspect to help optimize jquery code.

Don't let JavaScript do anything.

According to the previous optimization, the time has been reduced from 21 seconds to 8 seconds, but the 8 seconds is obviously unacceptable.

Further analysis of our code, in fact, loop traversal is language-level content, and its speed should be quite fast. The operations for each element are functions provided by jquery. Compared with traversal, they occupy the majority of resources. If the access element in the traversal process is 10 ms, you can say that the execution of an addclass is at least Ms.

Therefore, in order to further optimize the efficiency, we have to reduce the number of operations on elements. Review the code carefully and find that this function has many style modifications, including at least:

    • Add class to all th.
    • Add class to all TD.
    • Add a class to the tr parity row.
    • Add a text-align style to all th and TD.

In fact, we know that CSS itself has a child selector, and the efficiency of the browser native parsing CSS is much higher than that of letting JavaScript add class to elements one by one.

Therefore, if CSS is controllable, this function should not have the headerclass and cellclass configuration items, but should be configured in CSS as much as possible:

 
. Beautiful-Table Th {/* headerclass content */}. Beautiful-Table TD {/* cellclass content */}

Furthermore, for the tr parity row style, you can use the nth-Child pseudo class in Some browsers to implement it. In this respect, you can use the feature detection, add styles using addclass only in browsers that do not support this pseudo class. Of course, if you only want to optimize the IE series, this one can be ignored.

For Nth-Child pseudo-class detection, you can use the following methods:

    1. Create a stylesheet and create another rule, for example, # test span: Nth-child (ODD) {display: block ;}.
    2. Create an HTML structure, a div with the ID of test, and put three spans in it.
    3. Add stylesheet and Div to the DOM tree.
    4. View the display style of 1st and 3rd spans during runtime. If it is block, this pseudo class is supported.
    5. Delete the created stylesheet and Div. Do not forget to cache the test results.

Finally, you can use CSS to optimize the text-align style for all th and TD elements. Since you do not know which align is added, write more styles:

 
/* CSS style */. Beautiful-table-center th,. Beautiful-table-center TD {text-align: center! Important;}. Beautiful-table-Right th,. Beautiful-table-Right TD {text-align: Right! Important;}. Beautiful-table-left th,. Beautiful-table-left TD {text-align: left! Important;}/* JavaScript */table. addclass ('beauul ul-table-'+ options. Align );

Of course, the optimization mentioned above is based on the control of CSS. If CSS styles cannot be accessed, for example, this is a common plug-in function, it will be used by third parties that are completely uncontrollable. What should we do? There is no way at all:

    1. Find all CSS rules on the page, such as document. stylesheets.
    2. Traverse all rules and take out headerclass and cellclass in the configuration item.
    3. Extract all styles from several required classes and assemble them into new selectors, such as beautiful-Table th.
    4. Use the created selector to generate a new stylesheet and add it to the DOM tree.
    5. You can only add the class beautiful-table to the table.

Of course, the above practice is actually quite time-consuming. After all, we have to traverse stylesheet and create stylesheet. Is it a great help for efficiency improvement? It depends on the size of the page and whether it is used depends on the specific needs of function designers, here is a policy.

In general, by executing JavaScript as little as possible and handing over more styling tasks to CSS, the browser's rendering engine can further optimize the function, assuming that the call to addclass and CSS requires 120 ms, this optimization directly eliminates the original 726 + 846 = operations, saving 8 to Ms of time (of course there are exaggerated components, but for the consumption of the entire function, this is indeed a huge one ).

Final supplement

This article only involves the analysis, details, and optimization of jquery's entire operation process, some basic optimization methods are not mentioned, such:

    • First, remove the entire table from the DOM tree. After all the operations are completed, put back the Dom to reduce the repaint.
    • Change Mouseover and mouseout to mouseenter and mouseleave to reduce the execution of repeated event functions caused by the correct event bubble model.
    • For simple elements such as th and TD, the native getelementsbytagname is preferred to eliminate the time of sizzle analysis selector.

Finally, this article just wants to explain that for front-end developers, although the browser may be a black box, many frameworks, tools, and libraries are open, A certain degree of understanding before use will inevitably help improve personal technology and optimize the quality of the final product. It is a very taboo to "know it, but don't know why.

 

Permanent address: http://www.otakustay.com/jquery-code-optimization-1/

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.