百度文庫 文檔閱讀器


百度文庫新一代文檔閱讀器!核心技術點全解析! https://mp.weixin.qq.com/s/sr1hKlkSlN0528_RfdUkrg

百度文庫新一代文檔閱讀器!核心技術點全解析!

 

技術視野:
1、
圖形繪制可以直接借助於開源方案,比如fabric,輕松實現各種圖形的繪制

2、

vite + ts,vite 能夠帶給我們極致的開發體驗,ts 能夠讓我們寫的代碼更有保障,業務方調用API時更便捷

 

小結:

1)

渲染機制對比:
Canvas HTML+CSS SVG WebGL

 

 

2)

一但某頁不可見時,立馬釋放內存空間,這一措施讓整個閱讀器的內存占用降低90%

 

導讀:文庫有數十億文檔,包括 word、ppt、excel、txt 和 pdf 等十幾種常見辦公文檔,核心技術是轉碼和展現,轉碼的目的是把不同文檔進行解析轉換成一套通用的數據格式,由后端實現,而展現是把文檔數據進行渲染。在這之前,文庫前端采用的HTML+CSS進行渲染,這種方式在后面的業務發展過程中遇到了阻力,比如很難實現文檔導出長圖、文檔標記、關鍵字高亮、水印、文檔內容分析、防復制等。
全文2803字,預計閱讀時間14分鍾

 

一、架構


在今年5月份時候,我們開始使用 Canvas 實現新一代閱讀器,它能夠同時支持PC、wap 和小程序,相比與老的閱讀器它具備以下優勢:

  舊閱讀器 新一代閱讀器CReader
導出長圖 無法導出,需借助服務端能力 可直接導出
文檔標記 實現成本較高 支持
復制功能 文本選擇體驗差,不好屏蔽 文本選擇體驗好,可屏蔽復制
性能 HTML元素多,大文檔性能差 少量HTML元素,只渲染可見區域內容,性能更好
開發體驗 不能本地開發、無文檔、無單測、TS類型支持弱,集成復雜,可配置性低 采用vite+TS,高效的開發體驗,豐富的文檔,集成簡單,不依賴業務方技術棧
擴展性 添加功能比較復雜 層級分工明確,可方便擴展功能


在技術選型的時候,我們選擇了 vite + ts,vite 能夠帶給我們極致的開發體驗,ts 能夠讓我們寫的代碼更有保障,業務方調用API時更便捷。整體架構分為:邏輯層:負責管理數據的加載、頁面創建、頁面渲染調度、事件分發、對外提供核心API;數據層:負責加載文檔數據,包含文檔內容、自定義字體、圖片;解析層:負責把文檔數據進行解析,產出要渲染的數據,比如文本內容、字體大小、文本位置、圖片內容、圖片位置等;渲染層:負責把解析后的內容進行渲染,目前只支持Canvas渲染,可根據業務需求進行擴展其它渲染方式,比如 HTML、SVG;應用層:使用 CReader 進行文檔渲染的業務方,內部提供了一個在線閱讀器,輔助開發。
圖片

 

二、核心技術點

