減少樣式計算的範圍和複雜度

2022-09-06 02:33:10 字數 1699 閱讀 1812

通過增加和移除元素,修改屬性,類或者聽過動畫的方式來修改dom都會導致瀏覽器重新計算元素的樣式,且在大多是情況下重新布局頁面亦或重新布局部分頁面。這個過程被叫做computed style calculation。

計算樣式的一部分是建立一系列匹配的選擇器,本質上是瀏覽器計算出什麼類,偽選擇器和id應用到指定的元素上。

第二部分包括從匹配的選擇器上使用樣式的規則且計算出元素最終擁有的樣式。在blink(chrome和opera渲染引擎)中,這些過程消耗都是基本上相等的。

大約50%的時間用於為元素計算和選擇器匹配的元素的樣式。另一部分的時間用於從匹配的樣式規則中,構建並且渲染樣式。

詳細約閱讀style invalidation in blink

在最簡單的例子中,你的元素只有乙個屬性:

.title
當你的專案越來越複雜,你的選擇器也將也來越複雜,可能如下:

.box:nth-last-child(-n+1) .title
為了知道樣式運用在**,瀏覽器會這樣詢問:「這裡有乙個元素是title類,且它的父元素剛好是乙個box類的元素的第-n+1個子元素?」

計算出這個元素將花費很長的時間,所以你可以很簡單的為上面複雜的選擇器替換成乙個類名:

.final-box-title
你可能會有類名命名問題,但是對瀏覽器而言工作簡單多了!

如果你想要指定類中的最後乙個元素,瀏覽器必須要知道整個類,還有知道類元素之間的順序,類中的每個元素是第幾個nth-last-child,這將給瀏覽器帶來巨大的工作,所以我們可以簡單的為要尋找的元素新增乙個選擇器名就可(例如新增乙個類名)。

比樣式跟新更加重要的影響效能的因素是當元素修改的時候瀏覽器的工作量。

通常而言,需計算樣式的元素的數量等於元素數量乘以選擇器個數,因為每乙個元素都需要至少都要檢查每個樣式來看看元素是否和樣式匹配。

對於舊的瀏覽器而言,如果你修改了其中的乙個元素的樣式,將會作用於整個頁面,檢查頁面上的所有元素是否預設被修改。但是現代的瀏覽器不會這樣,現代的瀏覽器只會在指定的元素上做樣式的計算。

所以,為了相容所有瀏覽器的效能,你應該減少無效元素的數量。

最簡單且最好的計量樣式損耗的方式是使用谷歌瀏覽器開發者工具中的時間軸模組(timeline):

最上面的條狀**釋了每一幀的情況,如果你看見條比最低的線,也就是60fps要低的話,這說明該幀執行時間較長。

如果你在一些互動(例如scroll)中有執行時間較長的幀,那麼你考考慮對其進行優化。

上面展示了乙個執行時間很長的樣式重新計算時間,他耗費了18ms以上,且發生在scroll事件中間,對使用者體驗影響巨大。

如果你點選時間,你將會得到乙個call stack,指示了你js**中哪一部分應該對這個樣式的修改負責。

同樣,你還可以獲得樣式修改時影響的元素個數(上面是406個),你也可以知道樣式計算耗時。

bem (block, element, modifier) 原則就是為每乙個元素命名,當你需要使用繼承機制的時候,你應該直接使用元素名,元素名的命名上可以體現繼承規則:

.list .list__list-item
如果你要元素的最後乙個子元素,你可以這樣:

.list__list-item--last-child {}
使用bem原則可以有很好的效能,並且命名上易懂,如果你使用繼承機制來選擇元素的話,注意你的損耗將會是巨大的,因為你講遍歷指定元素的父元素亦或子元素。

時間複雜度和空間複雜度計算

時間複雜度 首先要說的是,時間複雜度的計算並不是計算程式具體執行的時間,而是演算法執行語句的次數。當我們面前有多個演算法時,我們可以通過計算時間複雜度,判斷出哪乙個演算法在具體執行時花費時間最多和最少。常見的時間複雜度有 常數階o 1 對數階o log2 n 線性階o n 線性對數階o n log2...

時間複雜度和空間複雜度的計算

時間複雜度 1.一般情況下,演算法的基本操作重複執行的次數是模組n的某乙個函式f n 因此,演算法的時間複雜度記做 t n o f n 分析 隨著模組n的增大,演算法執行的時間的增長率和 f n 的增長率成正比,所以 f n 越小,演算法的時間複雜度越低,演算法的效率越高。2.在計算時間複雜度的時候...

時間複雜度和空間複雜度的計算

時間複雜度 執行乙個演算法,執行的次數和問題規模之間的函式關係,用o 表示。o 1 常數項,和問題的規模無關。時間複雜度計算規則 1.只保留最高端項 2.不要係數 空間複雜度 執行乙個演算法,需要額外的輔助空間和問題規模之間的函式關係,用o 表示。簡單來說,時間複雜度指的是執行次數,空間複雜度指的是...