The essentials and extensions of high-performance JavaScript (bottom)

Source: Internet
Author: User
Tags setinterval

Sixth. Quick Response User Interface

This chapter begins with the concept of the browser UI thread, and I suddenly think of a small example of a problem that is often encountered by friends who write CSS3 animations:

<Head>    <MetaCharSet= "UTF-8">    <title>Title</title>    <style>Div{width:50px;Height:50px;background:Yellow;}. Act{width:100px;transition:width 0.5s;}    </style></Head><Body><Divclass= "Act"></Div><Button>Click Me</Button><Script>    varbtn=Document.queryselector ('Button'); varDiv=Document.queryselector ('Div'); Btn.onclick= function() {div.classname= "'; Div.classname= 'Act'; }</Script></Body>

As the code shows, we want to click on the button, the div can be removed by removing the class into the 50px, and then add it back to class to trigger the animation (0.5 seconds, the width from 50px to 100px),

But this code execution effect is--no effect (the screen software is a bit compatible bug in Win10, the mouse is offset):

The solution is simple-just put a settimeout on it:

    function () {        = ';        SetTimeout (function() {            = ' act ';         0)    }

EXECUTE as follows:

The principle is that we use the setTimeout to prioritize the first UI event of the Div, rather than the div.classname = ' act ' behind the execution.

When the user taps the button (the code without settimeout), it actually happens:

⑴ui Event--Updates the UI of the button so that the user can "see" it is clicked. Also put the callback event into the event queue.

The ⑵js event a--executes a callback event, executes the first line of div.classname = " , removes the div's class name, and generates a UI event A (a re-rendered Div) to be placed in the event queue for idle.

The ⑶js event b--continues with the callback event, adding a class called "act" to the Div, which still generates a UI event B (re-rendering Div) and waits in the queue.

⑷ui event a--The UI event in the event queue begins to enter the UI thread as a FIFO as the UI thread in the browser does not already have any task in execution (the callback has completed and is idle).

The ⑸ui event b--is the same as UI event A, which renders the rendering process according to the current style of the Div.

(When the mapping is not clear, the event A/b is written as event 1/2, we have to replace the brain of it)

The addition of SetTimeout then becomes:

⑴ui Event--Updates the UI of the button so that the user can "see" it is clicked. Also put the callback events (JS events A and B) into the event queue.

The ⑵js event a--executes a callback event, executes the first line of div.classname = " , removes the div's class name, and generates a UI event A (a re-rendered Div) to be placed in the event queue for idle.

⑶ui event a--Because JS event B has a delay feature, the queue members behind the event queue are released first, so that UI event a executes first. When the div loses its class, it is rendered as 50px width according to the current valid style.

The ⑷js event b--continues with the callback event, adding a class called "act" to the Div, and still generating a UI event B (re-rendering Div) and waiting in the queue.

⑸ui event B--div is added to the class, so it is rendered as 100px width according to the current valid style.

⑹ui Event c--The animation event is triggered because the width of the div has changed.

In general, we know a little bit about the workflow of the browser UI thread (the main thread), but the regular browser does not only have one thread running, but its main threads can be categorized as:

In addition, we look back at settimeout/setinterval these two time mechanisms, they actually just put the callback event into the queue in a "comity" state waiting, if there are event members then comity to the rear first out of the team.

This is the same as node's setimmediate, the difference is that the setimmediate is not limited by the delay when the event loop is executed at the end of the wheel.

Then give SetTimeout a value of 0 delay, whether the implementation of the Setimmediate function? The answer is no, in the book "Timer accuracy" section has mentioned, JS time mechanism is not accurate, it is affected by the system/client timer resolution (such as window under 15 milliseconds), so there will be millisecond-level bias.

But the truth here is that the time mechanism in--JS is not a purely asynchronous event, it still walks the UI single thread, only "Jianfengchazhen" to the UI thread when the event queue is empty, creating an "asynchronous" illusion.

By the way also mentioned here, JS really go asynchronous should be the following several events:

1. Ajax
2. event (e.g. listening click)
3. Requestaninmationframe
4. Websql, Indexdb
5. Web Worker
6. PostMessage

Seventh Chapter Ajax

The "Dynamic Script Injection" section describes the JSONP principle-the front-end contract good one callback name, which wraps the package data of the script request within the callback name, and the client pulls the callback back into the package with eval to trigger the callbacks immediately.

In addition to JSONP we can still have a lot of cross-domain communication implementations, can refer to my old article.

The "Multipart XHR" mentioned in this chapter is actually a realization of domain name convergence, such as the following single request to return to the corresponding multiple script resources:

http://imgcache.gtimg.cn/c/=/club/qv/pkg/qv_1.x.x.js,/clubact/premin/jquery.webStorage.min.js,/clubact/common/ Oz.js,/clubact/common/aid.js,/clubact/common/mustache.js,/clubact/common/nav/youxi_nav.js

But here's an interesting deal--if the MXHR response is out very much, wait until all the data comes back to do a bit of slow, we can listen to XHR readyState to advance processing.

When ReadyState is 3 o'clock, it means that the client has already started to download the package (including the header), and then we can process it in advance by polling (mainly to disassemble and extract the merged resources in the package):

varreq =NewXMLHttpRequest ();varGetlatestpacketinterval, lastlength = 0; Req.open (' GET ', ' rollup_images.php ',true); Req.onreadystatechange=Readystatehandler;req.send (NULL);functionreadystatehandler{if(Req.readystate = = = 3 && Getlatestpacketinterval = = =NULL) {        //Start PollingGetlatestpacketinterval = Window.setinterval (function() {getlatestpacket (); }, 15); }    if(Req.readystate = = 4) {        //Stop Pollingclearinterval (Getlatestpacketinterval); //Get last packetGetlatestpacket (); }}functionGetlatestpacket () {varLength =req.responseText.length; varPacket =req.responseText.substring (lastlength, length);    Processpacket (packet); Lastlength=length;}

The next mentioned Beacons is actually an image ping technique, which is used for cross-domain communication (mainly for statistics). However, the service-side response processing mentioned here is still worth a look:

1. The service side returns the real picture data, the client can determine the picture width to understand the state;

2. If the client does not need to know the server state, it returns 204 without the message body.

Eighth Chapter Programming Practice

This chapter provides some suggestions for readers to avoid using some of the most performance-friendly programming practices.

1. Avoid double evaluation

Some of the interfaces provided in JS allow you to enter strings to compile and execute, and Eval is the most familiar method. In addition to Eval, the following methods are included:

⑴ creates the function in the form of new function () ; ⑵ lets settimeout/setinterval execute the string.

These methods will let the JS engine do string parsing, and then do evaluation processing, resulting in double evaluation, performance overhead will become larger, so it is not recommended to use the general.

If you have to parse the large JSON string returned by the server, you can open a Web Worker to do asynchronous processing.

2. Use Object/array Direct volume

 //    o = {};o.a  = 1;o.b  = 2; //  recommended  var  o = {a:  1  2 / /  var  arr = new   Array (); arr[ 0] = 1;arr[ 1] = 2  //  recommended  var  arr = [1, 2]; 

Using "recommended" direct volume processing to define an object will get faster execution speed and also help reduce file volume.

3. Avoid duplication of effort

Most of the development will be ignored, that is, encapsulated in a method of functional branch judgment, each time the method is called, will be re-made redundant judgment:

function AddHandler (target, EventType, handler) {    if(target.addeventlistener) {          False)    Else  {        target.attachevent (' on ' +EventType, handler)    } }

If the event binding interface above is called each time, it is necessary to do an event to add a handle to the judgment.

The workaround for this problem is to internally override the interface (lazy load):

function AddHandler (target, EventType, handler) {    if(target.addeventlistener) {          function(target, EventType, handler) {            false)        }    else {        function(target, EventType, handler) {            target.attachevent (' on ' +  EventType, Handler)        }    }    // deferred loading }

4. Use the fastest part

⑴ bit operation

JS bit operations will be much faster than other calculations, and if used properly, can improve script execution speed.

For example, we will use if (i%2) to determine if I is an odd or even number, if the condition is changed to if (I & 1) will get the same result, but 50% faster.

This section also mentions the use of "bitmask", which is an interesting logical recognition process.

For example, in the Hand Q Web page development, we will use a "_WV" parameter to know whether the client (hand Q) shows the return button, share button, and how to display the sharing panel and other functions.

There are similar mappings for this parameter:

When we give the URL the _WV parameter value 21 (i.e. 16 + 4 + 1), hand Q hides the return button and the bottom bar for the value of the parameter, and configures the option to not have space in the share panel.

While we are writing JS, we can use bit masks to achieve the same processing.

We still use the above mapping table, but instead of using additive processing, we use bit processing:

var WV = 16 | 4 | 1; // Identification Processing if (WV & 1) {    // Hide Back button }if(WV & 2) {    //  Hide Share button } ... // omit branches of 4 and 8 if (WV & +) {    // share panel hide space Sharing }

⑵ Native method

That is, using the native Math interface to implement complex computations and using native selectors (such as Queryselector) to select the DOM.

As for the following two chapters, the main reference is the front-end construction and testing tools, some of the technology or eliminated things will not be described. Mutual Encouragement ~

The essentials and extensions of high-performance JavaScript (bottom)

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.