2.1 文本圖片渲染機制
文檔主要由文本和圖片構成,整個文檔渲染主要圍繞這兩個進行。Canvas是瀏覽器提供的一種能力,可以通過繪制指令進行繪制,最終把要展示的內容呈現給用戶。由於它不需要通過DOM元素渲染,這就享受不到DOM本身的可交互性,比如文本選擇、DOM事件,不過對於文檔來說,屬於靜態的,對可交互性要求沒有那么高。下面對比一下前端中的各種渲染機制:
圖片
綜合各種業務場景,我們最終選擇使用Canvas,不過整個閱讀器設計考慮了支持多種渲染方式。Canvas在渲染的過程中需要有一些注意點,比如在Safari瀏覽器中,畫布的大小在移動端和PC端不能超過它的限制,通過源碼(webkit源碼)中可以看到:
圖片
而且,繪制過程中不能占用太多的內存空間,否則調用 getContext('2d') 時會返回 NULL,我們當時渲染 1000頁文檔時,內存開銷很大。最終采用了一種策略,只對可見區域的頁面進行繪制,一但某頁不可見時,立馬釋放內存空間,這一措施讓整個閱讀器的內存占用降低90%。你可能會擔心Canvas渲染會有性能問題,其實在整個測試過程中,Canvas 渲染可以通過一些手段優化,繪制性能並不會成為瓶頸。
Canvas在繪制自定義字體的時候需要確保字體被加載過,否則使用的字體將無效。而且Canvas繪制並不支持字符間距,在數據解析后需要計算每個字符最終在畫布的位置,由於用戶會調整文檔尺寸,最終的字符位置需要考慮縮放比例。Canvas在繪制圖片時需要確保圖片被加載完才能進行繪制,如果想要對Canvas導出圖片,那么要確保圖片沒有跨域問題。最終的繪制效果如下(圖中的線條是我們的調試工具,可以查看每個字符具體繪制的位置):
圖片2.2 文本選擇
在老的閱讀器中,由於DOM節點比較復雜,文本選擇的體驗非常不好,會來回跳動,如果跨頁選擇時,由於頁間會有廣告,導致把廣告內容也復制了。使用Canva渲染時,它並沒有提供文本選擇方案,需要自己實現整個文本的選擇。整個思路其實就是根據鼠標經過的坐標位置,找到對應的文本,這就需要把光標的坐標與文本的坐標對應起來。在整個閱讀器設計的過程中,有一個數據層會記錄各個節點的坐標信息。但是,在文本選擇的過程中,需要考慮多種情況,比如光標首次落在非文字區域、文本選擇時發生了跨頁、整行文本內容字體大小不一、行間距不一等。為了不影響文檔原本內容,在文檔頂部按需創建了一個 Canvas 進行文本選擇高亮狀態繪制。整體效果如下:
圖片
跨頁文本選擇
圖片

 

三、業務功能

3.1 防作弊
舊版閱讀器中文本復制功能是瀏覽器自帶的,所有的文本節點通過瀏覽器的調試工具看到具體的內容,也可以通過代碼的方式獲取文本內容。而采用Canvas渲染,所有的內容節點將被繪制到一張圖上,從而有效避免獲取文檔中的內容。
3.2 文檔轉圖
由於舊版閱讀器采用HTML的方式渲染,DOM節點比較復雜,樣式比較多,采用類似html2canvas這種庫根本不好使。我們實現文檔導出長圖采用的是無頭瀏覽器的方式,這種方式需要消耗服務端資源,而且耗時比較長,平均5-6秒。新一代閱讀器采用Canvas 渲染,Canvas天然支持導出圖片,從而能夠把文檔中的任意頁導出圖,把不同頁面拼接成長圖。
3.3 文檔標記
新版閱讀器采用Canvas渲染,做文檔標記也就是順理成章的事情,使得實現成本極低。圖形繪制可以直接借助於開源方案,比如fabric,輕松實現各種圖形的繪制,而且能夠把繪制的內容導出為 json 文件,這讓多人標記共享成為了可能。文檔標記效果:
圖片

 

 

四、小程序排版


文庫文檔排版方式有兩種,一種稱為流式,適合移動端閱讀,但是丟失了文檔原有格式;另一種稱為版式,主要用於 wap 和 PC,與原文檔結構一致。目前小程序以流式為主,版式為輔,版式直接通過 webview 加載的H5頁面,但小程序的webview中不能添加小程序的原生組件,這導致用戶看版式文檔時不能看文檔周邊的其它信息,比如文檔推薦、VIP引導、工具欄等內容,下載文檔時也只能從 webview 中跳回小程序原生頁面。以前嘗試過以iframe的方式渲染文檔,但體驗不是很好,由於種種原因這種方式就廢棄掉了。新一代閱讀器不僅可以支持PC、wap,而且能夠擴充到小程序上,我們最近做過一次嘗試,成功地把版式文檔渲染出來了,而且體驗很好。這就能夠讓版式文檔和流式文檔一樣可以嵌入到小程序原生頁面當中。效果如下:
圖片

五、最后


總得來說,文庫新一代文檔閱讀器能夠帶給用戶更好的體驗,滿足更多復雜的業務場景。在開發體驗上,使用了最新構建工具 vite,帶來極致的開發體驗;接入更輕松簡單,無論使用任意技術棧都能夠輕松接入,如果均使用默認配置,5行代碼即可接入,在以前是無法做到的;全面的單測覆蓋,為質量保駕護航。同一套代碼可同時滿足wap、pc和小程序,覆蓋文庫90%的文檔類型,隨着不斷迭代,會覆蓋文庫所有的文檔類型。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM