開發與維運

僅使用CSS提高頁面渲染速度

作者 | 大漠

image.png
用戶在訪問一個Web網站(頁面)或應用時,總是希望它的加載速度快,功能流暢。如果過於慢,用戶就很有可能失去耐心而離開你的Web網站或應用。作為開發人員,給自己應用提供更快的訪問速度,提供很好的用戶體驗是必備的基礎技能,而且Web開發者在開發中也可以做很多事情來改善用戶體驗。那我們今天就來和大家聊聊,在CSS方面有哪些技巧可以幫助我們來提高Web頁面的渲染速度。

內容可見性(content-visibility)

一般來說,大多數Web應用都有複雜的UI元素,而且有的內容會在設備可視區域之外(內容超出了用戶瀏覽器可視區域),比如下圖中紅色區域就在手機設備屏幕可視區域之外:
image.png
在這種場合下,我們可以使用CSS的content-visibility來跳過屏幕外的內容渲染。也就是說,如果你有大量的離屏內容(Off-screen Content),這將會大幅減少頁面渲染時間。

這個功能是CSS新增的特性,隸屬於 W3C 的 CSS Containment Module Level 2 模塊。也是對提高渲染性能影響最大的功能之一。content-visibility可以接受visibleautohidden三個屬性值,但我們可以在一個元素上使用content-visibility:auto來直接的提升頁面的渲染性能。

假設我們有一個像下面的頁面,整個頁面有個卡片列表,大約有375張,大約在屏幕可視區域能顯示12張卡片。正如下圖所示,渲染這個頁面瀏覽器用時大約1037ms
image.png

你可以給所有卡片添加content-visibility

.card {
    content-visibility: auto;
}

所有卡片加入content-visibility樣式之後,頁面的渲染時間下降到150ms,差不多提高了六倍的渲染性能:
image.png
正如你所看到的,content-visibility非常強大,提高頁面渲染非常有用。換然話說,有了CSS的content-visibility屬性,影響瀏覽器的渲染過程就變得更加容易。本質上,這個屬性 改變了一個元素的可見性,並管理其渲染狀態。

content-visibility有點類似於CSS的displayvisibility屬性,然而,content-visibility的操作方式與這些屬性不同。

content-visibility的關鍵能力是,它允許我們推遲我們選擇的HTML元素渲染。默認情況之下,瀏覽器會渲染DOM樹內所有可以被用戶查看的元素。用戶可以看到視窗可視區域中所有元素,並通過滾動查看頁面內其他元素。一次渲染所有的元素(包括視窗可視區域之外不可見的HTML元素)可以讓瀏覽器正確計算頁面的尺寸,同時保持整個頁面的佈局和滾動條的一致性。

如果瀏覽器不渲染頁面內的一些元素,滾動將是一場噩夢,因為無法正確計算頁面高度。這是因為,content-visibility會將分配給它的元素的高度(height)視為0,瀏覽器在渲染之前會將這個元素的高度變為0,從而使我們的頁面高度和滾動變得混亂。但如果已經為元素或其子元素顯式設置了高度,那這種行為就會被覆蓋。如果你的元素中沒顯式設置高度,並且因為顯式設置height可能會帶來一定的副作用而沒設置,那麼我們可以使用contain-intrinsic-size來確保元素的正確渲染,同時也保留延遲渲染的好處。

.card {
    content-visibility: auto;
    contain-intrinsic-size: 200px;
}

這也意味著它將像有一個“固有尺寸”(Intrinsic-size)的單一子元素一樣佈局,確保你沒設置尺寸的div(示例中的.card)仍然佔據空間。contain-intrinsic-size作為一個佔位符尺寸來替代渲染內容。

雖然contain-intrinsic-size能讓元素有一個佔位空間,但如果有大量的元素都設置了content-visibility: auto,滾動條仍然會有較小的問題。

