写点什么

Node.js 12:服务端 JavaScript 的未来

  • 2019-08-02
  • 本文字数:4017 字

    阅读完需:约 13 分钟

Node.js 12:服务端JavaScript的未来

自 2009 年首次发布以来,Node.js 一直是一项改变游戏规则的技术。概括来说,它允许开发人员使用 JavaScript 在服务端运行脚本,在页面发送到用户的 Web 浏览器之前生成动态 Web 内容。Node.js 是“JavaScript 无处不在”的潮流代表;在这种潮流推动下,服务端和客户端脚本不再需要使用不同的语言编写,开发 Web 应用只用一种编程语言就够了。


如果你像我一样也是 JavaScript 和 Node.js 的粉丝,你会很高兴看到它们正在迎来全方位的改进。

Node 12 新特性与改进

“全方位改进”是什么意思呢?其实就在几个月前,Node.js 12 版刚刚发布了。


2019 年 4 月 23 日Node.js 12正式发布,全球各地的 JavaScript 爱好者都欢欣鼓舞。需要明确的是,这不只是一个普通的旧版本更新,而是一个有诸多重要内容更新的关键版本升级。具体升级内容如下。

V8 JavaScript 引擎升级

每次的新版本 JavaScript V8 引擎都会带来一些性能调整和改进,此外这次还有一些非常值得注意的升级。具体有:


  • 零成本异步堆栈跟踪——通过异步调用框架丰富 error.stack 属性,而无需为 V8 引擎添加额外的运行时。

  • 参数不匹配的调用更快——以前 V8 必须用统一的方式处理参数过多或过少的函数调用,造成性能损失。现在引擎变得更聪明了,知道什么时候可以跳过这一步,从而将调用开销减少了 60%。

  • 更快的异步函数和Promise——实际上现在使用异步要比 Promise 快两个微拍(microtick),因为对 Promise 不熟悉的开发者可以使用语法风格更加同步的 async/await。

  • 更快的JavaScript解析——在网页启动时,解析 JS 的耗时只有引擎总耗时的 10%不到。最新发布的 JavaScript 解析器在桌面端的解析速度提高了 30%。

使用 TLS 1.3 提高安全性

TLS(传输层安全),是 Node 处理加密流通信的方法。


随着 Node.js 12 的发布,TLS 也升级到了1.3版;虽然版本号只多了一点,但这次实际上是重大更新,加入了很多性能和安全性增强功能。听起来有些不可思议,但 TLS 1.3 实际上是比 TLS 1.2 更简单的协议,比后者更安全、更易配置,并且可以更快地在应用程序之间协商会话。


Node 应用可以在 TLS 1.3 的帮助下更好地保护终端用户隐私,同时减少 HTTPS 握手所需的时间来提高请求性能。


小结:为所有用户提供更好的安全性并减少服务之间的通信延迟,我认为这是一大进步。

合理配置的默认堆大小

下面来谈一些底层改进。以前,JavaScript 堆大小默认等于浏览器 V8 引擎设置的堆大小上限,前者可以手动调整。Node.js 12 发布开始,JS 堆大小将根据可用内存来自动配置,这样 Node 就不会尝试使用比可用内存更多的内存空间了,避免了耗尽内存导致进程被迫终止的问题。


新版在处理大量数据时不会再出现内存不足错误——以前经常会出现这种问题。需要的话,开发者还可以使用旧的–max-old-space-size 标志手动设置上限,但新功能出现后手动设置大小的需求应该就没那么多了。

默认的 http 解析器变为 llhttp

很多人(包括我自己)都不知道,Node 中之前使用的 http_parser 库非常难以维护和改进,这就是llhttp诞生的原因。该项目是一个 http_parser 到 TypeScript 的端口,然后通过 llparse 运行以生成 C 或 bitcode 输出。


测试表明llhttp比http_parser快156%;前者的代码量更少,并且所有性能优化都是自动生成的——相比之下 http_parser 需要手动优化代码。


从 Node.js 12 开始,官方决定将默认解析器切换到 llhttp,开始对其进行全面测试。我们希望它在用途各异的众多应用中都能维持出色的性能表现。

按需生成诊断报告

谈到调试的话题,Node.js 12 引入了一个新的实验性功能,允许用户根据需要或在发生某些触发事件时生成报告。


这种实时报告可以帮助开发者诊断生产中的问题,包括崩溃、性能下降、内存泄漏、高 CPU 使用率、意外错误等等——这些都是通常需要数小时甚至数天才能调试、诊断和修复的东西。

集成堆转储

这个版本中关于堆的另一项特性是 Node.js 12 内置的集成堆转储,它可以加速调试过程。


