天天看點

Node.js Interactive 2016 North America 紀行

原作者:洗影

受 Node.js 基金會的邀請到 Node.js Interactive 2016 North America 做了一次 talk,以下是個人的一些記錄。

關于 Node.js Interactive

Node.js 相關的技術會議主要包括

  • 每年夏天在舊金山舉辦的 Node Summit,規模較大,主要關注 Node.js 在各種企業/組織(如 ebay,NASA,Netflix 等)中的應用和 Node.js 生态系統方面的議題,偏架構/應用開發
  • 每年在世界各地舉辦的多場 Node Conf,規模不等,主要集中在歐洲和南北美洲,有點類似 JS Conf,内容比較廣泛,主要由來自當地的開發者做分享。今年規模最大的應該是 Node Conf EU。
  • 每年在紐約舉辦的 EmpireNode,規模中等,面向開發者社群,内容也比較廣泛
  • 由 Node.js 基金會在世界各地舉辦的 Node Live,規模比較小,内容取決于送出,主要是為了推廣 Node.js 和接觸世界各地的開發者,會去到一些當地不舉辦 Node 會議的地方(比如北京)
  • 由 Node.js 基金會主辦的 Node.js Interactive,從去年 Node.js 基金會成立後開始舉辦,規模較大。去年隻開了一場,今年在歐洲和北美各開了一場。主要關注 Node.js 在企業中的應用,Node.js 的生态系統與 Node Core 本身。

今年 5 月到 Node Live Beijing 做了一次分享,當時基金會的 Tracy 跟我說 You should speak in the US,然後 8 月就收到了郵件問我有沒有空參加 11 月底 12 月初的 Node.js Interactive。于是急急忙忙辦了護照和簽證,最後順利在 11 月底到達美國。

到美國參加會議要申請的是 B1/B2 簽證,基本上有邀請信和在職證明就可以了(簽證官隻看了一眼我的邀請信,然後問了一波問題,就 Approve 了)。Node.js 基金會名義上屬于是 Linux 基金會旗下,是以邀請信是 Linux 基金會開的。從參會的過程可以看出來 Linux 基金會主要是幫助 Node.js 基金會處理技術無關的事務的,比如财務、開簽證邀請信、協助組織會議、宣傳等。從 CTC 成員那裡還得知他們過來參加會議的花費也是由 Node.js 基金會提供的,不過似乎雇主是基金會成員的話還是從雇主那裡出,今年最大的贊助商 Google、Microsoft、IBM 和 Intel 都派了不少人過來。現在 Node 社群出現了大量來自這些大公司的貢獻者,并且這些公司之間多多少少存在一定的競争,Node 作為一個社群驅動的項目其實在這方面和 Linux 有點類似,Node 基金會依賴 Linux 基金會這個過來人指導非技術方面的東西也是很容易了解的。

今年 Node Interactive 的一些變化

(對去年 Node Interactive 的印象主要來自錄像)。

去年的 Node Interactive 還有比較多關注企業應用的分享(比如 Node at Uber/Paypal/Netflix/Godaddy),最後的 panel 也重點在讨論 Node.js for the Enterprise 這樣的話題,此外有比較多 Web 開發和物聯網(IoT)相關的議題。今年大家似乎已經預設企業應用已經比較成熟了,是以出現了更多 Node.js Core 的開發、JavaScript 引擎和配套的調試與追蹤工具相關的話題。由于 Node.js 開始以 working group 的方式組織各方面的開發工作,各個分享裡也可以看到來自不同 working group 的最新進展。

另外今年的 Node Interactive 比去年更擠了,短短兩天的時間擠了 50 多個技術分享和十幾個 keynote,幾乎每個時段都有三個不同的場地在做分享+一個場地在做 workshop,而且沒有按領域分組,有時候相似領域的分享會同時在不同的場地進行,感覺分身乏術啊……而且每個分享隻有 20 分鐘,對于很多話題來說非常難在這麼短的時間内講得比較深入,感覺還是有點遺憾的。