content-visibility提供的另外兩個值visiblehidden可以讓我們實現像元素的顯式和隱藏,類似於displaynone和非none值的切換:
image.png
在這種情況下,content-visibility可以提高頻繁顯示或隱藏的元素的渲染性能,例如模態框的顯示和隱藏。`content-visibility可以提供這種性能提升,這要歸功於其隱藏值(hidden`)的功能與其他值的不同:

  • display: none:隱藏元素並破壞其渲染狀態。這意味著取消隱藏元素與渲染具有相同內容的新元素一樣昂貴
  • visibility: hidden:隱藏元素並保持其渲染狀態。這並不能真正從文檔中刪除該元素,因為它(及其子樹)仍佔據頁面上的幾何空間,並且仍然可以單擊。它也可以在需要時隨時更新渲染狀態,即使隱藏也是如此
  • content-visibility: hidden:隱藏元素並保留其渲染狀態。這意味著該元素隱藏時行為和display: none一樣,但再次顯示它的成本要低得多

content-visibility屬性的擴展閱讀:

  • content-visibility: the new CSS property that boosts your rendering performance

`- https://web.dev/content-visibility/

  • More on content-visibility

`- https://css-tricks.com/more-on-content-visibility/

合理使用will-change

CSS渲染器(CSS Renderer)在渲染CSS樣式之前需要一個準備過程,因為有些CSS屬性需要CSS渲染器事先做很多準備才能實現渲染。這就很容易導致頁面出現卡頓,給用戶帶來不好的體驗。

比如Web上的動效,通常情況之下,Web動畫(在動的元素)是和其他元素一起定期渲染的,以往在動畫開發時,會使用CSS的3D變換(transform中的translate3d()translateZ())來開啟GPU加速,讓動畫變得更流暢,但這樣做是一種黑魔法,會將元素和它的上下文提到另一個“層”,獨立於其他元素被渲染。可這種將元素提取到一個新層,相對來說代價也是昂貴的,這可能會使transform動畫延遲幾百毫秒。

不過,現在我可以不使用transform這樣的Hack手段來開啟GPU加速,可以直接使用CSS的will-change屬性,該屬性可以表明元素將修改特定的屬性,讓瀏覽器事先進行必要的優化。也就是說,will-change是一個UA提示,它不會對你使用它的元素產生任何樣式上的影響。但值得注意的是,如果創建了新的層疊上下文,它可以產生外觀效果。

比如下面這樣的一個動畫示例:

<!-- HTML -->
<div class="animate"></div>

/* CSS */
.animate {
    will-change: opacity
}

瀏覽器渲染上面的代碼時,瀏覽器將為該元素創建一個單獨的層。之後,它將該元素的渲染與其他優化一起委託給GPU,即,瀏覽器會識別will-change屬性,並優化未來與不透明相關的變化。這將使動畫變得更加流暢,因為GPU加速接管了動畫的渲染。

根據 @Maximillian Laumeister 所做的性能基準,可以看到,他通過這種單行變化獲得了超過120FPS的渲染速度,和最初的渲染速度(大約50FPS)相比,提高70FPS左右。

image.png
will-change的使用並不複雜,它能接受的值有:

  • auto:默認值,瀏覽器會根據具體情況,自行進行優化
  • scroll-position:表示開發者將要改變元素的滾動位置,比如瀏覽器通常僅渲染可滾動元素“滾動窗口”中的內容。而某些內容超過該窗口(不在瀏覽器的可視區域內)。如果will-change顯式設置了該值,將擴展渲染“滾動窗口”周圍的內容,從而順利地進行更長,更快的滾動(讓元素的滾動更流暢)
  • content:表示開發者將要改變元素的內容,比如瀏覽器常將大部分不經常改變的元素緩存下來。但如果一個元素的內容不斷髮生改變,那麼產生和維護這個緩存就是在浪費時間。如果will-change顯式設置了該值,可以減少瀏覽器對元素的緩存,或者完全避免緩存。變為從始至終都重新渲染元素。使用該值時需要儘量在文檔樹最末尾上使用,因為該值會被應用到它所聲明元素的子節點,要是在文檔樹較高的節點上使用的話,可能會對頁面性能造成較大的影響
  • <custom-ident>:表示開發者將要改變的元素屬性。如果給定的值是縮寫,則默認被擴展全,比如,will-change設置的值是padding,那麼會補全所有padding的屬性,如 will-change: padding-top, padding-right, padding-bottom, padding-left;

詳細的使用,請參閱:

雖然說will-change能提高性能,但這個屬性應該被認為是最後的手段,它不是為了過早的優化。只有消退你必須處理性能問題時,你才應該使用它。如果你濫用的話,反而會降低Web的性能。比如:

使用will-change表示該元素在未來會發生變化。

因此,如果你試圖將will-change和動畫同時使用,它將不會給你帶來優化。因此,建議在父元素上使用will-change,在子元素上使用動畫。

.animate-element-parent {
    will-change: opacity;
}

.animate-element {
    transition: opacity .2s linear
}

不要使用非動畫元素。

當你在一個元素上使用will-change時,瀏覽器會嘗試通過將元素移動到一個新的圖層並將轉換工作交互GPU來優化它。如果你沒有任何要轉換的內容,則會導致資源浪費。

除此之外,要用好will-change也不是件易事,MDN在這方面做出了相應的描述:

  • 不要將 will-change 應用到太多元素上:瀏覽器已經盡力嘗試去優化一切可以優化的東西了。有一些更強力的優化,如果與 will-change 結合在一起的話,有可能會消耗很多機器資源,如果過度使用的話,可能導致頁面響應緩慢或者消耗非常多的資源。比如 *{will-change: transform, opacity;}
  • 有節制地使用:通常,當元素恢復到初始狀態時,瀏覽器會丟棄掉之前做的優化工作。但是如果直接在樣式表中顯式聲明瞭 will-change 屬性,則表示目標元素可能會經常變化,瀏覽器會將優化工作保存得比之前更久。所以最佳實踐是當元素變化之前和之後通過腳本來切換 will-change 的值
  • 不要過早應用 will-change 優化:如果你的頁面在性能方面沒什麼問題,則不要添加 will-change 屬性來榨取一丁點的速度。will-change 的設計初衷是作為最後的優化手段,用來嘗試解決現有的性能問題。它不應該被用來預防性能問題。過度使用 will-change 會導致大量的內存佔用,並會導致更復雜的渲染過程,因為瀏覽器會試圖準備可能存在的變化過程。這會導致更嚴重的性能問題。
  • 給它足夠的工作時間:這個屬性是用來讓頁面開發者告知瀏覽器哪些屬性可能會變化的。然後瀏覽器可以選擇在變化發生前提前去做一些優化工作。所以給瀏覽器一點時間去真正做這些優化工作是非常重要的。使用時需要嘗試去找到一些方法提前一定時間獲知元素可能發生的變化,然後為它加上 will-change 屬性。

最後需要注意的是,建議在完成所有動畫後,將元素的will-change刪除。下面這個示例展示如何使用腳本正確地應用 will-change 屬性的示例,在大部分的場景中,你都應該這樣做。

var el = document.getElementById('element');

// 當鼠標移動到該元素上時給該元素設置 will-change 屬性
el.addEventListener('mouseenter', hintBrowser);
// 當 CSS 動畫結束後清除 will-change 屬性
el.addEventListener('animationEnd', removeHint);

function hintBrowser() {
    // 填寫上那些你知道的,會在 CSS 動畫中發生改變的 CSS 屬性名們
    this.style.willChange = 'transform, opacity';
}

function removeHint() {
    this.style.willChange = 'auto';
}

在實際使用will-change可以記作以下幾個規則,即 五可做,三不可做

  • 在樣式表中少用will-change
  • will-change足夠的時間令其發揮該有的作用
  • 使用<custom-ident>來針對超特定的變化(如,left, opacity等)
  • 如果需要的話,可以JavaScript中使用它(添加和刪除)
  • 修改完成後,刪除will-change
  • 不要同時聲明太多的屬性
  • 不要應用在太多元素上
  • 不要把資源浪費在已停止變化的元素上

讓元素及其內容儘可能獨立於文檔樹的其餘部分(contain)

W3C的CSS Containment Module Level 2除了提供前面介紹的content-visibility屬性之外,還有另一個屬性contain。該屬性允許我們指定特定的DOM元素和它的子元素,讓它們能夠獨立於整個DOM樹結構之外。目的是能夠讓瀏覽器有能力只對部分元素進行重繪、重排,而不必每次針對整個頁面。即,允許瀏覽器針對DOM的有限區域而不是整個頁面重新計算佈局,樣式,繪畫,大小或它們的任意組合。

在實際使用的時候,我們可以通過contain設置下面五個值中的某一個來規定元素以何種方式獨立於文檔樹:

  • layout :該值表示元素的內部佈局不受外部的任何影響,同時該元素以及其內容也不會影響以上級
  • paint :該值表示元素的子級不能在該元素的範圍外顯示,該元素不會有任何內容溢出(或者即使溢出了,也不會被顯示)
  • size :該值表示元素盒子的大小是獨立於其內容,也就是說在計算該元素盒子大小的時候是會忽略其子元素
  • content :該值是contain: layout paint的簡寫
  • strict :該值是contain: layout paint size的簡寫

在上述這幾個值中,sizelayoutpaint可以單獨使用,也可以相互組合使用;另外contentstrict是組合值,即contentlayout paint的組合,strictlayout paint size的組合。

containsizelayoutpaint提供了不同的方式來影響瀏覽器渲染計算:

  • size:告訴瀏覽器,當其內容發生變化時,該容器不應導致頁面上的位置移動
  • layout:告訴瀏覽器,容器的後代不應該導致其容器外元素的佈局改變,反之亦然
  • paint:告訴瀏覽器,容器的內容將永遠不會繪製超出容器的尺寸,如果容器是模糊的,那麼就根本不會繪製內容

@Manuel Rego Casasnovas提供了一個示例,向大家闡述和演示了contain是如何提高Web頁面渲染性能。這個示例中,有10000個像下面這樣的DOM元素:

<div class="item">
    <div>Lorem ipsum...</div>
</div>

使用JavaScript的textContent這個API來動態更改div.item > div的內容:

const NUM_ITEMS = 10000;
const NUM_REPETITIONS = 10;

function log(text) {
    let log = document.getElementById("log");
    log.textContent += text;
}

function changeTargetContent() {
    log("Change \"targetInner\" content...");

    // Force layout.
    document.body.offsetLeft;

    let start = window.performance.now();

    let targetInner = document.getElementById("targetInner");
    targetInner.textContent = targetInner.textContent == "Hello World!" ? "BYE" : "Hello World!";

    // Force layout.
    document.body.offsetLeft;

    let end = window.performance.now();
    let time = window.performance.now() - start;
    log(" Time (ms): " + time + "\n");
    return time;
}

function setup() {
    for (let i = 0; i < NUM_ITEMS; i++) {
        let item = document.createElement("div");
        item.classList.add("item");

        let inner = document.createElement("div");
        inner.style.backgroundColor = "#" + Math.random().toString(16).slice(-6);
        inner.textContent = "Lorem ipsum...";
        item.appendChild(inner);

        wrapper.appendChild(item);
    }
}

