Deno 兼容瀏覽器詳細指的是什麼?

Deno 內里有一句形貌:”Aims to be browser compatible”,能夠看到 Deno 的目的是兼容瀏覽器。那末這裏的兼容瀏覽器究竟怎樣是什麼意義呢?

我簡樸談談我的明白吧。

起首這裏的兼容性一定不是 Deno 直接在瀏覽器端運轉。由於 Deno 是一個和瀏覽器平級的 Runtime。

許多人另有誤會認為兼容瀏覽器指的是 Deno 會供應“相似 Node.js 里的 UMD 寫法”。起首我們明白一點,這裏的兼容不是單指語法層面的兼容,並不是說要兼容 ES3 ES5。所以不要發生這類誤會,認為能夠經由歷程 babel 兼容 Node.js 和 Deno。

在 Deno 的 Roadmap 內里作者就已寫到了:

Deno does not aim to be API compatible with Node in any respect. Deno will export a single flat namespace “deno” under which all core functions are defined. We leave it up to users to wrap Deno’s namespace to provide some compatibility with Node.

這裏的兼容,我的明白是兼容瀏覽器的 API 和生態。(坐等被打臉)

之前有個 issue discussion: struct the browser-compatible APIs #82 議論這個題目,在 issue 中列舉了一些想要兼容的瀏覽器 API:

  • High level

    • Console ✓
    • URL ✓
    • File/FileList/FileReader/Blob
    • XMLHttpRequest/Fetch
    • WebSocket
    • URLSearchParams
  • Middle level

    • AudioContext/AudioBuffer
    • Canvas

議論中還包含 WebGL 設置 GPU 的支撐。我們能夠隱隱猜到 Deno 的一個目的就是讓瀏覽器中的代碼能夠直接運轉在 Deno 上面

我的看法依然是:Deno 不是下一代 Node.js。(再次坐等被打臉)

Deno 是一個“A secure TypeScript runtime on V8”。一個平安的基於 V8 的 TypeScript 運轉時,這個怎樣明白呢。

瀏覽器能夠認為是平安的 JavaScript 運轉時,一切的 JavaScript 代碼都是在沙盒(Sandbox)內里運轉。瀏覽器雖然裝置在你的電腦上,然則瀏覽器內里運轉的 JavaScript 代碼能夠來自世界各地,換言之瀏覽器內里運轉的都是不受信代碼,怎樣保證瀏覽器的 JavaScript 代碼不損壞你的電腦體系,這是瀏覽器平安機制須要處理的一個題目。而 Node.js 則不是,和任何的 Web 服務器一樣,Node.js 運轉的是受信代碼

之前 V8 湧現了關於逃逸剖析(Escape Analysis)的平安漏洞,Chrome 採取了緊急措施,鄙人一個版本中刪掉了逃逸剖析相干的功用,相比之下,Node.js 則沒有受到影響,由於 Node.js 運轉的代碼原本就是受信的。

從這個角度講,Deno 和瀏覽器的定位很像。

由於我們能夠看到,兼容服務器端生態和兼容瀏覽器端生態的一個區分:

  • 瀏覽器內里運轉的都是不受信代碼
  • 服務器運轉的是受信代碼

我們再換一個角度聊聊服務器生態。

許多人另有一個誤會,就是以為上面提到的那些 API,關於 Node.js 也完整能夠兼容,比方 Console、URL、XMLHttpRequest/Fetch 等,許多 API 都已被 Node.js 完成了。

當 Node.js 被開闢出來的時刻,相似 File、URL、Buffer 這類的 API 瀏覽器端都還沒有,但由於 Node.js 定位為服務器端運轉平台,因而 Node.js 參考的是其他 Web 服務器或許服務器編程言語。比方文件體系(File System),完成了一系列 POSIX(Portable Operating System Interface,可移植操縱體系接口) 兼容的函數和功用。

另有一點須要注重的是 Node.js 和瀏覽器的趨同化,比方 Node.js 7 到場的 URL API,而現今的主流瀏覽器也都供應了這個 API,這是由於 Node.js 也運用了 WHATWG URL 規範。

WHATWG 的全稱是 Web Hypertext Application Technology Working Group,網頁超文本應用技術工作小組。這是一個相稱“有分量”的構造,當 W3C 決議摒棄 HTML 盤算將將來的重點放在 XHTML 2.0 上時,WHATWG 堅決擁護 HTML,並制訂了下一代 HTML 設想。終究 WHATWG 說服了 W3C 並與其一起宣布了 HTML5。

如今 Web 的飛速發展我們要謝謝這些構造的勤奮。

那末如今就有一個疑問了:假如 Node.js、瀏覽器、Deno 都運用這些規範后,那末他們是否是就會變得一樣,Deno 會不會庖代 Node.js,成為下一代 Node.js?或許 Deno 變成一個和 Node.js 一樣然則比 Node.js 還難用的平台,終究被邊緣化或許被揚棄?

不會。由於機能和平安是不可兼得的,比方 File/FileReader/Blob 這類 API 生成就是為瀏覽器端沙盒環境設想的(WHATWG 很多規範都是為瀏覽器設想的)。Node.js 還沒有供應響應的 API,而且也不盤算供應,畢竟在服務器端環境我們更須要的是文件體系,所以 Node.js 不去擁抱 WHATWG,而挑選了 POSIX。

既然談到了這個,那我就再講的深切一點吧,深切究竟層看看為什麼 Node.js 不是用 Blob 和 FileReader 來讀取文件。

在瀏覽器端文件一般來自於收集,由 url 供應,或許來自於表單的用戶主動挑選。不管何種體式格局都是由瀏覽器來完成文件的讀取,並把文件內容加載到內存緩衝區中,這時候 JavaScript 能夠經由歷程 Blob 來操縱此文件。然則 Node.js 卻沒有完成這些 API,而是在文件體系之上構建了 Stream 模塊來完成。再看看其服務器端編程言語比方 Java、PHP 也都供應了 Stream。

假如我們把 Node.js 作為一個 Web 服務器,那末我們橫向和 Nginx 對照一下。假如運用 js 開闢一個靜態文件服務器,那末 Nginx 能夠輕輕鬆松以十倍百倍的機能輾壓 Node.js。

我們能夠從底層剖析一下二者為什麼相差懸殊。這裡有幾個知識點:

  • 用戶空間
  • 內核空間
  • 歷程上下文
  • 中綴上下文
  • DMA
  • Zero Copy

為了平安斟酌操縱體系不允許用戶代碼直接操縱硬件,為了保證操縱體系內核的平安,將空間劃分為兩部分,一部分為內核空間,一部分為用戶空間。用戶編寫的代碼運轉在用戶空間,當須要運用底層功用時,能夠經由歷程體系挪用進入內核,比方文件讀取。

當用戶歷程經由歷程體系挪用從用戶空間進入到內核空間時,體系須要將用戶歷程的上下文保留起來,當再次從內核空間回到用戶空間時,體系恢復此上下文。

關於靜態服務器,則這個步驟大概是:

  • 挪用 read,文件被 copy 到內核緩衝區
  • read 函數返回,文件從內核緩衝區 copy 到用戶緩衝區
  • write 函數挪用,將文件從用戶緩衝區 copy 到內核與 socket 相干的緩衝區
  • 數據從 socket 緩衝區 copy 到相干協定引擎

《Deno 兼容瀏覽器詳細指的是什麼?》

能夠看到文件在全部歷程當中被 copy 了 4 次。

而 Nginx 底層運用 sendfile,能夠完成 Zero Copy (零拷貝)。

全部流程變成了:

  • sendfile 體系挪用,文件被 copy 至內核緩衝區
  • 從內核緩衝區 copy 至內核中 socket 相干的緩衝區
  • 從 socket 相干的緩衝區 copy 到協定引擎

《Deno 兼容瀏覽器詳細指的是什麼?》

能夠看到在這個歷程當中,只要 3 次 copy。而且沒有了用戶空間和內核空間的切換,也不須要保留和恢復歷程的上下文。實在上面另有優化的餘地,由於在內核中發生了一次緩衝區到緩衝區的 copy。在 Linux 內核版本 2.4 以後,DMA 模塊將數據直接從內核緩衝區傳遞給協定引擎。

《Deno 兼容瀏覽器詳細指的是什麼?》

雖然稱為 Zero Copy,然則數據依然是從磁盤複製到了內存,從操縱體系的角度來看這個是必需的,所謂的零拷貝是指內核中沒有冗餘數據,數據不須要在內核拷貝。藉助 DMA 模塊此歷程完整不須要 CPU 介入。

在 Nginx 中只須要數據副本的 2 個 copy,而 Node.js 則須要 4 次。假如 Node.js 要想運用 Zero Copy 也有要領,比方運用 os 模塊的功用,或許直接運用 C++ 擴大。

從另一個角度講,Node.js 的機能消耗不僅僅是 4 次 copy 以及歷程上下文的保留和恢復,還包含數據和代碼從 C++ 到 JavaScript 的重複逾越邊境。

我們回過頭來議論瀏覽器,關於瀏覽器來說,基礎就不須要這個特徵。由於瀏覽器中的 JavaScript 代碼不僅僅是在內核空間運轉,而且照樣在沙盒空間運轉。

所以與其在此猜想兼容瀏覽器指的什麼,不如對照瀏覽器和服務器的差異:

  • 瀏覽器運轉不受信代碼,服務器運轉受信代碼
  • 瀏覽器遵照 W3/WHATWG,服務器遵照 POSIX
  • 瀏覽器體貼 API 層的機能,服務器更體貼操縱體系層的機能
  • 瀏覽器才能受限,服務器才能不受限

掃碼二維碼關注我的民眾號,每周推送原創前端內容

《Deno 兼容瀏覽器詳細指的是什麼?》

    原文作者:justjavac
    原文地址: https://segmentfault.com/a/1190000015458678
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