語雀編輯器自研之路

本文爲螞蟻集團語雀自研編輯器技術負責人遇春在語雀大會上的演講。

大家好,我我叫遇春,接下來由我給大家分享語雀自主研發的編輯器。

在這之前組委會跟我說要分享一下編輯器裏面一些技術先進的地方,我就仔細思考這個問題,究竟語雀編輯器中什麼技術是先進的。在我看來。技術本身其實不存在所謂的先進技術或者是落後的技術。技術的目的就是爲了解決問題,可能會有新舊之分,但是語雀團隊又不是一個特別追求新技術的一個團隊,所以可能接下來我的分享中主要是針對我們所遇到的具體問題,然後怎麼樣找解決方案。從問題本身來說,每一個產品他遇到的問題都不一樣,所以很難對比說我們的技術就很先進。所以接下來的分享,我們來看看我們語雀編輯器遇到了什麼樣的問題以及技術上的思考。

先從這一句話開始。文有汝心出,筆墨語雀來。這一句是語雀最早的 slogan。

我們希望當你打開語雀編輯器的時候,能夠沉浸在一種平靜而又愉悅的創作心流當中。不管你是要寫一個週報或者是寫個小說,或者旅遊回來寫一篇遊記。我們都希望這個過程是一種享受。當你想要插入一個流程圖或者是插一個數據報表,或者想要插一個視頻,我們都希望在語雀編輯器當中都能夠隨手拈來,一氣呵成。這就是語雀編輯器所要追求的一個方向。

接下來,我的分享會包含這幾個部分

Part 1. 語雀編輯器的家族介紹

七兄弟

先給大家放一張全家福,這是語雀所有編輯器的一個全家福,我們根據時間給大家做了一個排行,老大、老二、老三、老四、老五、老六、老七。

文檔編輯器

先從老大文檔編輯器開始,能力比較強,人比較老實,然後也肯喫苦,裏裏外外全靠他,髒活累活全包。可以說有內容輸入的地方就有他的身影。我們可以看到包括語雀小記,各種評論區都是他來負責的,基本上可以說沒有他就沒有這個家。

目錄編輯器

老二目錄編輯器,可能大家比較驚訝,這也是個編輯器嗎?對的,這是一個如假包換的編輯器。因爲早年出去讀書,然後常年在外不怎麼回家,所以大家都不認識他。大學的時候,在圖書館裏做過勤工儉學,在分類整理這一塊,可是一個一等一的高手。所以這幾年回家來打理家務,家裏的資料、文件,經他這麼一手,把你整理的井井有條。

工作表/數據表

老三工作表,這個哥們天生喜歡數學。家裏所有的水費、電費、煤氣費,各種喫穿用度,所有的收入開支交給他,保證給你管理的妥妥的。後來他發現自己忙不過來,又有了老七,

老七是我們的數據表,數據表就和現在的小孩子一樣,天生的互聯網的原住民,他比較喜歡收集數據,他在收集數據這塊也是有一手,憑着這一手絕活,將來定是前途無量的。所以和數據有關的事情交給他們,穩!

思維圖,流程圖和演示文稿

老四老五老六,思維圖,流程圖和演示文稿,他們是個三胞胎,出生的時候日子過得比較好,營養跟得上,牛奶、雞蛋每天伺候着,身板硬了心氣兒就高,對吧?在圖形領域可真是沒有怕過誰,不是今天要幹翻這個,就是明天要放平那個,正可謂是初生牛犢不怕虎,立志闖出一片天。

七個編輯器,七兄弟齊心協力爲大家服務。那麼重點來了所有的語雀編輯器的所有功能,對所有的用戶,不管你是付費的還是免費的,一視同仁,所有的功能都向大家免費開放。

四版本

好的,這麼多編輯器肯定說不完。我們接下來挑一些有故事的說,先從文檔編輯器說起。

一句話介紹,簡約而不簡單,包羅萬象,普惠大衆,語雀文檔編輯器經歷了四個版本,每一個版本也都給我們留下了一些非常寶貴的特性。