大廠(雲計算為主)的競争

今年 Node 社群裡大廠方面最大的動靜可能是 Google 的參與。雖然 Node.js 一直在使用 Google 的 V8,但是去年的 Node Interactive 居然看不到 Google 的身影,而且 V8 團隊長期以來把重點放在浏覽器方面的優化上,對 Node 的需求有些跟不上。當年在 Lars Bak 等人轉去做 Dart 之後,V8 團隊的主力從丹麥 Aarhus 轉移到了德國慕尼黑,主要應對 Chrome 的需求。今年 Google 加入了 Node.js 基金會,不僅慕尼黑的團隊開始重視 V8 在服務端的性能優化,山景城的 Google Cloud Platform 團隊也開始參與 V8 的開發,協助完成 V8 在服務端的需求。Google Cloud Platform 也加大了對 Node.js 的支援力度,提供了從 SDK、部署、追蹤、監控到調試的一條龍服務,是以 Node.js 的多個 working group 都可以看到 Google 員工的身影。另外 Node.js 的一些與 Web 标準相關的開發,如 ES6 Module 整合、HTTP/2 實作等方面的工作,也得到了 Google 的協助。

另一方面,在 Node.js 基金會創立之初就很積極的微軟,也在争取擴大自己在 Node.js 社群的影響力。延續去年開的頭,微軟依然在推動 Node.js 走向 VM Neutrality,讓 Node.js 能夠切換 JavaScript 引擎,使用微軟開源的 ChakraCore(IE 與 Edge 底層的 JavaScript 引擎)。此外微軟的 VS Code 不僅本身使用 Node.js 開發,也在努力推廣自己在 Node.js 開發者中的使用,比如 keynote 裡展示用 VS Code 結合 docker 插件開發 Node.js 應用部署到 Azure,同樣提供了開發工具、SDK、部署、追蹤、監控到調試的一條龍,果然跟 Google 相愛相殺……

值得一提的是彙集了 Node.js 核心貢獻者的 Node Source 成功與 Azure、Google Cloud Platform、AWS 等主流雲計算廠商達成了合作關系,幫助這些廠商完善生産環境中 Node.js 的監控、追蹤和調試工具,可謂是鹬蚌相争,漁翁得利。相比起來我們阿裡雲的 alinode 還有很長一段路要走,不過國外 Node.js 在後端的應用比國内廣泛得多,國外雲計算廠商對 Node.js 的關注也是可以了解的。按照 Google 在 closing keynote 的話說,他們隻是跟着開發者走,Node.js 開發者越來越多,他們自然要跟進。

相比起 Google 和微軟,同樣是沖着雲計算來的 IBM 關注的方向反而不太一樣,他們更注重 Node Core 開發計劃、私有雲、API Gateway、性能優化與事後調試(post-morterm diagnostics)方面的話題,這跟 IBM 收購了 StrongLoop 和他們一向對咨詢服務的側重有關。畢竟 IBM 一手促成了 Node.js 基金會的創立,目前 TSC 的 chair 也是 IBM 的員工,他們跟 Node.js Core 的關系更深一些。

另一個大廠 Intel 也是 Node.js 基金會最早的成員之一,去年 Intel 對 Node.js 在物聯網的應用投入了大量精力,今年的分享主要集中在 Node.js 的性能優化,特别是小型裝置的性能優化上。Intel 本來就是 V8 的貢獻者,在 Node 方面也做了不少工作,比如支援 vtune profiling 的編譯版本和基于 DPDK 的 libuv 優化,不過很多東西還是比較私有的。

議題總結

(前面說過因為分身乏術是以不是所有分享我都聽了……參考了 agenda 和聽了分享的人的感想)

今年的 Node Interactive 部分話題依然類似 QCon/Goto 這種綜合性技術會議的潮流,比如 Docker、Microservices,以及近期炒熱的的 Cloud Native,Kubernetes 和 serverless。

  • Building and Shipping Node.js Apps with Docker - Sophia Parafina, Docker, Inc.
  • Slaying Monoliths with Docker and Node.js, a Netflix Original - Yunong Xiao, Netflix.com(這場不僅座無虛席,走道和背後都站滿了人,Docker + Netflix 果然是受歡迎啊……内容麼就是 Node.js 在 Netflix 的應用曆程,很多工作感覺和蘇千大大團隊做過的事差不多耶……)
  • Scalable Microservices with gRPC, Kubernetes, and Docker - Sandeep Dinesh, Google
  • Solving Service Discovery - Richard Roger, Nearform
  • Hitchhiker's Guide to"'Serverless" Javascript - Steven Faulkner, Bustle
  • Serverless Front-End Deployments Using npm - Charlie Robbins, GoDaddy
  • 5 Things Developers Should Know About Serverless - Alan Ho, Apigee
  • Buzzword Bingo: Architecting a Cloud-Native Internet Time Machine - Ross Kukulinski, NodeSource (這個标題本身吐槽的很好……)

另一方面,在企業應用和物聯網應用話題相比去年減少的同時,出現了更多調試、追蹤、優化方面的分享(這部分跟我們 alinode 的工作聯系比較密切)。

  • Debugging Debugging - Josh Gavant, Microsoft
  • Instrumentation and Node.js Diagnostics - Thomas Watson, Opbeat (關于新的 Async Hooks API 的分享,不過其實就口頭過了一遍 Diagnostics Working Group 的文檔的感覺……這場雖然面向工具開發者,但是意外地人很多 >___<)
  • What's Up with the Community Post-Mortem Diagnostics Working Group - Richard Chamberlain, IBM (IBM 的一個爺爺和 Neflix 那個座無虛席的 skpeaker Yunong Xiao 一起做的分享,介紹了一下用 llnode 分析線上 coredump)
  • Node.js Community Benchmarking Efforts - Michael Dawson, IBM
  • Perf Stories - David Clements, nearForm
  • Don't Let Just Node.js Take the Blame! - Daniel Khan, Dynatrace
  • Real-Life Node.js Troubleshooting - Damian Schenkelman, Auth0
  • NodeJS @ Intel: Innovations in Open Source - Suresh Srinivas, Principal Engineer, Intel Corporation (介紹 Intel 在 Node.js 性能優化方面的工作和他們的 Language Performance 監控平台)

和去年一樣也有不少 JavaScript 引擎相關的分享:

  • Math in V8 is Broken and How We Can Fix It - Athan Reines, Fourier
  • Are Your V8 Garbage Collection Logs Speaking To You? - Joyee Cheung, Alinode(Alibaba) (這是我 >__<)
  • Let’s Crank Up the Volume: A Deep Dive into the Crankshaft Compiler - Safia Abdella, nteract (感覺在這個 Crankshaft 即将退役,V8 終于要啟用打磨了三年的 TurboFan 的節點講這個好像有點尴尬……礙于時間限制沒法講得很深,但是還是講到了 Hydrogen 和 Lithium,順便提了一下 OSR 之類的,讓我想起了自己校招時被長仁老大面試的問題囧)
  • Node.js & ChakraCore - Arunesh Chandra, Microsoft (示範了一下 Node-CharkaCore 的 Time-Travel Debugging(诶怎麼感覺好像和去年示範的差不多) 和 NAPI)

還多了一些關于 Node.js Core 開發的分享

  • A Beginner’s Guide To Reading Node.js Core Source - Rich Trott, UC San Francisco (他自己吐槽時間不夠,非常蜻蜓點水地用十來分鐘講了一下目錄結構就到台下亂晃了,還說剩這麼多時間大家可以去看 Google 的人做的那個 Shedding Light on the Darknet……)
  • Implementing HTTP/2 for Node.js Core - James Snell, IBM (内容意外地充實,比較詳細地介紹了現在 Node.js Core 裡 HTTP/2 的實作背景,設計緣由,進展,實作難點和性能報告)
  • Node.js Releases, How Do They Work? - Myles Borins, IBM (呃,這個分享他似乎已經在不同的會上講了十幾次了吧哈哈哈……就是介紹一下 LTS 怎麼釋出的和一些建議)
  • Node's Event Loop From the Inside Out - Sam Roberts, IBM
  • The Path to ES Modules - Bradley Meck, GoDaddy (之前他在日本的 NodeFest 也有講過這個,日本那次有提到大約要等到 v10 LTS 才能進來了,這個好像沒有提)

