动态

详情 返回 返回

JSON.parse 比 Object 字面量語法更快 - 动态 详情

寫在前面

原文地址:

https://www.bram.us/2019/11/25/faster-javascript-apps-with-json-parse/

原文中包含油管視頻,有梯子並且英文好的可以直接點開鏈接觀看。

針對太長不看的讀者

因為 JSON 語法比 Javascript 的語法更簡單,因此解析 JSON 比解析 Javascript 更高效。當一個 web app 需要加載在首次加載時,解析一個非常複雜的、大型的、符合 JSON 規範的對象字面量配置對象時(比如配置 redux 的 store),我們可以根據這一點來提升首屏加載性能。

為什麼 JSON.parse 更快

使用 AST 表示 JSON.parse(...) 更加簡單

AST 中,表示 JSON.parse(...) 更加簡單,只包含一個類型為 CallExpression,一個類型為 StringLiteraltoken 即可。

而表示等價的對象字面量代碼則複雜的多,複雜程度取決於 JSON 字符串所代表對象的複雜程度,每一個 key 值為一個類型為 StringLiteraltoken,每一個值為 NumericLiteral 類型的 token,但在 js 中,這個值實際可以為任何類型。

如果對象包含嵌套結構,則會涉及更多的 token 以及值類型,這對於 JS 解釋器來講,將不得不花額外的時間來解析它們以確保代碼能夠正確執行。

解釋 JSON.parse(...) 更加簡單

首先來説 JSON.parse('{ 這段代碼,當解釋器嘗試解釋這段代碼時,只會遇到兩種情況:

  • 它是一個合法的 JSON 字符串,如果它以 { 開頭的話
  • 它是一個不合法的 JSON 字符串

而對於 { 來講,情況就會變得複雜很多,首先來看一段代碼:

const x = 42
const y = ({ x }

對於這段代碼,解釋器讀到這個字節時,無法提前得知後續可能發生的情況。這裏的 y 真得會是對象字面量,還有可能是其他的情況嗎?如果解釋器不執行後續的代碼,它無法得出任何結論。

如果第二行代碼是這樣的:

const y = ({ x })

y 代表一個對象,而這裏的 x 指向第一行代碼中的 x 變量,它是 42

但如果第二行代碼是這樣的:

const y = ({ x } = { x: 21 })

這裏的 y 就會是 21,第一個 x 是用於結構賦值的,它指向後面對象中的那個值為 21x

這還沒完,如果代碼是這樣的呢?

const y = ({ x }) => x

這裏 y 則執行一個匿名箭頭函數了,而 x 代表一個結構賦值參數。

這些例子説明,對於 JS 引擎來説,解釋一段代碼,要根據它所處的上下文分析很多事情,而這會花費很多時間,而 JSON.parse 則更加簡單。

benchmark

1381345316-11844419e1c1224d_articlex.png

可以發現在各種不同的 js 引擎中,至少能夠提升 1.5x 的性能。

使用建議

雖然使用 JSON.parse 可以提升性能,但是不建議我們通過手動的方式來應用它,主要有以下兩點原因:

  • 使用 JSON.parse 比使用 Object 字面量可讀性低
  • JSON 字符串參數無法享受編輯器的高亮效果

建議的做法是,我們可以將這一步驟加入到代碼的編譯打包過程中去,比如使用babel-plugin-object-to-json-parse 插件。(注:這個插件只是實驗版本,穩定之前不建議在生產環境使用)

參考

  • https://v8.dev/blog/cost-of-javascript-2019#json

關注公眾號 全棧101,只談技術,不談人生
全棧101.PNG

user avatar tianmiaogongzuoshi_5ca47d59bef41 头像 Leesz 头像 alibabawenyujishu 头像 zaotalk 头像 smalike 头像 jingdongkeji 头像 dirackeeko 头像 aqiongbei 头像 chongdianqishi 头像 razyliang 头像 leexiaohui1997 头像 longlong688 头像
点赞 153 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.