1.0

從 1.0 開始,我們是一個 Markdown 編輯器,熟悉 Markdown 語法的同學都知道。我們可以通過輸入一些非常簡單的字符,然後實現一些清晰的文檔結構。標題,列表,引用等等,非常有利於閱讀。這也讓我們意識到文檔的美,美在結構。而這種快捷輸入的能力在我們 1.0 的時候就已經具備並且延續了下來。

2.0

2.0 我們進入了富文本時代,富文本時代給我們帶來了更加豐富的樣式,讓我們可以更盡情的發揮。而且富文本編輯器還給我們帶來了一個新的編輯模式,叫做“所見即所得”。你所編輯的就是你看到的,不再需要你反覆去預覽,這樣可以大大的提升了你的編輯效率。

3.0

3.0 時代,我們完全進入自研的時代,也就是大家近2年多一直在使用的編輯器,我們發現我們還需要在文檔裏插入一些特殊格式的數據,比如說一個日曆,比如說一個投票,比如說一個代碼塊,這樣的一個複雜的數據格式,我們需要能夠滿足,我們引入了卡片模型,卡片模型讓語雀整個編輯器變得更加開放,更加具有連接能力。藉助這個能力,我們可以連接互聯網,比如說你插入一個網頁進來也是可以的,我們也可以在語雀內部去做一些連接,不同的文檔之間也可以相互引入,原文檔編輯後,引入的文檔也會自動更新。

然後,3.0 還給我們帶來一個另一個能力,就是多人協同,多人協同讓我們語雀編輯器真正的實現了多人同時編輯,成爲知識協作的一個工具。

4.0

今天,我們進入 4.0 時代,4.0 編輯器剛剛發佈上線,大家可能夠直觀感受到就是我們的文檔表格已經可以多人同時編輯了。經過了半年的研發,我們底層做了一個很大的升級,在架構上也具有更好的靈活性和拓展性。大家知道我們的評論區裏面有很多用戶給我們提的建議,還有一些問題。雖然不是每個建議我們都能夠採納,但是 4.0 時代我們會給大家呈現更多的精彩,讓我們敬請期待。

當然剛剛上線難免會有一些問題,一些用戶在討論區裏面說我們的有一些交互變了。雖然這些交互的變化也是經過了我們的一些思考的,但總有不到的地方,我們希望大家不斷的給我們提意見。鮮花和雞蛋我覺得都會讓我們變得更好。

Part2. 編輯器成長故事

接下來我給大家介紹一下語雀編輯器的成長故事。

就像剛纔所說,其實語雀就是在用戶給我們不斷的吐槽,給我們不斷提建議的一個環境下長大的。那接下來的三個故事,讓我們慢慢來看。

故事1. 實時協同

先從第一個故事:實時協同。

在我們語雀商業化第一年的時候,其實我們是不具備這樣的一個能力的,我們當時是從我們自己的工作場景中觀察,發現多個人同時編輯一篇文檔的場景很少,偶爾會用到,頻率也很低。但是當時整個市場上對於這個功能是非常關注的,沒有這個功能,好像都不好意思跟別人打招呼,是不是這樣呢?我們要不要花費巨大的研發成本來實現一個低頻的能力呢?我們從來不是一個喜歡去跟風的一個產品,但是我們還是會反思的。我們在想這樣的一個功能,這樣一個低頻的功能,爲什麼大家如此關注?

我們後來仔細想一想,原來我們看待問題的方式可能有一些問題。

那就是使用頻率和重要性。它其實並不能夠劃等號。我舉個例子,一個商場它的消防設施可能並不是經常使用,對吧?我們也希望它一直不要使用,那消防設施其實它很重要。重要性決定我們要不要做這個功能,而使用頻率只是決定我們要把它做到什麼樣子,放在什麼位置。

當我們想通了這一點以後,我們覺得我們之前的顧慮和猶豫其實是有問題的。作爲一個提倡知識協作的產品,多人同時編輯會在關鍵時刻提升用戶的協作效率。於是我們決定要做實時協同。

