Quantcast
Channel: CNode:Node.js专业中文社区
Viewing all articles
Browse latest Browse all 14821

《请叫我Node.js 8》兼发布说明

$
0
0

《请叫我Node.js 8》兼发布说明

为了避免和V8引擎的名字冲突,请叫我Node.js 8

可以进入官网 https://nodejs.org/en/下载,或者使用

$ nvm install 8
VERSION_PATH=''
######################################################################## 100.0%
Computing checksum with shasum -a 256
Checksums matched!
Now using node v8.0.0 (npm v5.0.0)
$ node -e "console.log(process.versions.v8)"
5.8.283.41

相关的 ES语法支持 可以在 node.green 查看

核心内容

  • 是下一个长期支持版本
  • 更新 V8 到 5.8版本: 核心变更TurboFan & Ingnition(加了jit即时编译)
  • 更新 npm 到 5.0.0:宇宙最快+自带lock文件
  • 引入新的 c/c++ 扩展方式:N-API,解决addon的编译问题
  • Async函数性能提升
  • Async Hooks API支持

长期支持版本

Node.js 8 is the next release line to enter Long Term Support (LTS). This is scheduled to happen in October 2017. Once Node.js 8 transitions to LTS, it will receive the code name Carbon.

更新 V8 到 5.8版本: 核心变更TurboFan & Ingnition(加了jit即时编译)

一句话:more modern compiler + jit pipeline

中文说明,参见《精华 V8 Ignition:JS 引擎与字节码的不解之缘》https://cnodejs.org/topic/59084a9cbbaf2f3f569be482

With Node.js Version 8, the underlying V8 JavaScript engine gets updated as well.

The biggest change it brings to Node.js users is the introduction of TurboFan and Ignition. Ignition is V8’s interpreter, while TurboFan is the optimizing compiler.

“The combined Ignition and TurboFan pipeline has been in development for almost 3½ years. It represents the culmination of the collective insight that the V8 team has gleaned from measuring real-world JavaScript performance and carefully considering the shortcomings of Full-codegen and Crankshaft. It is a foundation with which we will be able to continue to optimize the entirety of the JavaScript language for years to come.” - Daniel Clifford and the V8 team

Currently (well, with V8 versions older than 5.6, so anything below Node.js version 8) this is how the V8 compilation pipeline looks

The biggest issue with this pipeline is that new language features must be implemented in different parts of the pipeline, adding a lot of extra development work.

This is how the simplified pipeline looks, without the FullCode Generator and the Crankshaft:

This new pipeline significantly reduces the technical debt of the V8 team, and enables a lot of improvements which were impossible previously.

Read more on TurboFan and Ignition and the TurboFan Inlining Heuristics .

更新 npm 到 5.0.0

一句话:据说速度最快,秒杀yarn,支持自动生成lock文件

The new Node.js 8 release also ships with npm 5 - the newest version of the npm CLI.

Highlights of this new npm release:

  • A new, standardized lockfile feature meant for cross-package-manager compatibility (package-lock.json), and a new format and semantics for shrinkwrap,
  • –save is no longer necessary as all installs will be saved by default,
  • node-gyp now supports node-gyp.cmd on Windows,
  • new publishes will now include both sha512 and sha1 checksums.

官方博客 http://blog.npmjs.org/post/161081169345/v500

引入新的 c/c++ 扩展方式:N-API,解决addon的编译问题

一句话: 是新的 c/c++ 扩展方式,借助Application Binary Interface (ABI)虚拟机,一次编译,多个版本运行,妈妈再也不担心addon的编译问题了