另外依然有一些看名字不明覺厲的分享……

  • Shedding Light on the Darknet - Nwokedi Idika, Google
  • Taking on Genetically Evolving Cellular Automata with JavaScript - Irina Shestak, Small Media Foundation
  • Multimodal Interactions & JS: The What, The Why and The How - Diego Paez, Despegar
  • The Future is Now: Realizing Your Potential as a Cyborg - Emily Rose, SalesForce

其他一些偏 JS 和全棧的 talk,比如

  • Full Stack Testing with Node.js - Stacy Kirk, Quality Works
  • Best Practices using TypeScript with Node.js - Bryan Hughes, Microsoft
  • JavaScript Will Let Your Site Work Without JavaScript - Sarah Meyer, BuzzFeed
  • Take Data Validation Seriously - Paul Milham, WildWorks
  • Quit Writing Everything Yourself - Evan Lucas, Help.com

安全方面的 talk:

  • Writing Secure Node Code: Understanding and Avoiding the Most Common Node.js Security Mistakes - Guy Podjarny, Snyk
  • Tales from the Crypt: Cryptography Primer - Adam Englander, iovation
  • Surviving Web Security Using Node.js - Gergely Nemeth, RisingStack
  • 開場的一個 keynote 宣布 Node Security 加入了基金會(KEYNOTE: Mission Critical Node.js - Security, Reliability, Efficiency - Joe, McCann, Node Source )

其他還有一些 talk 介紹了 Node.js 在機器學習之類的領域的應用,和 Node.js 在一些受關注較少的市場的情況(比如 autodesk 的羅詩亞的 How China Does Node,呃圍繞着 GFW 展開……有提到 cnpm 之類的解決方案,還有一個 Node.js & Africa Market 被臨時取消了)

Node 社群近況與未來方向

從前兩天的分享和後兩天的 collaboration summit 總結一下 Node 社群的近況和未來的開發集中的方向(其實還有更多,這裡隻總結個人比較關注的一些)。

調試與追蹤

V8 debugger -> inspector

由于 V8 的老 debugger protocol 已經 deprecate 兩年了(在 Node 裡提過 issue 但是沒有被 CTC 注意到),計劃在 V8 5.7 删除代碼,而

node debug

目前還是用的這個協定。經過協商之後 Google 同意推遲到 5.8 再删除代碼,留給 Node 團隊一點時間做遷移。Google 團隊已經在年初貢獻了新的 inspector protocol 協定實作(基于 websocket)到 Node.js Core(

PR

),并且已經在 Node V6 釋出,是以主要的問題是如何向 Node.js 社群通知這個消息,讓大家從

node debug

轉為使用

node --inspect

由于現在 Node.js Core 裡的實作隻有 server,沒有 client(自動丢一個 url 讓使用者連 chrome 裡的 client),是以考慮将

node-inspect

納入 Node.js 基金會下,作為官方的新指令行 debugger 用戶端。至于這個指令行用戶端是內建到 core 裡替代原來的還是讓使用者自己通過 npm 安裝還需要讨論。

另外由于 V8 inspector 的 PR 自帶 websocket 實作,是以 Node.js 自帶 websocket 協定子產品又有希望了……

Google 主導的 Chrome Trace Event 內建 ( )