實時協同我們怎麼設計呢?

我們在實時協同之前,語雀的編輯是一種鎖模式,就是一個人在編輯的時候,別人是不能夠同時編輯的。這也是基於內容的安全考慮,防止內容和版本變亂,那鎖模式它也有鎖模式的好處,比如說鎖模式比較簡單,比較穩定,它的離線也比較友好。我們希望這些特性也能夠在在繼續延續下來,所以我們額外增加了一個協同模式。

協同模式在團隊下,在協同的知識庫下面默認開啓,你的個人知識庫如果加了協作者也會幫你默認開啓協作模式。協作模式的好處,就是多個人同時可以同時編輯了,內容實時同步到多個編輯端。但是它也有它的缺點,比如協同模式對網絡的要求比較高,有些用戶他可能網絡比較慢,或者是經常會斷,或者是他設置了代理,有可能連不到我們的協同服務器上。這時候我們又增加了一個叫做智能切換的能力,我們可以將你從協同模式切回到鎖模式,讓你更加穩定的去編輯,這就是語雀編輯器在協同這一塊的設計。

實時協同上線了1年多,我們也遇到很多問題。

剛上線的時候其實有很多很難解的問題。比如說丟光標、內容錯亂,大家可能偶爾會遇到過,這些問題有很多問題很不好復現。因爲你在正常編輯下可能還發現不了,只有那些非常奇怪的一些場景纔會出現。然後我們用了接近一年的時間來不斷的修bug,改造底層,交互調優,把這些協同的問題慢慢的解掉。在協作模式和鎖模式之間實現平滑無感知的智能切換,到去年的下半年語雀的實時協同的功能才逐步的趨於穩定。

故事2. 表格滾動

接下來一個故事是關於表格滾動的

表格編輯器在當初的定位是要把 Excel 20% 的基礎功能做到極致,發揮在線的協作優勢,將 80% 的數據處理場景做透。這樣一個定位決定我們肯定不可能把那個 Excel 的功能全部照搬過來。當然這也不太現實,畢竟人家做了三十幾年。既然不能全部照搬,那我們就從最基礎的功能去着手。

我們要把基礎功能的體驗做到極致。那基礎體驗是什麼?

我把它比喻成空氣和水,乾淨的水和清新的空氣本身就可以給大家帶來一些愉悅的感受。我們希望語雀的編輯器能夠像乾淨的水和空氣一樣,給編輯者帶來最自然的愉悅感受。

怎麼樣把基礎體驗做得極致呢?我們說用戶會告訴我們,我們常說和用戶一起成長,這句話有人可能不太好理解。其實我們的故事就是這樣子發生的。

先從表格編輯器中一個最基礎的功能來說起,就是滾動。

在你查看錶格的時候,你總是需要上下滾動,或者左右滾動來查看你需要的那一行或者一列數據。我們知道受瀏覽器的一些渲染性能的侷限性,表格的滾動可能每個 web 產品的做法可能都不一樣。有一種滾動叫做行級滾動,就是一行一行的滾動。一些知名的產品也採取了行級的滾動。我們可以看一看行級滾動是一個什麼樣的效果。

當你的每一行的內容有一些多的時候,你會發現它的滾動過程中是跳動着的。甚至極端場景,某一行的內容高度超過視窗,你是看不到這行內容底部的內容的。可以自行腦補一下。

然後我們再看一看語雀的像素級滾動

像素級滾動就明顯平滑很多,然後這是語雀在滾動這一塊做的一個體驗。中間爲了實現這樣的一個特能力,我們其實做了很多技術上的優化方案。比如說根據視窗來按需渲染,比如說我們要實時計算並緩存每一行的高度,等等。

做完像素級滾動以後,我們覺得我們的滾動效果挺好了,然後又有用戶跟我們反饋了,說你們的滾動好像有點“晃”,還給我們發來了視頻,我們就仔細琢磨了一下。你說的“晃”是什麼“晃”。

