【Odoo】Odoo16-性能優化提升

  • 2022 年 10 月 23 日
  • 筆記

上海序說科技,專註於基於Odoo項目實施,實現企業數智化,助力企業成長。
老韓頭的開發日常,部落格園分享(2022年前博文)

10月12日,Odoo16版本正式發布,本文將就Odoo官方在性能方面做的優化做一個總結。如果需要官方影片,可以翻閱B站,有不少朋友已經做了搬運工。

性能提升切入點

Odoo作為B/S架構的應用,終端用戶一般使用的是瀏覽器訪問。因此,對於用戶側而言,性能提升的感覺主要體現在用戶點擊後響應實現變化。如下圖
image
官方將該過程分為了

  • Web應用終端
  • 網路請求
  • 業務應用
  • Odoo主框架邏輯
  • 硬體層面

Web應用終端

在Web應用終端,其實也就是用戶側的瀏覽器。官方在JS和CSS方便都做了不同程度的優化,如下圖
image-1666048195420
BlockDOM
官方定義是一種更為底層的對於DOM對象的抽象管理庫。可以在渲染頁面DOM對象的時候以塊的形式進行,並區分了其中的靜態元素和動態元素。
關於BlockDOM的詳細說明,部落客將在後續的文章中進行介紹。
blockdom is a very fast virtual dom library. Its main selling point is that it does not represent DOM element by element, but instead block by block, where a block is an element with all its static content and some special tags to indicate dynamic content. This allows blockdom to use cloneNode(true) on blocks and speed up the diff process, since the vdom tree is much smaller.
OWL2 框架
我們知道自Odoo15開始,官方引入了新的前端框架OWL。隨著Odoo16的發布,OWL框架也進入2.x版本,其中與1.x版本還是有一些不同的,這也是為什麼部落客會寫 OWL系列教程 的原因。
image-1666049043586
如上,在Odoo15中,只有30%的前端組件使用了OWL1框架,那麼在本次發布的Odoo16版本中,除了Odoo Studio模組的部分前端程式碼依舊保留有Widget形式外,已經有99%的程式碼使用OWL 2進行了重構。
由此帶來的效果是:

  1. 縮減了30%的程式碼行數
  2. 頁面渲染速度實現了2到20倍不同程度的提升
    CSS Cleanup
    Odoo16中大幅縮減了SCSS的程式碼行數,從而減少了渲染頁面時的時間。
    image-1666220596494
    其他
  • 在Tree視圖下的,將該對象下全部的資訊的數量調整為上限10000,如下圖所示,性能提升效果還是很明顯的。
  • 減少或合併了一些RPC請求,進而提高客戶端的響應
  • 重構了討論模組並將longpoll改為了websocket(終於改了,該功能在Odoo14的時候就已經有開發者pull了,但一直沒有合併 )
    image-1666220704726

網路請求

作為BS架構的應用,用戶的每一次操作都需要與伺服器實現有效的數據交互。因此,優化的重點就放在了
image-1666221933715

  • 縮減請求包體大小
  • 合併請求數量

將分別將JS、CSS文件合併為一個文件,並去除了冗餘程式碼:

image-1666049865554
優化load_views()中邏輯,精簡欄位數據:
image-1666049985367

  • 通過NGINX等軟體代理實現大文件的下載

在啟動Odoo實例的時候,添加--x-sendfile指令,可以在用戶請求大文件的時候,響應用戶請求的worker可通過添加X-Accel-Redirect頭,實現NGINX直接將快取文件發送回用戶,減少對應用的壓力。
image-1666069654551

業務應用

業務應用方面的優化主要是體現在

  • onchange -> compute
  • 程式碼重構

image-1666089508680

onchange -> compute
image-1666089574698
在上圖中該銷售單共有多個產品行,每個訂單行的金額小計依賴於商品價格、數量、優惠等,而訂單總金額則依賴於每行的金額小計。因此,在上圖中,若我們改變了三行的優惠額度,那麼對於總價而言,也將計算三次。但是,若我們將總金額通過compute方式實現,就只需要計算一次就夠了。
如下圖所示,Compute與onchange的對比:
image-1666222937217

Odoo16在field定義的時候,還新增了precompute關鍵字,可用於替換特定場景下的default,有效減少SQL操作。
image-1666307479656

Odoo主框架邏輯

Odoo16在主框架上優化還是很明顯的,對於已有項目的遷移可能是個挑戰。正好有客戶使用的Odoo14版本,後續將遷移過程也會整理下。

  • 翻譯欄位優化
  • 片段優化
  • 索引優化
  • 視圖和菜單優化
  • Sessions

image-1666307789381

翻譯欄位優化
image-1666308113268

我們看到,在老版本的Odoo中,res.country對象在不同語種情況下的名稱是單獨定義在iir.tanslation對象中的。那麼,當我們需要非英語的國家名稱時,需要將兩張表關聯查詢才能得到目標值。
Odoo16將類似這種情況下的欄位,調整為了JSONB格式欄位,這樣就允許我們較為直接的查詢到我們的目標值。優化後在查詢和更新時都會有較為明顯的提升,唯一一個缺點是我們需要安裝一個新的語種時會慢一點,不過這也能夠理解。畢竟是新的語種需要將所涉及到的翻譯全部都更新一遍。

image-1666308441416

片段快取
在Odoo16的視圖渲染中,引入了片段快取的概念,如下圖,我們可以在視圖中通過t-cache關鍵字標識該區域是否啟用快取或者依賴於哪些對象。比如,header、footer標籤一般是所有頁面通用的,因此此處我們設置為t-cache="True"。在Section標籤中,有可能展示不同的商品資訊,此處我們配置了t-cache="products,pricelist"對象。而在購物車的位置,將需要判斷用戶是否登陸再渲染,所以此處設置為t-cache="None"

image-1666308898971

通過片段快取技術,頁面渲染的速度得到蠻大的提升。

image-1666309293681

索引優化
在Odoo16中,擴展了索引的方式,btree_not_null(並無索引null)和trigram(用於字元串搜索,ilike等場景)。
image-1666309486654

視圖和菜單
引入視圖快取的方式及優化菜單冷載入,可將視圖載入的時間提高6.5倍。
image-1666309743244

Sessions
僅存儲必要的Sessions資訊,對於訪客的Session將不再存儲。
image-1666309954816

硬體層面
這點沒什麼好說的