在 Node Core 裡添加和 Chrome 目前使用類似的 Trace Event,由使用者自己定義追蹤點,輸出 chrome://tracing 相容的日志,直接重用 Chrome 自帶的可視化 GUI 來檢視。另外這個 Trace Event 也可以當成一種簡單的開發時日志/profiling 方案來用,與 console.log 相比更底層,針對追蹤設計是以可控性更高。Google 正在和其他 JavaScript 引擎廠商合作抽象這個追蹤 infrastructure,讓其他廠商也來實作,這樣将來切換到其他 JS 引擎也可以用。初步打算是先做 C++ 層面的 instrumentation,JavaScript 的 API 随後。

Async Hooks

這是一個打磨了很久都沒有正式開放的 API(

)……目的是将 Node.js Core 裡的所有異步操作都經過 AsyncWrap 的封裝然後在這裡加上 hooks,讓使用者能夠自行在各種異步操作産生和結束等時點執行自己的代碼,在不開啟的時候對性能基本沒有影響,對編寫監控和追蹤工具十分有用。由于 Node Core 裡的異步操作有的用 JS 實作有的用 C++ 實作,目前 Async Hooks 隻對外暴露了 JavaScript 層面的 API(雖然是通過

process.binding

這個和 C++ 互動的接口加載的)。這個實作一直有同步回 Node.js Core,隻是因為還不是很完善,沒有文檔也沒有對外宣傳,現在 demo 已經比較成熟了,也有了簡單的

文檔

,決定對外公開接受回報。

Post-morterm Diagnostics/底層優化

Post-morterm Diagnostics 也就是線上的事後調試(程序挂了之後的調試)。參與這兩方面的公司主要有 IBM,Intel 與 Joyent。Joyent 本來就有自己的 mdb_v8 用于加載 coredump 進行事後調試,并且将 dtrace 支援內建進了 Node。IBM 則是在社群項目 llnode(給 lldb 加的分析 V8 堆棧的插件) 的基礎上加以改進,并且做了

node-report

(設定觸發 dump 出一切有用的資訊,包括 JS 堆棧、C++ 堆棧等)。Intel 就是之前說的帶 vtune 的 Node 編譯版本和基于 DPDK 的 libuv 了。相比來說,IBM 做的工作都歸到了 Node 基金會下面并都開源了出來,更有希望成為社群的主流工具。

JS 引擎中立與 ECMAScript 标準的參與

Node-ChakraCore