那其實是這樣子的,最初我們做的滾動呢,它是橫向和縱向可以自由滾動的,橫向和縱向都可以同時滾動。(我拿一個自由滾動的友商產品舉個例子)

如果是觸摸板的同學可能感受更深一些,你會發現當你橫向滾動的時候,你的縱向難免會有一些偏移,所以當你想查看某一行數據的時候,你的視線在這種滾動的時候會受到干擾,你的注意力會聚焦不到你所關注的那一行。

於是我們又增加了方向的約束,

然後我們看到上面的這張動畫,就是我們現在的滾動效果,橫向滾動和縱向滾動的時候,它的另一個方向就會鎖住。這樣的話你的整個滾動會更加穩定,視覺的焦點頁能夠更加專注,數據的檢索會更加高效,這就是我們的滾動。

在語雀表格編輯器中這樣的細節體驗其實還有很多。

我們今天就不一一介紹了。

故事3. 讀寫分離

第三個故事是關於讀寫分離的。

我們先說一說讀寫分離的一個設計初衷。我給大家說兩個場景,大家感受一下。

第一個場景,你正在寫一篇文章,你的身後站着一堆人在那裏看,你是什麼樣的一個感受,你會不會覺得你的腦袋是完全空白的,不知道該寫什麼,對不對?

第二個場景,你正在看一篇文章,你發現光標在動,有個人正在寫,還有人在刪字,還有一些人在調整段落格式,又是一個什麼樣的閱讀感受,你會不會也覺得有些不知所措,這篇文章究竟有沒有寫完,要不要現在看?

這就是讀和寫,它本身是兩種場景。如果把他們揉在一起,會發生很奇怪的一些體驗。所以我們希望對作者來說,他的寫能夠在一種平靜又沉浸的一個創作環境中,他能夠無所顧慮的寫。而讀者他能夠放心的去閱讀。然後在這兩個體驗之間,我們用一個“發佈/更新”的動作來實現連接。這個發佈讓我們的作者更加有儀式感,這個動作告訴作者,你的內容將交給讀者,由讀者來閱讀。

這樣的一個“讀寫分離”的設計的使用反饋是怎麼樣的呢?

我們看一看,首先有一部分用戶說挺好的,這樣的我可以放心大膽的寫了。也有一部分用戶會說我一個人寫爲什麼要發佈呀?好麻煩呀。是的。同一個體驗設計收到截然不同的兩種反饋。我們是什麼樣的感受,讀寫要不要分離,我們的內心是陷入矛盾的,是堅持還是妥協?問題在哪裏?然後我們就去想怎麼樣去改進這個問題。

分析發現,其實是讀者和作者這兩個角色的關係問題,我們後來增加了一個自動發佈的選項,

對於那些讀者和作者是同一個角色的時候,我們就開啓這種自動發佈的選項。比如我們的個人私密的知識庫下,我們就默認開啓,比如我們的桌面端,桌面端我們就會默認進入寫模式,這樣的讀寫分離就會更加友好,我們根據讀寫兩種角色是否爲同一個角色來決定讀寫分離的方式。

好的,3個用戶故事我們就講到這裏。

Part3. 編輯器防火牆

接下來我給大家分享一下雲雀的編輯器的防火牆:防丟、防亂和防卡。

這一章節之前,在這裏向之前所有被語雀編輯器弄丟過、卡過或者弄亂過內容的用戶表示一聲歉意。確實是我們一開始做的不到,給大家帶來了麻煩,那也同時要感謝大家,陪伴我們,幫助我們反饋問題,協助排查問題,才讓我們不斷的可以去完善產品,來改進體驗。

防丟

先從防丟開始說

內容不丟,我們把它當成是一個基礎體驗的底線。有人說自動保存不就可以了嗎?是真的這麼簡單嗎?

我們看一些客觀的因素

首先,保存是個大動作,語雀採用的是快照模式的保存,每次保存需要編輯器將全文整理好,發送給服務端,當保存動作和輸入動作同時發生的時候,尤其大文檔的時候,容易造成輸入卡頓。

其次,歷史版本過多也容易讓人抓狂,不太方便追述。所以我們需要緩存,而緩存是有容量限制的。

再次,網絡是個非常不靠譜的東西,斷網,弱網,代理網絡都有影響。

最後,用戶習慣不可琢磨,有些編輯頁打開半個月都不關,我們已經中間發佈過好幾次了,有些同一篇文檔開着N個窗口,今天這個窗口寫兩句,明天那個窗口寫兩句,這些現實問題給保存帶來了非常大的挑戰。

我們來看看語雀的自動保存的設計,

爲了應對各種狀況,我們聘請了5位管家和一位專屬快遞員,這裏的文字比較多,就不給大家讀了。這五大管家核心的任務是什麼?就是在最合適的時候將你的內容該緩存的緩存,該保存的保存,在你離開的時候,我們會第一時間保存。在你激活的時候第一時間更新內容。

當你離線的時候,我們這位快遞員就會在你下一次上線的時候,將你的離線的編輯內容第一時間保存一份到服務端,作爲快遞員他很貼心,它保存服務端的過程中,如果出現一些網絡問題沒有成功,它不會將你的離線緩存給刪掉。所以只要你存到我們的離線緩存裏面,你自己不去主動刪,內容基本上是安全的。

這樣一個設計之後有很有一些調皮的用戶就說那麼怎麼樣才能丟內容呢?這個問題確實挺奇特的。想要丟內容也不是做不到,除非你打開編輯器,一秒不停的編輯,然後斷電了。或者離線編輯,然後手動的刪除了你的離線緩存。如果你真的這麼操作,目前情況下我們是沒法保全你的內容的。當然家下來我們會繼續完善這裏的機制,做到只要你肉眼看到的就不會丟掉。

防亂

下一個防火牆是防亂,常見的亂有哪些呢?

首先最最基本的亂,就是多個人基於同一個版本來編輯。然後後面的保存的覆蓋了前面的,這是一種版本錯亂。第二個就是你的協同模式下,你的網絡可能有些問題,你的數據沒有同步到服務端,那有可能造成某些版本的數據的丟失。然後還有一些程序bug,這就不多說了。

剛纔說了我們有兩種模式,每一種模式遇到問題都不一樣,解法也不一樣。我們今天就重點說一下鎖模式,鎖模式爲了防亂,我們首先給文檔設計了一個版本號,這個版本號會跟隨着文檔。然後當你保存了一次,他的版本號會加1,然後你每次保存也會攜帶着你編輯前的基線版本號到服務端,服務端會判斷你這個版本號是不是最新的。如果不是最新的,就不會保存成功,會提示衝突。

每次當你打開編輯器的時候,我們會去服務端請求最新的版本,然後來和你本地緩存的基線版本做對比,然後讓你基於最新的版本去編輯。

在你離開的時候,我們也會將你的內容第一時間保存到服務端。同時在你編輯的過程中,我們也會每一分鐘去服務端請求一下有沒有最新的版本。這樣的輪詢考慮的是一些斷網場景,你可能編輯的時候斷網了自己都不知道,而在你斷網的時候,你的鎖權限其實已經收回去了。那別人可能在你斷網的過程中編輯了內容,版本已經升上去了。這時候我們我們的輪詢會保證你的編輯過程中,即使斷網。遇到別人同時編輯的時候,也會在你連網的第一時間,獲取最新版本,能讓你每次都基於最新的版本去編輯。

但如果出現保存衝突或者有更新的版本怎麼辦呢?我們會把你的離線編輯的緩存版本備份一份到歷史記錄裏,這樣方便你後期手動的把那些離線的內容同步到文檔的最新版本中。

防卡

最後說一說如何防卡,常見的卡也是有兩種:

一種是流程的卡,我們某些彈窗讓你沒法往下繼續編輯,這種叫做卡住的卡。

還有一種卡就是卡頓的卡,性能不太好,然後編輯不夠順暢。

這兩種也都有自己的一些解決方案。

性能卡不用多說,就是不斷的去優化性能,然後我們會做一些性能的監控。