现在开发者无需安装新模块来调查内存问题——只需通过命令行或 API 调用告诉 Node 你需要哪种 JSON 格式的诊断摘要,然后解析你能处理的所有信息即可。

Node.js 中的原生模块更易使用

底层改进说完了。此外,对于 Node 生态系统中的开发人员和模块开发者来说也有一些改进值得一提。


新版进一步完善了为 Node 创建和构建原生模块的流程,包括更好地支持原生模块与 worker 线程的结合,N-API 也升级到了第 4 版,让开发者可以更容易为原生异步函数配置自己的线程。


总的来说,这意味着 Node 专属模块的创建者和维护者可以像纯 JavaScript 模块的创建者一样轻松地维护这些模块。之前维护人员需要为模块支持的所有 Node.js 版本各做一份二进制文件,而新版 N-API 大大简化了这部分工作。

Worker 线程即将到来——实验标志已被删除

虽然 Node 10 开始就引入了 Worker 线程,但到了 12 版中,启用 Worker 线程不再需要标志——实验阶段快要结束了。在 Node.js 11.7.0 之前,开发者需要在命令行中使用–experimental-worker 标志启动 node 才能访问 Worker 线程模块。


$ node -e "require('worker_threads'); console.log('success');"internal/modules/cjs/loader.js:605    throw err;    ^Error: Cannot find module 'worker_threads'    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:603:15)    at Function.Module._load (internal/modules/cjs/loader.js:529:25)    at Module.require (internal/modules/cjs/loader.js:657:17)    at require (internal/modules/cjs/helpers.js:22:18)    at [eval]:1:1    at Script.runInThisContext (vm.js:123:20)    at Object.runInThisContext (vm.js:312:38)    at Object. ([eval]-wrapper:6:22)    at Module._compile (internal/modules/cjs/loader.js:721:30)    at evalScript (internal/bootstrap/node.js:720:27)$$ node --experimental-worker -e "require('worker_threads'); console.log('success');"success$
复制代码


在执行 CPU 密集型 JavaScript 操作时 Worker 的表现非常出色;但它对 I/O 密集型任务没什么帮助,这种时候 Node 内置的异步 I/O 操作比 Worker 更高效。

启动时间的改进

Node.js 11 引入了内置的代码缓存支持,将 Worker 线程的启动时间减少了近60%


Node 12 在此基础上更进一步,在构建时提前为内置库生成代码缓存,允许主线程使用代码缓存来处理用 JavaScript 编写的内置库的初始加载过程。


结果主线程的启动速度又提升了30%,你的应用为用户加载的速度也能变得更快了。

ES6 模块支持,马上就要完成了

重头戏留到最后介绍。对我来说最令人兴奋的功能之一是ES6模块支持——这也是我们很多人一直在等待的东西。这个功能仍然是实验性的,Node 团队正在收集测试反馈。这个功能意味着开发者只要动动手指就能够实现从前端到后端 JavaScript 的无缝过渡。


以下是最新版本的–experimental-modules 的亮点所在:


  • ES2015 import 语句可以将 Javascript 文件引用为相对链接./examples.js、绝对链接 file:///opt.app/examples.js、包名称 example-package 或包中的路径 example-package/lib/examples.js。


// relative urls‘./examples.js’ // absolute URLs‘file:///opt.app/examples.js’ // package names‘example-package’ // paths within packagesexample-package/lib/examples.js
复制代码


  • .js 文件中的导入和导出语法现在也都能用了。自 ES6 发布以来,开发人员终于可以像在传统 JS 中那样指定默认导出 import test from ‘./examples’、命名导出 import {example1, example2} from ‘./examples’ 和命名空间导出 import * as samples from ‘./examples’ 了。


// default imports / exportsimport test from ‘./examples’ // named imports / exportsimport {example1, example2} from ‘./examples’ // namespace exports import * as samples from ‘./examples’
复制代码


  • 将“type”: “module”添加到项目的 package.json 中,且 Node.js 将项目中的所有.js 文件视为 ES 模块。这种方法允许 Node 将 package.json 用于包级元数据和配置,做法类似 Babel 等捆绑和配置工具。

  • 使用.mjs 结尾的文件会被显式视为模块,使用.cjs 结尾的文件会被视为 CommonJS。这些是仍然使用 require 和 module.exports 语法类型的文件。


现在这些功能不再需要标志就能使用,真是太棒了。

Node 12 的新编译器和平台最低标准

最后要谈的是新版 Node 的运行需求变动。