如果不使用contain,即使更改是在單個元素上,瀏覽器在佈局上的渲染也會花費大量的時間,因為它會遍歷整個DOM樹(在本例中,DOM樹很大,因為它有10000個DOM元素):
image.png
在本例中,div的大小是固定的,我們在內部div中更改的內容不會溢出它。因此,我們可以將contain: strict應用到項目上,這樣當項目內部發生變化時,瀏覽器就不需要訪問其他節點,它可以停止檢查該元素上的內容,並避免到外部去。
image.png
儘管這個例子中的每一項都很簡單,但通過使用contain,Web性能得到很大的改變,從~4ms降到了~0.04ms,這是一個巨大的差異。想象一下,如果DOM樹具有非常複雜的結構和內容,但只修改了頁面的一小部分,如果可以將其與頁面的其他部分隔離開來,那麼將會發生什麼情況呢?

有關於contain的更多內容:

使用font-display解決由於字體造成的佈局偏移(FOUT)

在Web開發的過程中,難免會使用@font-face技術引用一些特殊字體(系統沒有的字體),同時也可能會配合變量字體特性,使用更具個性化的字體。

使用@font-face加載字體策略大概如下圖所示:
image.png
上圖來自於@zachleat的《A COMPREHENSIVE GUIDE TO FONT LOADING STRATEGIES》一文。

Web中使用非系統字體(@font-face規則引入的字體)時,瀏覽器可能沒有及時得到Web字體,就會讓它用後備系統字體渲染,然後優化我們的字體。這個時候很容易引起未編排(Unstyled)的文本引起閃爍,整個排版本佈局也看上去會偏移一下(FOUT)。

幸運的是,根據@font-face規則,font-display屬性定義了瀏覽器如何加載和顯示字體文件,允許文本在字體加載或加載失敗時顯示回退字體。可以通過依靠折中無樣式文本閃現使文本可見替代白屏來提高性能。

CSS的font-display屬性有五個不同的值:

  • auto:默認值。典型的瀏覽器字體加載的行為會發生,也就是使用自定義字體的文本會先被隱藏,直到字體加載結束才會顯示。即字體展示策略與瀏覽器一致,當前,大多數瀏覽器的默認策略類似block
  • block:給予字體一個較短的阻塞時間(大多數情況下推薦使用 3s)和無限大的交換時間。換言之,如果字體未加載完成,瀏覽器將首先繪製“隱形”文本;一旦字體加載完成,立即切換字體。為此,瀏覽器將創建一個匿名字體,其類型與所選字體相似,但所有字形都不含“墨水”。使用特定字體渲染文本之後頁面方才可用,只有這種情況下才應該使用 block
  • swap:使用 swap,則阻塞階段時間為 0,交換階段時間無限大。也就是說,如果字體沒有完成加載,瀏覽器會立即繪製文字,一旦字體加載成功,立即切換字體。與 block 類似,如果使用特定字體渲染文本對頁面很重要,且使用其他字體渲染仍將顯示正確的信息,才應使用 swap
  • fallback:這個可以說是autoswap的一種折中方式。需要使用自定義字體渲染的文本會在較短的時間不可見,如果自定義字體還沒有加載結束,那麼就先加載無樣式的文本。一旦自定義字體加載結束,那麼文本就會被正確賦予樣式。使用 fallback時,阻塞階段時間將非常小(多數情況下推薦小於 100ms),交換階段也比較短(多數情況下建議使用 3s)。換言之,如果字體沒有加載,則首先會使用後備字體渲染。一旦加載成功,就會切換字體。但如果等待時間過久,則頁面將一直使用後備字體。如果希望用戶儘快開始閱讀,而且不因新字體的載入導致文本樣式發生變動而干擾用戶體驗,fallback 是一個很好的選擇。
  • optional:效果和fallback幾乎一樣,都是先在極短的時間內文本不可見,然後再加載無樣式的文本。不過optional選項可以讓瀏覽器自由決定是否使用自定義字體,而這個決定很大程度上取決於瀏覽器的連接速度。如果速度很慢,那你的自定義字體可能就不會被使用。使用 optional 時,阻塞階段時間會非常小(多數情況下建議低於 100ms),交換階段時間為 0

