欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS生態(tài)系統(tǒng)加速探索Draft-js?emoji插件功能及使用探索

 更新時(shí)間:2024年01月21日 11:24:39   作者:大家的林語冰?人貓神話  
這篇文章主要介紹了JS生態(tài)系統(tǒng)加速探索Draft-js?emoji插件功能使用探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

長(zhǎng)話短說:從 42kB 的重字符串中,從零開始構(gòu)建了 7138 次正則表達(dá)式。緩存該計(jì)算大大加快了 Draft-js 表情符號(hào)插件的初始化階段。

本期《前端翻譯計(jì)劃》共享的是“加速 JS 生態(tài)系統(tǒng)系列博客”,包括但不限于:

  • PostCSS,SVGO 等等
  • 模塊解析
  • 使用 eslint
  • npm 腳本
  • draft-js emoji 插件
  • polyfill 暴走
  • 桶裝文件崩潰
  • Tailwind CSS

本期共享的是第 5 篇博客 —— Draft-js emoji 插件。

Draft-js emoji 插件

我通過 Josh Goldberg 的電郵收到了一個(gè)非常有趣的問題,涉及一個(gè)網(wǎng)站卡死了大約 2-3 秒。該網(wǎng)站使用 Draft-js 富文本編輯器進(jìn)行一些輸入,它能夠?qū)⒎秶s小到 Draft-js 表情符號(hào)插件中出現(xiàn)的問題。

通過 Chrome 的分析器捕獲的快速記錄證實(shí)了最初的懷疑。表情符號(hào)插件出 bug 了。我們可以看到,底部有一大坨頻繁的函數(shù)調(diào)用,占用了大部分時(shí)間。不幸的是,Chrome 的分析器沒有像 speedscope 那樣的某種“left-heavy”可視化功能。這使得確定哪個(gè)函數(shù)值得研究變得有點(diǎn)困難。“left-heavy”對(duì)此更好,因?yàn)樗鼘㈩愃频恼{(diào)用堆棧合并為一個(gè)。

每個(gè)單獨(dú)的調(diào)用看起來都棒棒噠,并且總是以調(diào)用正則表達(dá)式引擎結(jié)束。但一大坨調(diào)用已經(jīng)足以引發(fā)憂慮。Chrome 分析器一個(gè)很酷的事情是,它可以使用采樣的跟蹤來注釋源碼行。這將為您提供每行執(zhí)行所需的大概時(shí)間。由于前端項(xiàng)目涉及大量轉(zhuǎn)譯,它并不是 100% 準(zhǔn)確,但它足以得出一些早期結(jié)論。

消耗大部分時(shí)間的兩種方法都處理正則表達(dá)式。大家可能很容易得出結(jié)論,正則表達(dá)式本身是罪魁禍?zhǔn)祝矣幸环N感覺,這只是深層問題的表癥。我們首先檢查的是此函數(shù)被調(diào)用的頻率。這可以通過增加一個(gè)簡(jiǎn)單的計(jì)數(shù)器,或直接使用 console.count()。

  ns.escapeRegExp = function(string) {
+   console.count("escapeRegExp");
    return string.replace(/[-[\]{}()*+?.,;:&\\^$#\s]/g, "\\$&");
  };

  ns.replaceAll = function(string, find) {
+   console.count("replaceAll");
    var escapedFind = ns.escapeRegExp(find);
    var search = new RegExp("<object[^>]*>.*?<\/object>|<span[^>]*>.*?<\/span>|<(?:object|embed|svg|img|div|span|p|a)[^>]*>|("+escapedFind+")", "gi");
    // ...
  };

事實(shí)證明,每當(dāng)頁面加載時(shí),replaceAll 方法就會(huì)被調(diào)用 7318 次。接下來,我們檢查了 escapeRegExp 被調(diào)用的參數(shù)類型。理論上,也許它會(huì)被相同的參數(shù)反復(fù)調(diào)用。

一分鐘后,這個(gè)假設(shè)被實(shí)錘了,因?yàn)樗磸?fù)轉(zhuǎn)義同一個(gè)字符串。我們知道此方法是從 replaceAll 調(diào)用的,所以讓我們檢查一下是否總是在那里傳遞相同的參數(shù)。果然,第一個(gè) string 參數(shù)收到兩個(gè)不同的值,但第二個(gè) find 參數(shù)始終相同。這就是后來傳遞給 escapeRegExp 的那個(gè)。

圖窮匕見的問題是:“誰在調(diào)用 replaceAll,為什么它們總是傳遞相同的參數(shù)?”

再次放大配置文件,我們觀察到對(duì) replaceAll 的所有調(diào)用都將 toShort 作為共同祖先。

這里發(fā)生了一些非常有趣的事情,傳遞給 replaceAll 的第二個(gè)參數(shù),根本不依賴傳遞給 toShort 的參數(shù)。沿著 unicodeCharRegex 的線索,我們可以更清楚地了解此處代碼的用途。與 Slack 等流行聊天 App 一樣,draft-js 插件允許您輸入文本 :smile:,然后該文本會(huì)自動(dòng)轉(zhuǎn)換為正確的表情符號(hào)“??”。但反過來也是必要的,這就是我們?cè)谶@里看到的。

尋找解決方案

進(jìn)一步了解此代碼的用途后,我們注意到,正則表達(dá)式是通過迭代 unicode 字符及其元數(shù)據(jù)的大數(shù)據(jù)結(jié)構(gòu)構(gòu)建的。然后將此正則表達(dá)式應(yīng)用于傳入的文本,匹配表情符號(hào)并將其替換為短代碼。每次調(diào)用 toShort 時(shí),都會(huì)從零開始構(gòu)建正則表達(dá)式。這成為了一個(gè)性能問題,因?yàn)?nbsp;unicode 標(biāo)準(zhǔn)有無數(shù)的表情符號(hào),并且隨著膚色和其他東西變化。是的沒錯(cuò),難怪生成的正則表達(dá)式很大。

Chrome 的控制臺(tái)顯示,構(gòu)建正則表達(dá)式的生成字符串比單獨(dú)的 42kB 更大。

與大多數(shù)昂貴計(jì)算的情況一樣,我們可以通過緩存先前的結(jié)果來避免大量工作。這樣我們就不需要反復(fù)重新計(jì)算同樣的事情。這是侵入性最小的修復(fù),不需要對(duì)插件的架構(gòu)大更改。我們做了一個(gè) PR,它總共將阻塞時(shí)間從 2-3s 減少到 <200ms。

完結(jié)撒花

如果我們退后一步,每當(dāng)該模塊首先加載時(shí),總是構(gòu)建該正則表達(dá)式似乎是浪費(fèi)。結(jié)果總是相同的,因此優(yōu)化是存儲(chǔ)轉(zhuǎn)換后的結(jié)果,并在插件中使用它。每當(dāng)發(fā)布新版本的插件時(shí)都可以構(gòu)建它。

另一個(gè)潛在的想法是,使用手工函數(shù)來匹配表情符號(hào)。它可以讓您非常快速地縮小潛在匹配項(xiàng)的搜索空間,但仍然需要驗(yàn)證此方案在該情況下是否比正則表達(dá)式更快。我認(rèn)為值得一試。

一個(gè)更好的想法是,我們可以利用最近的 unicode 增強(qiáng)功能,而不是構(gòu)建 >40kB 的正則表達(dá)式。這包括特殊的 unicode 屬性轉(zhuǎn)義,比如 Emoji_Presentation,它允許您直接匹配所有表情符號(hào)(比如:/\p{Emoji_Presentation}/gu)。這樣我們就可以完全擺脫所有正則表達(dá)式生成代碼。

總的來說,這個(gè)特定問題很好地提醒我們時(shí)不時(shí)地分析我們的代碼。這提醒我們,即使是看似無害的函數(shù),也會(huì)對(duì)性能產(chǎn)生巨大影響。

免責(zé)聲明

本文屬于是語冰的直男翻譯了屬于是,略有刪改,僅供粉絲參考,英文原味版請(qǐng)傳送 Speeding up the JavaScript ecosystem - draft-js emoji plugin

以上就是JS生態(tài)系統(tǒng)加速探索Draft-js emoji插件功能及使用探索的詳細(xì)內(nèi)容,更多關(guān)于JS Draft-js emoji插件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論