Writing high performance JavaScript (translation) _javascript techniques

Source: Internet
Author: User
Tags benchmark closure event listener garbage collection object model chrome developer chrome developer tools fast web

The translator presses: I first translation foreign language, the speech unavoidably some obscure, but as far as possible expressed the author's original intention, does not have the excessive polishing, welcome criticizes the correction. Another text is long, the information is big, may be difficult to digest, welcome the message to discuss the detail question. This article focuses on the performance optimization of V8, some content does not apply to all JS engines. Finally, reprint please indicate the source:)

======================== Line ===========================

Many JavaScript engines, such as Google's V8 engine (used by chrome and node), are designed specifically for large JavaScript applications that need to be executed quickly. If you are a developer and care about memory usage and page performance, you should know how the JavaScript engine works in the user's browser. Whether it's V8,spidermonkey (Firefox) Carakan (Opera), Chakra (IE) or other engines, doing so can help you better optimize your application . This is not to say that you should specifically optimize for a particular browser or engine, don't do that.

But you should ask yourself a few questions:

    • In my code, can I make the code more efficient
    • What is the optimization of the mainstream JavaScript engine
    • What the engine cannot optimize, and whether the garbage collector (GC) can reclaim what I want

Loading A Fast Web site is like a fast sports car that requires specially tailored parts. Image source: Dhybridcars.

There are some common pitfalls in writing high-performance code, and in this article we will show some of the more validated and better ways to write code.

So, how does JavaScript work in V8?

If you don't have a deep understanding of the JS engine, it's no problem to develop a large web application, just like a driver who has seen the hood without looking at the engine inside the hood. Since Chrome is my browser's first choice, talk about its JavaScript engine. The V8 is composed of the following core components:

    • a basic compiler that parses JavaScript code and generates local machine code before it executes, rather than executing bytecode or simply explaining it. These codes were not initially highly optimized.
    • V8 the object as an object model . Objects in JavaScript are represented as associative arrays, but in V8 objects are treated as hidden classes, an internal type system for optimizing queries.
    • The Runtime Analyzer monitors the running system and identifies "hot" functions (such as code that takes a long time to run).
    • optimizes the compiler to recompile and optimize code that is identified by the runtime parser as "hot" and perform optimizations such as "inline" (for example, replacing a function call with the principal of the callee).
    • V8 support to optimize , which means that the optimization compiler will discard optimized code if it finds that it is overly optimistic about the assumption of code optimization.
    • V8 has a garbage collector , and it's just as important to know how it works and to optimize JavaScript.

Garbage collection

Garbage collection is a form of memory management that is actually a collector concept that attempts to reclaim the memory occupied by objects that are no longer in use. In JavaScript, the garbage collection language, objects that are still referenced in the application are not purged.

Manual elimination of object references is not necessary in most cases. Everything will work very well by simply placing variables where they are needed (ideally, as far as possible, as local scopes, that is, in the function they are using rather than the outer layer of the function).

The garbage collector attempts to reclaim memory. Photo Source: Valtteri Mäki.

In JavaScript, it is not possible to enforce garbage collection. You should not do this because the garbage collection process is controlled by the runtime and it knows what is the best time to clean up.

Misunderstanding of "eliminating references"

There are a lot of discussions on JavaScript memory recycling on the web. The Delete keyword, although it can be used to delete the attributes (key) in the object (map), some developers think it can be used to force "eliminate references." It is recommended to avoid using delete as much as possible, in the following exampledelete o.x 的弊大于利,因为它改变了o的隐藏类,并使它成为一个"慢对象"。

var o = {x:1}; 
Delete o.x; True 
o.x;//undefined

You will easily find references to delete in the popular JS library--It's language-purposeful. The thing to note here is to avoid modifying the structure of the hot object at run time. The JavaScript engine can detect this "hot" object and try to optimize it. If the object's structure does not change significantly in its lifecycle, the engine will be more likely to optimize the object, and the delete operation will actually trigger this larger structural change, which is not conducive to engine optimization.

There are also misconceptions about how NULL works. Setting an object reference to null does not change the object to "empty", but it simply sets its reference to NULL. Using o.x= null is better than using delete, but it may not be necessary.