image.png
下面是使用swap值的一個例子:

@font-face {
    font-family: "Open Sans Regular";
    font-weight: 400;
    font-style: normal;
    src: url("fonts/OpenSans-Regular-BasicLatin.woff2") format("woff2");
    font-display: swap;
}

在這個例子裡我們通過只使用WOFF2文件來縮寫字體。另外我們使用了swap作為font-display的值,頁面的加載情況將如下圖所示:
image.png

注意,font-display一般放在@font-face規則中使用。

有關於字體加載和font-display更多的介紹,可以閱讀:

scroll-behavior讓滾動更流暢

早前在滾動的特性和改變用戶體驗的滾動新特性中向大家介紹了幾個可以用來改變用戶體驗的滾動特性,比如滾動捕捉、overscroll-behaviorscroll-behavior

scroll-behavior是CSSOM View Module提供的一個新特性,可以輕易的幫助我們實現絲滑般的滾動效果。該屬性可以為一個滾動框指定滾動行為,其他任何的滾動,例如那些由於用戶行為而產生的滾動,不受這個屬性的影響。

scroll-behavior接受兩個值:

  • auto :滾動框立即滾動
  • smooth :滾動框通過一個用戶代理定義的時間段使用定義的時間函數來實現平穩的滾動,用戶代理平臺應遵循約定,如果有的話

除此之外,其還有三個全局的值:inheritinitialunset

使用起來很簡單,只需要這個元素上使用scroll-behavior:smooth。因此,很多時候為了讓頁面滾動更平滑,建議在html中直接這樣設置一個樣式:

html {
    scroll-behavior:smooth;
}

口說無憑,來看個效果對比,你會有更好的感覺:

640.gif

有關於scroll-behavior屬性更多的介紹可以再花點時間閱讀下面這些文章:

  • CSSOM View Module:scroll-behavior
  • CSS-Tricks: scroll-behavior
  • Native Smooth Scroll behavior
  • PAGE SCROLLING IN VANILLA JAVASCRIPT
  • smooth scroll behavior polyfill

開啟GPU渲染動畫

瀏覽器針對處理CSS動畫和不會很好地觸發重排(因此也導致繪)的動畫屬性進行了優化。為了提高性能,可以將被動畫化的節點從主線程移到GPU上。將導致合成的屬性包括 3D transforms (transform: translateZ(), rotate3d(),等),animatingtransformopacity, position: fixedwill-change,和 filter。一些元素,例如 <video>, <canvas><iframe>,也位於各自的圖層上。將元素提升為圖層(也稱為合成)時,動畫轉換屬性將在GPU中完成,從而改善性能,尤其是在移動設備上。

減少渲染阻止時間

今天,許多Web應用必須滿足多種形式的需求,包括PC、平板電腦和手機等。為了完成這種響應式的特性,我們必須根據媒體尺寸編寫新的樣式。當涉及頁面渲染時,它無法啟動渲染階段,直到 CSS對象模型(CSSOM)已準備就緒。根據你的Web應用,你可能會有一個大的樣式表來滿足所有設備的形式因素。

但是,假設我們根據表單因素將其拆分為多個樣式表。在這種情況下,我們可以只讓主CSS文件阻塞關鍵路徑,並以高優先級下載它,而讓其他樣式表以低優先級方式下載。

<link rel="stylesheet" href="styles.css">

image.png
將其分解為多個樣式表後:

<!-- style.css contains only the minimal styles needed for the page rendering -->
<link rel="stylesheet" href="styles.css" media="all" />

<!-- Following stylesheets have only the styles necessary for the form factor -->
<link rel="stylesheet" href="sm.css" media="(min-width: 20em)" />
<link rel="stylesheet" href="md.css" media="(min-width: 64em)" />
<link rel="stylesheet" href="lg.css" media="(min-width: 90em)" />
<link rel="stylesheet" href="ex.css" media="(min-width: 120em)" />
<link rel="stylesheet" href="print.css" media="print" />

image.png
默認情況下,瀏覽器假設每個指定的樣式表都是阻塞渲染的。通過添加 media屬性附加媒體查詢,告訴瀏覽器何時應用樣式表。當瀏覽器看到一個它知道只會用於特定場景的樣式表時,它仍會下載樣式,但不會阻塞渲染。通過將 CSS 分成多個文件,主要的 阻塞渲染 文件(本例中為 styles.css)的大小變得更小,從而減少了渲染被阻塞的時間。

避免@import包含多個樣式表

通過 @import,我們可以在另一個樣式表中包含一個樣式表。當我們在處理一個大型項目時,使用 @import 可以使代碼更加簡潔。

關於 @import 的關鍵事實是,它是一個阻塞調用,因為它必須通過網絡請求來獲取文件,解析文件,並將其包含在樣式表中。如果我們在樣式表中嵌套了 @import,就會妨礙渲染性能。

/* style.css */
@import url("windows.css");

/* windows.css */
@import url("componenets.css");

image.png
與使用 @import 相比,我們可以通過多個 link 來實現同樣的功能,但性能要好得多,因為它允許我們並行加載樣式表。
image.png

注意動態修改自定義屬性方式

CSS自定義屬性又名CSS變量,該特性已經是非常成熟的特性了,可以在Web的開發中大膽的使用該特性:

:root { --color: red; }

button {
    color: var(--color);
}

義屬性是個全局的自定義屬性(全局變量),可以被所有嵌套的子元素繼承。就上例而言,--color屬性允許任何button樣式將其作為變量使用。

熟悉CSS自定義屬性的同學都知道,可以使用style.setProperty來重新設置已註冊好的自定義屬性的值。但在修改根自定義屬性時,需要注意,因為它會影響Web的性能。早在2017年@Lisi Linhart 在《 Performance of CSS Variables》中闡述過。

  • 在使用CSS變量時,我們總是要注意我們的變量是在哪個範圍內定義的,如果改變它,將影響許多子代,從而產生大量的樣式重新計算。
  • 結合CSS變量使用calc()是一個很好的方法,可以獲得更多的靈活性,限制我們需要定義的變量數量。在不同的瀏覽器中測試calc()與CSS變量的結合,並沒有發現任何大的性能問題。然而在一些瀏覽器中對一些單位的支持還是有限的,比如degms,所以我們必須記住這一點。
  • 如果我們比較一下在JavaScript中通過內聯樣式設置變量與setProperty方法的性能標誌,瀏覽器之間有一些明顯的差異。在Safari中通過內聯樣式設置屬性的速度非常快,而在Firefox中則非常慢,所以使用setProperty設置變量是首選

有關於這方面的具體細節就不在這闡述了,如果你對這方面感興趣的話,可以閱讀下面這幾篇文章:

小結

可能很多人會說,5G已到來,終端設備性能越來越好,網絡環境也越來越強,Web性能已不是問題了,但事實上在Web開發過程中總是難免碰到性能是的問題。而且我們為用戶提供更流暢的體驗也是我們必備技術之一。時至今日,優化Web性能的方式和手段很多,但在開發時注重每個細節,可以讓我們把性能做得更好。正如文章中提到這些。

除了文章提到的這幾個點,還有一些其他的方法可以使用CSS來提高網頁的性能。當然,文章中提到的一些特性還沒有得到所有瀏覽器支持,比如content-visibilitycontain等,但在未來它們肯定能讓頁面渲染帶來更快的渲染。另外,文章中提到的一些技巧並沒有深入闡述,比如CSS的引用方式,CSS的阻塞等。如果你對這方面感興趣的話,可以繼續觀注後續的相關更新;如果你在這方面更好的建議或經驗,歡迎與我們分享。


image.png

Leave a Reply

Your email address will not be published. Required fields are marked *