跳過導覽
Main illustrated image for Speeding up Symbols blog post
Sketch 內幕

加速符號:我們如何在 Sketch 67 中提升效能

深入了解我們如何在 Sketch 中建構符號,以及如何讓使用它們更加快速。

當我們發佈 Mac app 67 版時,我們非常重視它帶來的效能提升。我們的團隊在幕後努力簡化流程,讓整個應用程式感覺更加順暢和反應靈敏。請查看我們的公告文章以了解更多資訊。

現在,我們想讓您了解我們加速符號的方法。這是新系列文章的第一篇,我們將深入探討應用程式的技術層面。敬請期待後續更多文章。


我們花了很多時間在 Sketch 67 的效能上,讓 Mac app 變得更快。我們改進了許多方面,從我們如何渲染具有飽和度的背景模糊,到我們如何調整顯示更新時間以更接近螢幕的更新頻率。

我們也試圖讓使用符號的整體感覺更順暢,也有一些人詢問我們是如何做到的。雖然答案並不是涉及高深電腦科學或數學的瘋狂故事,但也不是只有一件事造成所有差異。但我們確實認為有一些有趣的事情可以分享,這些事情可能也適用於其他開發人員。

什麼構成一個符號?

當我們推出符號時,我們從一個基本基礎開始。符號由兩部分組成:一個符號主體,它就像一個畫板,包含多個圖層(例如文字圖層、群組和形狀);以及一個符號實例,它是一個常規圖層,只包含對主體的參考。每當我們需要在畫布上繪製一個實例時,我們會找到符號主體並在其位置繪製。

符號實例也可以包含覆蓋,這是一組從主體值衍生的值。文字覆蓋是最常見的。在 Sketch 67 之前,如果一個實例有覆蓋,我們會完整複製主體,用覆蓋值更新文字圖層,然後繪製該副本。

找到重點

當我們第一次發佈符號時,它們只支援文字覆蓋。從那時起,我們添加了更多類型的覆蓋——巢狀符號覆蓋、樣式覆蓋、調整大小規則、智慧佈局等等。擁有一個不斷壯大的團隊來處理這些問題,帶來了挑戰,雖然我們總是試圖記錄我們的程式碼並分享知識,但我們並不是一個蜂巢思維。我們一直有一種揮之不去的感覺,覺得我們可以做得更好。

隨著功能的發展,構建它們的基本假設可能不再成立,您在第一天建立的架構可能不再適用。但是,與其在出現問題的第一時間就重寫它,通常更有意義的是稍微擴展一下系統。畢竟,我們不可能每次創建新功能時都重寫每一行程式碼。

最終,你會遇到瓶頸,而我們在開發智慧型佈局 (Smart Layout) 時就碰到了這個問題。我們過去將符號實例 (Symbol instances) 渲染為符號主體 (Symbol masters) 的副本,但為了處理影響巢狀符號的佈局調整,我們不得不改變這種做法。現在,我們將符號渲染為分離的群組 — 符號實例會轉成一個群組,其中包含所有這些圖層的副本,並遞迴向下包含所有巢狀符號。

在推出智慧型佈局之後,我們覺得需要退一步來評估我們整體的方法。不出所料,我們發現了一些不再成立的假設,而且不可避免地,由於多位開發人員在不同的假設下工作,現在出現了衝突。例如,我們發現我們有兩個用於儲存計算後符號的快取,而且我們花費了大量的時間預先填滿其中一個快取,但在最重要的地方卻從未使用它。

調整符號

我們也決定仔細研究如何在套用覆寫、縮放、智慧型佈局等之後計算我們最終渲染的符號實例。如同我所提到的,這些使用分離的群組,而我們發現我們建立了太多(深度)物件樹的中間副本。我們設法大幅減少了這些副本。

我先前描述過我們如何複製主體來套用覆寫。雖然這對於大多數符號來說沒問題,但隨著符號變得更複雜且巢狀更深,情況就會成倍惡化。使情況更糟的是我們在模型中使用的雙樹狀結構 — 一個可變樹狀結構,讓使用者介面層可以輕鬆進行更改,並由一個無鎖的不可變模型作為後盾,我們可以安全地在執行緒之間傳遞這個模型,例如跨多個執行緒渲染畫布。

簡而言之,我們建立了許多中間副本,然後又將它們丟棄。這沒有神奇的解決方案 — 只需要找到我們從一個樹狀模型轉換到另一個樹狀模型的方法,並試圖消除它們。在任何大小適中的符號上,我們都設法使用這個方法消除了至少六個中間副本。

這也產生了各種其他的連鎖效應。例如,這表示我們可以更好地利用基於識別碼的快取。建立中間副本會導致快取未命中,這可能會導致相對昂貴的操作,例如重新計算陰影。

更少的工作,更快的速度

另一個很大的收穫是發現當符號主體更改時,我們繪製的內容太多了。在典型的 macOS 應用程式中快速繪製是透過盡可能減少繪製來實現的。這有兩個好處:

  1. 透過告知系統螢幕上已更改的最小區域,我們可以減少推送回螢幕的像素數量。
  2. 我們不需要重新繪製未更改的像素,因此您可以略過遍歷圖層、繪製路徑、陰影等的邏輯。

我們發現編輯符號主體實際上會導致整個畫布重新繪製,這與我們如何追蹤文件中更改的方式有關 — 透過計算一系列不可變樹狀結構的差異。我們將在未來的文章中討論這帶來更大的好處,但可以說這是一個值得進行的修復。

未來的藍圖

如果要從中汲取教訓,也許就是偶爾停下來研究你已有的東西是很重要的。小的效率低落很容易潛入,而且因為它們發生在程式碼庫的其他持續更改之間,所以很容易被忽略。讓 Sketch 盡可能具有回應性和可靠性是我們的首要任務,也是我們未來將繼續努力的方向。

目前,如果您尚未嘗試 Sketch 67 且您的文件中有很多符號,我希望您可以嘗試一下,看看它帶來的改變。

您可能也喜歡

免費試用 Sketch

無論您是 Sketch 新手,還是回來看看有什麼新功能,我們都能讓您在幾分鐘內設置好並準備好完成最佳工作。

免費開始使用
免費開始使用