流程的卡我們有很多措施,比如說我們的模式智能切換,當你沒法連上我們的協同服務器的時候,那我們不希望將你卡住,我們會將你降級到鎖模式下去編輯。

我們對鎖模式做了很多次升級也都是防卡設計,我們最初是鎖人,不同的人不可以同時編輯。但是我們發現這還不夠,有些人他是同時打開多個瀏覽器的,多個窗口之間會相互卡住,我們就開始升級到鎖端,鎖端又有可能自己把自己也給鎖住了,需要切到有權限的編輯端,或者等待1分鐘。我們覺得不好,然後我們又加一個不自鎖。不自鎖還是不夠,因爲用戶就是沒法避免兩個頁面之間不停的來回切,我們不僅要解決鎖的問題,還要解決內容同步的問題,我們於是在離開的時候自動解鎖,並且把你的內容及時保存上去,在你激活一個編輯器的時候,要同時把最新的內容更新下來。這樣的一個鎖模式的不斷升級,來讓我們在鎖模式下,盡最大可能減少卡住的情況。

說到卡,在流程的順滑方面,我們還有一些分級的提醒設計。舉個簡單的例子,我們的保存有自動保存和手動保存。自動保存我們是不會提示的。因爲我們希望你在沉浸的編輯當中自動保存它是背後自然發生的,而手動保存會提示你保存成功,這也是基於一個交互的實時性反饋考慮,同樣是保存,有些需要默默完成,有些需要及時響應。

另外,有些異常如果我們能夠應付過來,我們就把它以一種消息提醒的方式在右上角出現,會提示你有點小狀況,不過我們已經給你處理好了,可以繼續放心編輯。如果是我們覺得這個問題特別嚴重,那我們就會提示一個彈窗出來,讓你來決定下一步如何操作。

以上就是語雀在防丟,防亂以及防卡方面所做的一些設計。

Part4. 編輯器的詩與遠方

最後一趴給大家分享一下編輯器的詩與遠方。

先從這個塔模型開始說,

這是一個我比較喜歡的一個模型:DIKW模型。它給我們揭示知識的演化過程,從數據到信息到知識到人類智慧的一個演進模型。最底層是我們的海量的數據。在數據當中我們可以提煉和觀測出一些有用的信息,信息相對數據更加濃縮,然後不同的信息,不同維度的信息,經過一些組織,一些思考,一些推理,能夠發現它其中的一些規律,形成我們的知識,知識的運用形成智慧。在這個知識形成的模型當中,我認爲編輯器更像一個階梯。他在每個環節中承擔了這種階梯的作用,讓數據昇華爲信息,讓信息昇華爲知識,是一個工具。可以說編輯器就是促進知識形成的一個工具。我們會不斷的增加語雀編輯器在每一個環節的能力,讓語雀編輯器不負使命。

再分享一棵樹,這顆樹我們可以叫他爲知識之樹。

有一個有意思的問題:知識是什麼樣子的?大家覺得知識是什麼樣子的?有人說知識可能是網狀的,然後有人說知識是樹狀的,那究竟是什麼樣子呢?其實看你怎麼樣看待這個問題,取決於你的觀測角度,從編輯器的角度來看,我們希望知識它更像一棵樹,知識的創作從無到有,它其實是一個生長的過程,我們希望它有脈絡,有主幹,有枝葉,這樣子在創作過程中,包括後期的學習中,你能夠更更好的把握它的結構。這是從創作和學習的角度考慮,那麼一定還有其他的角度,我覺得語雀編輯器的職責就是讓知識能夠自由的生長成爲他應有的樣子。從古至今,人類把文字記在龜殼上,到寫在竹籤上,再寫在紙上,錄入到電腦上,網絡中,那知識的形態也發生了不斷的變化,從圖形到文字,到圖片,到聲音,視頻。知識究竟應該什麼形態纔是最棒的呢?語雀的編輯器也在不斷的探索,希望能將知識呈現出她最好的樣子呈現給大家。

這就是我的分享,感謝。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章