Node.js 12 通过内部改进和 V8 引擎的升级引入了许多新功能,最低运行需求也随之变化。对于 macOS 和 Windows 以外的平台而言,新版代码库现在至少需要 GCC 6 和 glibc 2.17。使用这套新工具链编译的版本会包含编译时性能和安全性增强。


如果你使用的是 Mac 或 Windows 系统应该就没问题了:Windows 系统版本需求没变,Mac 用户至少需要 Xcode 8 和 10.10“Yosemite”系统来运行新版 Node。来自 nodejs.org 的 Linux 兼容版本将支持 Enterprise Linux 7、Debian 8 和 Ubuntu 14.04,但可能需要在原生不支持 GCC 6 的系统上使用自定义工具链。我相信你会很快找出所需要的东西。

总结

Node.js 的历史只有 10 年,现在还是单线程的,也没有像其他一些编程语言那样广泛应用,但 Node 拥有一些其他编程语言难以企及的优势:它是用 JavaScript 构建的 ,并且既可以在客户端也能在服务端运行。


致力于支持和改进 Node 的团队和企业是业界最优秀的。Node 正在持续从核心 JavaScript 和其他语言中学习,挑选合适的部分并吸纳到自身当中,为开发人员和应用程序打造一个不断进步的平台。


Node.js 12 带来了一些非常令人兴奋的改进,例如 ES6 模块支持、更好的应用程序安全性和更快的启动速度等。虽然直到2019年10月它才会进入LTS(长期支持)模式,但我还是要深入研究这些新功能,看看团队还能想到哪些内容来继续改进这个平台,使其成为更加出色的服务端解决方案。


英文原文:https://blog.logrocket.com/node-js-12/


2019-08-02 10:163396

评论

发布
暂无评论
发现更多内容

人脸识别技术的历史发展及未来趋势

数据堂

当金融风控遇上人工智能,众安金融的实时特征平台实践

NebulaGraph

人工智能 风险控制 金融风控

数据湖系列之三 | 打造高性能云原生数据湖,层级 namespace 对象存储加速大数据计算

Baidu AICLOUD

数据湖 对象存储 层级namespace

企业需要什么样的全面预算管理?

用友BIP

全面预算

精选|Dubbo异步化实践

得物技术

人脸识别技术的原理及其应用

数据堂

Flutter卡片分享功能实现:将你的内容分享给世界

编程的平行世界

flutter android

有奖问卷 | 2023 中国软件研发效能调查问卷即将截止

CODING DevOps

升哲科技受邀出席第十四届夏季达沃斯论坛

SENSORO

【AI 充电】KServe + Fluid 加速大模型推理

阿里巴巴云原生

阿里云 Kubernetes 云原生

人脸识别技术的优缺点及实际应用

数据堂

跑得更快!华为云GaussDB以出色的性能守护“ERP的心脏”

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 企业号 6 月 PK 榜

深度分析:企业大数据分析的选型需要关注哪些能力

对不起该用户已成仙‖

如何在 NGINX 中安全地分发 SSL 私钥

NGINX开源社区

nginx ssl

浅显易懂传统开发与低代码开发的区别

互联网工科生

低代码 JNPF 传统开发

共识算法揭秘:理解分布式系统的关键

Steven

用友BIP全球司库十问之资金结算如何统一管理?

用友BIP

全球司库 资金管理

Zilliz Cloud 明星级功能详解|解锁多组织与角色管理功能,让你的权限管理更简单!

Zilliz

SaaS 非结构化数据 Zilliz AIGC zillizcloud

强化学习从基础到进阶-常见问题和面试必知必答[8]:近端策略优化(proximal policy optimization,PPO)算法

汀丶人工智能

人工智能 深度学习 强化学习 6 月 优质更文活动 ppo算法

“多云“和”私有化“,企业级刚需推动 DataBricks 和 MosaicML的13亿美金 AI 交易

B Impact

人脸识别技术的挑战和未来发展

数据堂

2023-06-28:你想要用小写字母组成一个目标字符串 target。 开始的时候,序列由 target.length 个 ‘?‘ 记号组成 而你有一个小写字母印章 stamp。 在每个回合,你可

福大大架构师每日一题

Go rust 算法、 福大大架构师每日一题

国产替代,本质是价值替代

用友BIP

AI 2.0来袭,AIGC如何重新定义招聘?

用友BIP

AI 招聘

阿里云顺利通过云原生中间件成熟度评估

阿里巴巴云原生

阿里云 云原生 中间件 成熟度

软件测试/测试开发丨Python内置库学习笔记

测试人

Python 程序员 软件测试 内置库

Node.js 12:服务端JavaScript的未来_语言 & 开发_Paige Niedringhaus_InfoQ精选文章