var o = {x:1}; 
o = null;
O Null
o.x//TypeError

If this reference is the last reference to the current object, the object will be garbage collected. If this reference is not the last reference of the current object, the object is accessible and will not be garbage collected.

Also note that global variables are not cleaned up by the garbage collector during the life cycle of the page. Regardless of how long the page is open, the JavaScript runtime variable in the global object scope persists.

var myglobalnamespace = {};

Global objects are cleaned only when you refresh the page, navigate to another page, close a label page, or exit the browser. The variables of the function scope are cleared when the scope is exceeded, that is, when the function is exited, there is no reference, and the variable is cleared.

Rule of thumb

In order for the garbage collector to collect as many objects as possible at the earliest possible time, do not hold objects that are no longer used . Here are a few things to remember:

    • As mentioned earlier, using variables in the right range is a better choice to manually eliminate references. That is, a variable is only used in a function scope, do not declare it in the global scope. This means more clean and hassle-less code.
    • Be sure to unbind event listeners that are no longer needed, especially those that are bound by Dom objects that are about to be destroyed.
    • If the data used is cached locally, be sure to clean up the cache or use the aging mechanism to avoid large amounts of data that is not reused to be stored.

Function

Next, let's talk about functions. As we have said, garbage collection works by reclaiming memory blocks (objects) that are no longer accessed. To better illustrate this point, here are some examples.

function foo () {
 var bar = new Largeobject ();
 Bar.somecall ();
}

When Foo returns, the object that bar points to will be automatically recycled by the garbage collector because it has no existing references.

Compare:

function foo () {
 var bar = new Largeobject ();
 Bar.somecall ();
 return bar;
}

Somewhere else
var b = foo ();

Now we have a reference to the bar object, so that the life cycle of the bar object lasts from the call of Foo until the caller specifies another variable B (or b out of range).

Closure (CLOSURES)

When you see a function that returns an intrinsic function, the internal function will gain access outside the scope, even after the external function executes. This is a basic closure--An expression of a variable that can be set in a particular context. For example:

function sum (x) {
 function Sumit (y) {return
  x + y;
 };
 return sumit;
}

Usage
var SumA = SUM (4);
var sumb = SumA (3);
Console.log (SUMB); Returns 7

The function object (SUMIT) generated in the sum invocation context cannot be reclaimed, it is referenced by global variables (SumA), and can be invoked through SumA (n).

Let's take a look at another example, where can we access variable largestr?

var a = function () {
 var largestr = new Array (1000000). Join (' x ');
 return function () {return
  largestr;}
 ;
} ();

Yes, we can access largestr through a (), so it's not recycled. What's the bottom one?

var a = function () {
 var smallstr = ' x ';
 var largestr = new Array (1000000). Join (' x ');
 return function (n) {return
  smallstr;}
 ;
} ();

We can't visit largestr anymore, it's already a garbage collector candidate. "Translator Note: Because LARGESTR no longer has an external reference."

Timer

One of the worst memory leaks is in the loop, or in settimeout ()/setinterval (), but this is fairly common. Consider the following example:

var myobj = {
 callmemaybe:function () {
  var myref = this;
  var val = settimeout (function () { 
   Console.log (' time is running out! '); 
   Myref.callmemaybe ();
  }, 1000);
 }
;

If we run Myobj.callmemaybe () to start the timer, we can see that the console prints "time is running out!" every second. If you then runmyObj = null,定时器依旧处于激活状态。为了能够持续执行,闭包将myObj传递给setTimeout,这样myObj是无法被回收的。相反,它引用到myObj的因为它捕获了myRef。这跟我们为了保持引用将闭包传给其他的函数是一样的。

It is also worth remembering that references in Settimeout/setinterval calls (such as functions) will need to be executed and completed before they can be garbage collected.

Beware of performance traps

Never optimize the code until you really need it. Now you can often see benchmark tests that show that n is more optimized than M in V8, but testing in the module code or application will find that these optimizations actually have a much smaller effect than you expect.

Doing too much is better than doing nothing. Image source: Tim sheerman-chase.

For example, we want to create such a module:

    • Requires a local data source containing a digital ID
    • Draw the table that contains the data
    • Add an event handler to toggle the cell's CSS class when the user clicks on any cell

This problem has several different factors, although it is easy to solve. How do we store data, how to efficiently draw tables and append into the DOM, and how to better handle table events?

The first (naïve) approach to these problems is to use the object to store the data and put it in an array, use jquery to traverse the data-drawing table and append into the DOM, and finally use the event to bind us to the desired click behavior.

Note: This is not what you should do.

var Modulea = function () {return

 {

  data:dataarrayobject,

  init:function () {
   this.addtable ();
   This.addevents ();
  },

  addtable:function () {for

   (var i = 0; i < rows; i++) {
    $tr = $ (' <tr></ Tr> ');
    for (var j = 0 J < This.data.length J + +) {
     $tr. Append (' <td> ' + this.data[j][' id '] + ' </td> ');
    $tr. Appendto ($tbody);}

  },
  addevents:function () {
   $ (' table TD '). ON (' click ', Function () {
    $ (this). Toggleclass (' active ');}
   );
  }
();

This code completes the task simply and efficiently.

But in this case, the data we're traversing is just a numeric attribute ID that should simply be stored in the array. Interestingly, using the DocumentFragment and local DOM methods directly is a better choice than using jquery (in this way) to generate tables, and of course, event proxies have a higher performance than binding each TD individually.

Note that while jquery uses documentfragment internally, in our case, the code calls append within the loop and these calls involve some other little knowledge, so the optimizations here are not very useful. Hopefully this will not be a pain point, but be sure to make a benchmark test to make sure your code is OK.

For our example, the above approach has resulted in (expected) performance improvements. The event agent is an improvement to simple bindings, and optional documentfragment also helps to push the load.

var moduled = function () {return

 {

  Data:dataarray,

  init:function () {
   this.addtable ();
   This.addevents ();
  },
  addtable:function () {
   var td, TR;
   var frag = Document.createdocumentfragment ();
   var frag2 = Document.createdocumentfragment ();

   for (var i = 0; i < rows; i++) {
    tr = document.createelement (' tr ');
    for (var j = 0; J < This.data.length; J + +) {
     td = Document.createelement (' TD ');
     Td.appendchild (document.createTextNode (this.data[j));

     Frag2.appendchild (TD);
    Tr.appendchild (FRAG2);
    Frag.appendchild (TR);
   }
   Tbody.appendchild (Frag);
  },
  addevents:function () {
   $ (' table '). On (' Click ', ' TD ', function () {
    $ (this). Toggleclass (' active ');}};}

();

Next look at other ways to improve performance. You might have read it somewhere. Using prototype mode is better than module mode, or you've heard that using the JS template framework is a good performance. Sometimes this is true, but they are actually used to make the code more readable. That's right, and precompiled! Let's see how it behaves in practice.

Moduleg = function () {};

ModuleG.prototype.data = DataArray;
ModuleG.prototype.init = function () {
 this.addtable ();
 This.addevents ();
};
moduleG.prototype.addTable = function () {
 var template = _.template ($ (' #template '). text ());
 var html = template ({' Data ': This.data});
 $tbody. Append (HTML);
moduleG.prototype.addEvents = function () {
 $ (' table '). On (' Click ', ' TD ', function () {
  $ (this). Toggleclass (' Active ');
 };

var modg = new Moduleg ();

It turns out that the performance boost in this case can be negligible. The choice of templates and prototypes does not really provide much more stuff. That is, performance is not why developers use them, but the readability, inheritance model, and maintainability of the code are the real reasons.

More complex issues include the efficient drawing of pictures on canvas and the manipulation of pixel data with or without an array of types.

Before you apply some methods to your own application, be sure to learn more about the benchmarking of these scenarios. Maybe someone remembers the shoot-off of JS templates and the extended version later. You need to be aware that benchmarking is not a virtual application that you can't see, but rather a test of the optimizations that you can bring to your actual code.

V8 Optimization Techniques

The optimization points of each V8 engine are described in detail outside the scope of this article, and there are certainly a number of techniques worth mentioning here. With these tips in mind, you'll be able to reduce the low performance code.

    • Specific patterns can make V8 out of the dilemma of optimization, such as Try-catch. For more information on which functions can or cannot be optimized, you can use the –trace-opt file.js command in the V8 scripting tool D8.
    • If you care about speed, try to make your function single, that is, ensure that variables (including attributes, arrays, function arguments) use only objects contained in the same hidden class. For instance, don't do this:
      function add (x, y) {return 
       x+y;
      } 
      
      Add (1, 2); 
      Add (' A ', ' B '); 
      Add (my_custom_object, undefined);
    • Do not load uninitialized or deleted elements. If you do so, there will be no errors, but this will slow down.
    • Do not make the function body too large, which makes optimization more difficult.

More content can go to see Daniel Clifford in Google I/O sharing breaking the JavaScript Speed Limit with V8. Optimizing for V8-a series is also well worth reading.

Object vs Array: Which should I use?

    • If you want to store a bunch of numbers, or some objects of the same type, use an array.
    • If you need semantically the attributes of a bunch of objects (different types), use an object and attribute. This is very efficient and very fast in memory.
    • The elements of an integer index, whether stored in an array or an object, are much faster than the properties that traverse the object.
    • Objects have complex properties: they can be created by setters, with different enumerations and writable features. In an array, there is no such customization, and there are only two states of existence and none. At the engine level, this allows for more optimization of the storage structure. In particular, when there are numbers in an array, such as when you need a container, you do not have to define a class with the X,y,z attribute, but only an array.

One of the main differences between objects and arrays in JavaScript is the Magic length property of arrays. If you maintain this property yourself, the speed of objects and arrays in V8 is just as fast.

Tips for working with objects

    • Use a constructor to create the object. This ensures that all objects it creates have the same hidden classes and helps avoid changing these classes. As an additional benefit, it is also slightly faster than object.create ()
    • In your application, there is no limit to the use of different types of objects and their complexity (within a reasonable range: Long prototype chains are often harmful, rendering only a very small number of objects faster than larger objects). For "hot" objects, try to keep a short prototype chain, and less attributes.

Object cloning

For application developers, object cloning is a common problem. Although benchmark tests can prove that V8 has handled the problem well, be careful. Copying big things is usually slower--don't do that. For in JS.. The in loop is especially bad because it has a demon-like specification and it may never be faster than any object in either engine.

Use an array or a custom copy constructor feature to explicitly copy each attribute when you are sure to copy the object on the key-capable code path. This is probably the quickest way:

function Clone (original) {
 this.foo = Original.foo;
 This.bar = Original.bar;
}
var copy = new Clone (original);

Caching functions in module mode

Caching functions when using module mode can lead to performance improvements. See the following example, because it always creates a new copy of the member function, and the changes you see may be slower.

Also note that using this method is significantly better than relying on prototype mode (confirmed by Jsperf test).

Performance improvements when using module or prototype mode

This is a performance comparison test for a prototype model and a module pattern:

 Prototypal Pattern Klass1 = function () {} Klass1.prototype.foo = function () {log (' foo ');
 } Klass1.prototype.bar = function () {log (' bar ');
  }//Module pattern Klass2 = function () {var foo = function () {log (' foo ');
  }, bar = function () {log (' bar ');

  }; return {foo:foo, Bar:bar}}//Module pattern with cached functions var foofunction = function () {log (
 ' foo ');
 };
 var barfunction = function () {log (' bar ');

 }; KLASS3 = function () {return {foo:foofunction, bar:barfunction}}//Iteration Tests//Prototypal VA
 R i = 1000, objs = [];
  while (i--) {var o = new Klass1 () Objs.push (New Klass1 ());
  O.bar;
 O.foo;
 }//Module pattern var i = 1000, objs = [];
  while (i--) {var o = Klass2 () Objs.push (Klass2 ());
  O.bar;
 O.foo;
 }//Module pattern with cached functions var i = 1000, objs = [];
  while (i--) {var o = Klass3 () Objs.push (KLASS3 ());
  O.bar;
 O.foo; }//The TEST for full details 

Tips for using arrays

Next, let's talk about array-related techniques. In general, do not delete an array element , which will make the array transition to a slower internal representation. When the index becomes sparse, V8 will move the element to a slower dictionary mode.

The literal amount of the array

The literal value of an array is very useful, and it can imply the size and type of the VM array. It is usually used in an array of small size.

Here V8 can and so you want a 4-element array containing numbers:
var a = [1, 2, 3, 4];

Don ' t does this:
a = [[]; V8 knows nothing about the "array for"
(var i = 1; I <= 4; i++) {
  a.push (i);
}

Storage single type vs multiple types

It is never a good idea to have data in a mixed type (such as numbers, strings, undefined, true/false) in an array. For example, var arr = [1, "1", Undefined, True, "true"]

Performance tests for type inference

As we can see, the array of integers is the fastest.

sparse arrays and full arrays

When you use sparse arrays, be aware that the access elements will be much slower than the full array. Because V8 does not allocate an entire block of space to an array that uses only part of the space. Instead, it is managed in the dictionary, which saves space but spends the time of the visit.

sparse arrays and full arrays of tests

Pre-allocated space vs dynamic allocation

Do not allocate large arrays (such as elements larger than 64K) to their maximum size, but should be dynamically allocated. Before we test the performance of this article, keep in mind that this applies only to some JavaScript engines.

Null literals are tested with a pre-configured array in a different browser

Nitro (Safari) is more advantageous to a pre-configured array. In other engines (V8,spidermonkey), pre-allocation is not efficient.

Pre-allocated Array test

Empty array
var arr = [];
for (var i = 0; i < 1000000 i++) {
 arr[i] = i;
}

pre-allocated array
var arr = new Array (1000000);
for (var i = 0; i < 1000000 i++) {
 arr[i] = i;
}

Optimization of your application

In the world of Web applications, speed is everything. No user wants a table application that takes a few seconds to calculate the total number of columns or to spend a few minutes summarizing information. This is an important reason why you need to squeeze every bit of performance into your code.

Photo Source: Per Olof Forsberg.

Understanding and improving the performance of your application is very useful, but it is also difficult. We recommend the following steps to address the pain point of performance:

    • Measurement: Find a slow place in your application (approx. 45%)
    • Understanding: Find out what the real problem is (about 45%)
    • Fix It! (About 10%)

Some of the tools and techniques recommended below can help you.

Benchmarking (Benchmarking)

There are many ways to run the benchmark of JavaScript code fragments to test its performance--the general assumption is that the benchmark simply compares two timestamps. This pattern is indicated by the Jsperf team and is used in the Sunspider and Kraken base suites:

var totaltime,
 start = new Date,
 iterations = 1000;
while (iterations--) {
 //Code snippet goes here
}
//totaltime→the number of milliseconds taken 
//to E Xecute the code Snippet 1000 times
totaltime = new Date-start;

Here, the code to test is placed in a loop and runs a set number of times (for example, 6 times). After that, the start date subtracts the end date, which results in the time it takes to perform the operation in the loop.

However, this benchmark test does things too simply, especially if you want to run benchmarks in multiple browsers and environments. The garbage collector itself has a certain effect on the result. Even if you use a solution like window.performance, you have to take these flaws into account.

Whether you run the code for the base section or not, write a test suite or coded base library, the JavaScript benchmark is actually more than you think. For a more detailed guide benchmark, I strongly recommend that you read the JavaScript benchmark test provided by Mathias Bynens and John-david Dalton.

Analysis (PROFILING)

The Chrome developer tool is a good support for JavaScript analytics. You can use this feature to detect which functions are taking up most of the time, so you can optimize them. This is important, even a small change in code can have a significant impact on overall performance.

Analysis panel for Chrome developer tools

The parsing process begins to obtain a code performance baseline, which is then represented as a timeline. This will tell us how long the code will take to run. The "Profiles" tab gives us a better perspective on what's going on in the application. The JavaScript CPU analysis file shows how much CPU time is used for our code, and the CSS selector analysis file shows how much time is spent on the processing selector, and the heap snapshots show how much memory is being used for our objects.

With these tools, we can isolate, adjust, and re-examine whether our functional or operational performance optimization really works.

The Profile tab shows code performance information.

A good introduction to the analysis, read Zack Grossbart's JavaScript Profiling with the Chrome Developer Tools.

Tip: Ideally, you can use a --user-data-dir <empty_directory> flag to start chrome if you want to make sure that your analysis is not affected by an installed application or extension. In most cases, this method of optimizing the test should be sufficient, but it will take you more time. This is a V8 sign that can help.

Avoid memory leaks--3 Snapshot technology

Inside Google, Chrome developer tools are used by teams such as Gmail to help detect and troubleshoot memory leaks.

Memory statistics in the Chrome Developer tool

Memory counts the private memory usage that our team cares about, the size of the JavaScript heap, the number of DOM nodes, the storage cleanup, the event listener counters, and what the garbage collector is trying to reclaim. Read Loreena Lee's "3 snapshots" technique. The point of this technique is to record some behavior in your application, Force garbage collection, check whether the number of DOM nodes is restored to the expected baseline, and then analyze the three-heap snapshots to determine if there is a memory leak.

Memory management for single page application

Memory management for single page applications, such as Angularjs,backbone,ember, is very important and they will almost never refresh the page. This means that a memory leak can be quite obvious. A single page application on a mobile terminal is full of traps because the device has limited memory and is running applications such as email clients or social networks for a long time. The greater the capacity, the heavier the responsibility.

There are many ways to solve this problem. In backbone, be sure to use Dispose () to handle old views and references (currently available in backbone). This function was recently added to remove the handler function added to the View ' event ' object and the model or collection event listener passed to the third parameter (callback context) of view. Dispose () is also invoked by the view's remove () to handle the primary cleanup when the element is removed. Other libraries such as Ember when the element is removed, the listener is cleaned up to avoid a memory leak.

Some sensible advice from Derick Bailey:

Rather than understanding how events and references work, it is better to follow the standard rules for managing memory in JavaScript. If you want to load data into a backbone collection of user objects, you need to empty the collection so that it no longer consumes memory, and that must be all references to the collection and the objects in the collection. Once the reference is made clear, the resource is reclaimed. This is the standard JavaScript garbage collection rule.

In this article, Derick covers a number of common memory flaws when using backbone.js, and how to troubleshoot these problems.

Felix Geisendörfer's tutorial on debugging memory leaks in node is also worth reading, especially as it forms part of a broader spa stack.

Reduced backflow (reflows)

When browsers recreate the elements in the document, they need to recalculate their position and geometry, which we call reflux. Backflow can block the user's actions in the browser, so it is helpful to understand the timing of the upgrade.

Reflow Time Chart

You should trigger the reflow or redraw in batches, but use these methods sparingly. It is also important not to handle the DOM as much as possible. You can use DocumentFragment, a lightweight document object. You can use it as a way to extract part of the document tree, or to create a new document "Fragment". Instead of constantly adding DOM nodes, use the document fragment only once to perform a DOM insert operation to avoid excessive reflow.

For example, we write a function to add 20 div to an element. If you simply append one div to the element at a time, this triggers a 20-time return.

function Adddivs (Element) {
 var div;
 for (var i = 0; i < i + +) {
 div = document.createelement (' div ');
 div.innerhtml = ' heya! ';
 Element.appendchild (div);
 }

To solve this problem, you can use DocumentFragment instead, we can add a new div to the inside each time. Adding DocumentFragment to the DOM when finished will only trigger a reflow.

function Adddivs (Element) {
 var div; 
 Creates a new empty documentfragment.
 var fragment = Document.createdocumentfragment ();
 for (var i = 0; i < i + +) {
 div = document.createelement (' a ');
 div.innerhtml = ' heya! ';
 Fragment.appendchild (div);
 }
 Element.appendchild (fragment);
}

You can see make the Web faster,javascript Memory optimization and finding Memory leaks.

JS Memory Leak Detector

To help discover JavaScript memory leaks, Google's developers (Marja Hölttä and Jochen Eisinger) developed a tool that was used in conjunction with the Chrome Developer tool to retrieve a snapshot of the heap and detect what object caused the memory leak.

A JavaScript memory leak detection Tool

There is a complete article about how to use this tool, suggest yourself to the memory Leak detector project page to see.

If you want to know why such tools have not been integrated into our development tools for two reasons. It was originally in the closure library to help us capture some specific memory scenarios, which are more suitable as an external tool.

V8 optimization debugging and garbage collection logo bit

Chrome support directly by passing some flags to the V8 for more detailed engine tuning output results. For example, this can track the optimization of V8:

"/Applications/Google chrome/google Chrome"--js-flags= "--trace-opt--trace-deopt"

Windows users can run Chrome.exe–js-flags= "–trace-opt–trace-deopt" like this

The following V8 flags are available when you are developing an application.

    • trace-opt--records the name of the optimization function and shows skipped code because the optimizer does not know how to optimize it.
    • trace-deopt--records the code that will be "optimized" at run time.
    • The trace-gc--records each garbage collection.

V8 's processing script uses a * (asterisk) to identify the optimized function, with a ~ (wave number) representing the function that is not optimized.

If you are interested in learning more about V8 's logo and how the V8 interior works, it is highly recommended to read the excellent post on V8 internals of Vyacheslav Egorov.

High-resolution time and navigation TIMING APIs

High-precision Time (HRT) is a millisecond-level, high-precision time interface that provides an effect that is not subject to system time and user tuning, and can be used as a more accurate metric than new Date and Date.now (). This is a great help for us to write benchmark tests.

High-precision Time (HRT) provides the time accuracy of the current sub-millisecond level

HRT is currently used in Chrome (stable version) in Window.performance.webkitNow (), but the prefix is discarded in Chrome Canary, which allows it to pass through Window.performance.now () Method call. Paul Irish on Html5rocks for more on HRT.

Now that we know the precise timing of the current, is there an API that can accurately measure page performance? Okay, now there's a navigation Timing API available, which provides an easy way to get the exact and detailed time measurement records when the page is loaded to the user. You can use window.performance.timing in the console to get time information:

Time information displayed in the console

We can get a lot of useful information from the above data, for example, network latency is responseend–fetchstart, page loading time is loadeventend–responseend, processing navigation and page loading time is loadeventend– Navigationstart.

As you can see, Perfomance.memory's properties also show the use of JavaScript's memory data, such as the total heap size.

For more details on the navigation Timing API, read Sam Dutton's measuring Page Load Speed with navigation Timing.

About:memory and About:tracing

The about:tracing in Chrome provides a browser's performance view that records all of Chrome's threads, tabs, and processes.

about:tracing provides browser performance view

The real use of this tool is to allow you to capture Chrome's running data so that you can properly adjust JavaScript execution or optimize resource loading.

Lilli Thompson has an article for game developers using the About:tracing analysis WebGL game and is also suitable for JavaScript developers.

You can enter about:memory in the chrome navigation bar, which is also useful to get memory usage for each tab, which is helpful for locating memory leaks.

Summary

We see that there are a lot of hidden traps in the JavaScript world and there is no silver bullet to improve performance. Only by integrating some optimization schemes into the (real world) test environment can the maximum performance benefit be obtained. Even so, understanding how the engine interprets and optimizes the code can help you tweak your application.

measure, understand, fix. The repeats this process continuously.

picture Source: Sally Hunter

Remember to focus on optimization, but Some small optimizations can be discarded for convenience. For example, some developers choose. foreach and Object.keys instead of for and for. In loops, although this can be slower but easier to use. To ensure a clear mind, know what optimization is needed, what optimization is not needed.

Also note that while the JavaScript engine is getting faster, the next real bottleneck is DOM. The reduction of reflow and redraw is also important, so move the DOM when necessary. There is the need to focus on the network, HTTP requests are precious, especially on mobile terminals, so to use the HTTP cache to reduce the load of resources.

Remember these points to ensure that you get most of the information in this article and hope it will help you!

Original: http://coding.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/

Author: Addy Osmani

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.