這也是一個弄了很久的項目,由微軟主導,将 Node.js 底層的引擎替換成 ChakraCore(IE 和 Edge 底層的 JS 引擎),并且和微軟研究院合作添加了 Time-travel debugging (可以倒着調試)這樣的黑科技(今年還給 FSE 投稿了一篇論文(

Time-Travel Debugging for JavaScript/Node.js

)。原理上來說就是在 ChakraCore 的 runtime hosting API (JSRT) 上做一個 V8 API 的 shim,這樣隻要支援全了 Node.js 使用的 V8 API 的子集就可以切換引擎了。目前來說在 Node.js 的倉庫裡塞兩個引擎似乎希望不大,是以把這個項目挪到了基金會下面,開發者使用的時候改用這個編譯出的 node 可執行檔案,理論上來說是可以無縫運作現有的 JavaScript 代碼的,至于 C/C++ addon 的平滑遷移則留給了新的 NAPI 項目來做。

Node.js Native API (NAPI)

這是之前的 NAN API 的改進版,因為之前的 NAN API 最開始是為了讓 C/C++ addon 不需要為 V8 更新而重新編譯做的,目的是抹平不同版本的 V8 API 的差距,是以整體上還是非常偏重 V8 的抽象,作為 JS 引擎中立的 API 不是很适合。這個新的 API 旨在讓開發者可以在切換 JavaScript 引擎不需要重新編譯 C/C++ addon,是以可以算是 JavaScript 引擎的 ABI 了。目前的目标是讓這個 API 到達可用的程度,推廣給社群替代 NAN,并且最終讓 Node.js Core 裡的代碼也改用這套 API(目前 Node.js Core 裡的 C++ 代碼都是直接

v8::xxx

這樣使用 V8 API 的),這樣最後能夠達到讓 Node.js Core 無縫在 JavaScript 引擎上遷移的效果。

這套 API 目前還是 C 的 (

node_jsvmapi.h

),而且打算是保證 C API 和 ABI 的穩定,再加上一個不保證穩定的 C++ Wrapper。目前實作已經有一定的可用性了,但是錯誤處理和性能影響評估等方面還需要加強。Google 的團隊給這個 API 做了 review,似乎沒什麼大意見,不過也沒法保證将來 V8 不會出現幅度太大的改進導緻 NAPI 無法跟進。現在的計劃是 Node v8.x 的時候釋出,看情況可能會放在 flag 後面,v10.x 的時候再決定要不要完全走這條路。

這個 API 最大受益者是手上在推 Node-ChakraCore 的微軟,另外在 Node Interactive 前 Mozilla 也宣布了加入 NAPI 的工作。IBM, Intel 等老本行就是這個的廠商也有參與。Mozilla 對 SpiderNode (使用 SpiderMonkey 作為 JS 引擎的 Node.js)投入了一定的精力,并且希望 SpiderNode 能在 WebAssembly (呃,不用介紹了吧)和 Shared Memory API (為 JavaScript 提供多線程程式設計的工具)方面做一些工作。現在看來主流浏覽器的 JS 引擎貌似就剩一個 JavaScriptCore 沒有向 Node.js 抛出橄榄枝了,雖然按照蘋果現在在社群的作風似乎也是可以了解的……(TC39 有吐槽曰,Apple is the new Microsoft, Microsoft is the new Google……)

FFI w/ JIT support

V8 正在基于 TurboFan JIT 做一個新的 dynamic FFI,用于在 JS 裡直接調用 C 函數,現在還在 proof of concept 階段的樣子,目測可能類似 LuaJIT 的 FFI。如果能夠做到 LuaJIT 的水準,JS 在 JIT 編譯後生成的機器碼裡通路 C 代碼的記憶體,開銷跟 C 編譯器編譯出來的 C 代碼通路 C 代碼記憶體差不多,函數調用也可以被 inline 而不像現在走 binding 要多出一堆多餘的動作。考慮到 Node Core 裡有很多部分還是放在 JavaScript 裡寫的,有很多地方為了性能會通過 binding 回到 C++,有一個 fast FFI 直接寫 C 會更快。不過外部的 Native Addon 被性能誘惑也開始用這個 FFI 的話,估計引擎中立 API 又有得頭疼了,畢竟 JITted FFI 這種東西怎麼想也是各家樂于自己搞的節奏……

TC39 的參與與 ES Module 的整合

由于 TC39 基本還是 pay to play,Node.js 基金會暫時無法作為非營利組織加入(吐槽:明明有 jQuery 基金會在前……),現在 Node.js 主要依靠 Node core 開發者以 invited expert 的身份,以及自己的成員公司在 TC39 的代表出席 TC39 的會議(包括 IBM,Paypal, Godaddy,Netflix 等)。目前來說 Node Core 和 ECMAScript 标準關系最密切的是 EcmasScript Module(ESM) 的實作,由于 ESM 在設計時基本沒怎麼考慮過 Node.js,關于同步/異步和符号靜态/動态的語義跟 Node 原來的 CommonJS Module(NCJS) 差得太遠,要做到兩種子產品加載的互動并且保證語義(特别是在有可能出現循環依賴的情況下)相當困難。

ESM 的标準原本包括一個 parser 和一個 loader,parser 部分被 ECMAScript 标準化,而 loader 部分被 TC39 決定從标準抽出,轉由宿主決定實作。在 Node.js 真正開始探索 ESM 之前,還出現了 Babel 這樣把 ESM 的文法轉譯到 NCJS 的語義的實作(但是 parser 其實完全不符合 ESM 标準)。Node.js 能夠依賴 V8 實作正确的 ESM parser,但是 loader 部分需要自己實作。當時 WHATWG 做出了 loader 的标準和參考實作,于是 Node.js 試圖讓自己的實作迎合 WHATWG 的 loader 标準,卻發現與 NCJS 子產品的語義差距太遠,新舊兩種子產品要互動會遇到非常多奇怪的 edge case 問題。而此後浏覽器廠商真正實作的 loader(

type=module

)又與 WHATWG 的 loader 完全不同(吐槽:WHATWG 這也能算 living standard……),相當于 Node.js 之前的功夫白費了。

于是 Node.js 提出了

新的 proposal

,希望能保持和已經有廣泛應用的 Babel 保持互動,中間經過了無比漫長的讨論,包括這個六百多個留言的 PR 和 Node 社群成員和 TC39 成員在 twitter 上漫長的大戰。最後 Node 社群決定向 TC39 送出 proposal 修改現有的标準,鑒于 Babel 的實作和 ESM 标準基本八竿子打不着邊,如果要和标準保持一緻難度太高,隻能放棄自己的實作和 Babel 的互動。在 Node 社群成員出席 TC39 會議後,發現 Node 一直在糾結的其實是較為嚴格的 Source Code Module Record,但事實上它是 Abstract Module Record 的一個具體實作, Node 其實可以按照自己的需求從這個父類繼承下來定一個寬松一些的 Module Record。總之現在 Node ESM 的實作還有很長的路要走,最起碼也要 v10 才能做出來。

(吐槽:Node 社群負責這個實作的 Bradley Farias 在講這段曆史的時候聽上去心都好累……TC39 真是牛角尖的龍卷風……)

V8 的優化與維護

由于 V8 的釋出政策是大約每六周從 master 上挑取出穩定的 patch 切成一個分支釋出(和 Node 有點類似),除了 master 以外,同一時間内隻有兩個分支 beta(下一個釋出)和 stable(目前釋出的版本)有在維護,這意味着大概每 6 周 V8 就會淘汰掉一個分支。而 Node 的 LTS 政策決定了每個 LTS 版本附帶的 V8 基本是同一個,一個 LTS 有 30 個月的生命期,就會導緻 Node 需要在兩年多的時間裡,自己維護 LTS 上那個已經淘汰掉的 V8 分支。這期間不可避免地會發現這個 V8 官方不再維護的分支有 bug 或者需要挑回來的 patch。由于 Node 對第三方依賴的維護政策是不自行改自己代碼倉庫裡的那份代碼,所有變動都必須在上遊修複掉之後把 patch 挑回來合并(backport),就需要花費不少精力在關注、定位、合并上遊 patch 上。現在 V8 與 Google Cloud Platform 的團隊有幾個人為 Node 社群做接應,幫忙盯着上遊需要合回來的 bugfix,為 Node 社群定位與 backport 需要的 patch,還會對 Node 裡的一些寫法進行優化或修複性能 regression,讓 Node 的 V8 維護工作完善了很多。

V8 從 5.6 開始終于要啟用打磨了三年的 TurboFan 優化編譯器,并配上 Ignition 解釋器,這套新的流水線理論上能夠

大幅度提升原生 ES 2015+ 的性能

。想想當年 Lars Bak 堅持 JavaScript 引擎不需要解釋器更不需要位元組碼,好像有點諷刺……

Ignition 是一個基于 Register-based 位元組碼的解釋器,一開始是為了配合小型裝置的需要設計的。原來的 baseline 編譯器(Full Codegen)編譯器以 AST 為 source of truth,但是因為 AST 太大了是以實際儲存的是源代碼,recompile 動辄需要 reparse,資源消耗更大,而且基于 AST 做 OSR(比如在循環中的去優化)不如在位元組碼上做容易。Full Codegen 類似一個 stack machine,基本隻是把 AST 翻譯到機器碼而不做任何優化,而 Ignition 在把 AST 編譯到位元組碼時,會對部分緩存起來的位元組碼做一些簡單的優化,是以編譯時間有時反而更長。目前來看似乎 Ignition 的好處更多在于在小型記憶體上消耗少和使架構更幹淨了一些,編譯速度和解釋速度相比起 Full Codegen 暫時沒有很顯著的優勢,雖然随着打磨應該會越來越好。

TurboFan 則是一個開發了很久的優化編譯器,之前主要負責處理部分 ES6 代碼和 asm.js/WebAssembly 的編譯,現在已經在 Node v6 及以上包含的 v8 中開始接手 Crankshaft 無法優化的一些寫法。V8 的大緻計劃是明年去掉原來的 Full Codegen 和 Crankshaft 兩個編譯器,改為 Ignition + TurboFan的組合,目前還保留原來的兩個是過渡階段的權宜之計。Crankshaft 在 ES5 上的優化确實不是 TurboFan 目前能完全趕上的,就連 TurboFan 的原生 ES 2015+ 性能相比轉譯到 ES5 再交給 Crankshaft 的性能依然有差距,但是 TurboFan 從架構和技術債務上來說都比 Crankshaft 有進步,逃逸分析也開始在做了,超越 Crankshaft 的性能還是很有希望的。

目前與 Crankshaft 相比,TurboFan 的優勢在于可以優化很多原來根本無法優化的寫法,以及對原生 ES2015+ 的優化支援。而對于編寫時已經小心避開去優化的 ES5 代碼,還是 Crankshaft 的編譯結果更好,這也是為什麼 Crankshaft 還沒有完全退役的原因。Full Codegen 沒有退役倒主要是因為 Crankshaft 去優化的時候回不到解釋器,隻能回 Full Codegen,是以捆綁了……嗯是以現在 V8 裡同時有四個東西,有點尴尬,雖然是暫時的……

Node 的下一個 LTS 版本大概會包含 v8 5.6 或 5.7,不過 5.8 也有非常小的可能(時間上可能趕不上)。另外下一個 LTS 也叫 v8,名字沖突了,目前計劃大概是直接跳過(類似 windows 9)或者明确寫 version 8 之類的,還沒有定……

新 Web 标準的實作

HTTP/2

由于目前 Node.js 裡的 HTTP 完全針對 HTTP/1.1 實作(無狀态,基于文本,一個連結一個 socket),幾乎不可能在此基礎上去實作 HTTP/2(有狀态,以二進制傳遞,資料可以被分塊後讓多個連結共用一個 socket,可以伺服器推送,還有大量的優化設計和新功能),是以目前的方向是另外寫一套代碼,挂在 HTTP 子產品的一個引用下(

require('http').HTTP2

),高層 API 方面盡量與 HTTP/1.1 靠齊,但底層設計不可能保持一緻。Node.js 裡 HTTP/1.1 的細節實作原本由 http_parser 處理,HTTP/2 則使用了 nghttp2,主要工作落在為 nghttp2 編寫 binding 并建構 JavaScript 層面的 API 上(比如提供能讓使用者用于自制協定的

Http2Stream

/

Http2Session

)。

目前服務端實作已經成型了(但是流的抽象等底層 API 還有待打磨),性能相比 HTTP/1.1 實作略有損失,但因為還在初級階段,還有很多的優化空間。用戶端實作方面得到了 Google 的協助,正在進行中。雖然 HTTP/2 協定本身不要求服務端必須有 TLS 保護,但目前各大浏覽器都隻接受與有 TLS 的 HTTP/2 伺服器連結,是以新的 API 也将是偏向于預設要求使用者傳入 TLS 配置的。目前這部分的代碼放到了

另一個倉庫下

,等到實作完善後再決定是否真的将這個方案納入 Node core。

WHATWG URL

Node.js 的 URL 子產品在實作時并沒有非常刻意地追求和浏覽器端标準一緻,目前跑 WHATWG 的測試基本是挂一大片的,現在決定嘗試重新按照 WHATWG 的 URL 标準做一個實作,這個目前還在非常原始的階段,和 HTTP/2 類似将另一套代碼挂在

require('url').URL

下面,不過沒有另開一個倉庫,隻是放到了

lib/internal/url.js

去實作。