在里有一堆官方的PoC示例:nodejs/abi-stable-node-addon-examples。如果只想有个直观感受,看这个视频也凑合:[Node.js & ChakraCore by Arunesh Chandra, Microsoft](https://youtu.be/zGmQR7iBfD4?list=PLfMzBWSH11xYaaHMalNKqcEu

The N-API is an API for building native addons. It is independent of the underlying JavaScript runtime and is maintained as part of Node.js itself. The goal of this project is to keep the Application Binary Interface (ABI) stable across different Node.js versions.

The purpose of N-API is to separate add-ons from changes in the underlying JavaScript engine so that native add-ons can run with different Node.js versions without recompilation.

Read more on the N-API.

Async函数性能提升

在v8 5.7的时候,它的Native async 函数就已经和promise一样快了

本次发布的Node.js 8搭载的v8 5.8,性能还有更多提升。具体数据未见,但有一个例子

Using newest v8 should give us faster performance as shown on the v8 blog. Instead of writing micro benchmarks, we can also see what parts of code are optimized or deoptimized using 00trace-deopt and --trace-opt flags respectively. So lets write simple example using koa framework and koa-route package.

const Koa = require('koa')
const app = new Koa()
const _= require('koa-route')

app.use(_.get('/', (ctx) => {
   ctx.body = "hello world"
}))

app.listen(3000);

Immediately we see [removing optimized code for: slice] when running this with node --trace-deopt --trace-opt on latest stable Node.js release. However, running this on latest v8 shows this is not an issue anymore. Now, there are much more optimizations killers, especially if you are using newer ES6/ES7 features. For more info you can visit https://github.com/petkaantonov/bluebird/wiki/Optimization-killers Lets add one of the most common into our server, Try/Catch statement. This is probably regularly used in your production code.

function test() {
    try {
        // ...some other code that could throw...
        return Math.random() * Math.random()
    } catch(e) {}
}
app.use(ctx => {
    console.time("trycatch")
    for (let i = 0; i < 9000000; ++i)
       test()
    console.timeEnd("trycatch")
    ctx.body = 'Hello Koa'
})

Running this under LTS gives us [disabled optimization for 0x22ef78b6cb01 <SharedFunctionInfo test>, reason: TryCatchStatement] with result trycatch: 522.535ms. Moving on to latest stable shows us that this is now optimized [completed optimizing 0xf67777c9d21 <JS Function test (SharedFunctionInfo 0x243afe6743d9)>] with result trycatch: 289.591ms.

This gives us 44% faster code without changing anything.

Moving on to latest v8 release, gives us 190.850ms for a total of 64% increase. Not bad given that our code stayed the same and we got all this from only a newer compiler.

This kind of optimizations are especially important for Node.js since cpu intensive code blocks the event loop, leaving you with a slow server overall. Although, you probably won’t be running this kind of code in a production, you probably will do some data processing sooner or later, which can be very cpu intensive.

http://blog.qaap.io/2017/04/30/Using-latest-v8-in-Node-js/

Async Hooks API支持

一句话:结构化生命周期,用于异步追踪,搭配AsyncEvent等更好

The Async Hooks (previously called AsyncWrap) API allows you to get structural tracing information about the life of handle objects.

The API emits events that inform the consumer about the life of all handle objects in Node.js. It tries to solve similar challenges as the continuation-local-storage npm package, just in the core.

If you are using continuation-local-storage, there is already a drop-in replacement that uses async hooks, called cls-hooked - but currently, it is not ready for prime time, so use it with caution!

How The Async Hooks API Works in Node.js Version 8

The createHooks function registers functions to be called for different lifetime events of each async operation.

const asyncHooks = require('async_hooks')

asyncHooks.createHooks({  
  init,
  pre,
  post,
  destroy
})

These functions will be fired based on the lifecycle event of the handler objects.

Read more on Async Hooks, or check the work-in-progress documentation.

其他

https://nodejs.org/en/blog/release/v8.0.0/

Buffer 安全和性能提升

Before Node.js version 8, Buffers allocated using the new Buffer(Number) constructor did not initialize the memory space with zeros. As a result, new Buffer instances could contain sensitive information, leading to security problems.

While it was an intentional decision to boost the performance of new Buffer creation, for most of us, it was not the intended use. Because of this, starting with Node.js 8, Buffers allocated using new Buffer(Number) or Buffer(Number) will be automatically filled with zeros.

TRAILING COMMA IN PARAMETER + ARGUMENTS

In early Node versions (0.X) the support for object and array trailing commas were already implemented, making multiline object and array definitions much more friendly towards extension and version control.

In Node 8 this support arrived for function parameters and function arguments too. From now on, the definition and invocation of multiline parametered functions will now also be extension and version control friendly.

function foo(
  a,
  b,
  c, // this threw a Parse Error before Node 8
) { … }

foo(
  ‘a’,
  ‘b’,
  ‘c’, // this threw a Parse Error before Node 8
);

TEMPLATE LITERAL REVISION (ES2018)

Template literals were introduced in the ES2015 standard. It is really useful when it comes to string interpolation, however there are some special unicode characters, such as \u or \x that cannot be used in template literals.

The template literal revision aids this problem by allowing these special characters. A good use case can be found in the proposal document: the embedding of DSL languages (like LaTeX where \u or \x characters are common) can greatly benefit from this feature.

function latex(strings) {
  // ...
}

latex`
\document{article}
\usepackage{somepackage}
`
// \document{article} works on previous Node versions
// \usepackage{somepackage} will only work on Node 8 due to ‘\u’ special character

OBJECT REST AND SPREAD (ESNEXT)

Array rest and spread were already available in previous Node versions. Now in Node 8 the support for object rest and spread has landed.

Object rest gathers the non-destructured keys remaining in the object:

const foo = { a: 1, b: 2, c: 3 };
const { a, ...rest } = foo;
console.log(rest); // { b: 2, c: 3 }

Object spread inserts the respective object’s key-value pairs into the target object:

const foo = { a: 1, b: 2, c: 3 };
const bar = { d: 4, e: 5 };
const baz = {};

const qux = { ...foo, ...bar, ...baz };
console.log(qux); // { a: 1, b: 2, c: 3, d: 4, e: 5 }

Spread can be used instead of Object.assign and/or lodash assign/extend. Both rest and spread helps to create a more readable codebase.


Viewing all articles
Browse latest Browse all 14821

Trending Articles