国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > CSS > 正文

高效的CSS選擇器編寫指南

2024-07-11 08:50:06
字體:
供稿:網(wǎng)友

高效的CSS已經(jīng)不是一個(gè)新的話題了,也不是我一個(gè)非得重拾的話題,但它卻是我在Sky公司工作之時(shí),所感興趣的,關(guān)注已久的話題。

有很多人都忘記了,或在簡單的說沒有意識到,CSS在我們手中,既能很高效,也可以變得很低能。這很容易被忘記,尤其是當(dāng)你意識到你會的太少,CSS代碼效率很低的時(shí)候。

下面的規(guī)則只真正被應(yīng)用到那些速度要求很高,有成百上千的DOM元素被繪制在頁面上的大型網(wǎng)站。但是,實(shí)踐出真理,這和你是在創(chuàng)建下一個(gè)Facebook,還是寫一個(gè)本地的展示頁面都沒有關(guān)系,多知道一點(diǎn)總是好的。

CSS選擇器:

對我們大多數(shù)人來說,CSS選擇器并不陌生。最基本的選擇器是元素選擇器(比如div),ID選擇器(比如#header)還有類選擇器(比如.tweet)。

一些的不常見的選擇器包括偽類選擇器(:hover),很多復(fù)雜的CSS3和正則選擇器,比如:first-child,class ^= “grid-”.

CSS選擇器具有高效的繼承性,引用Steve Souders的話, CSS選擇器效率從高到低的排序如下:

  1. ID選擇器 比如#header
  2. 類選擇器 比如.promo
  3. 元素選擇器 比如 div
  4. 兄弟選擇器 比如 h2 + p
  5. 子選擇器 比如 li > ul
  6. 后代選擇器 比如 ul a 7. 通用選擇器 比如 *
  7. 屬性選擇器 比如 type = “text”
  8. 偽類/偽元素選擇器 比如 a:hover

以上引用自Steve Souders的Even Faster網(wǎng)站、

我們不得不提的是,縱使ID選擇器很快、高效,但是它也僅僅如此。從Steve Souders的CSS Test我們可以看出ID選擇器和類選擇器在速度上的差異很小很小。

在Windows系統(tǒng)上的Firefox 6上,我測得了一個(gè)簡單類選擇器的(reflow figure)重繪速度為10.9ms,而ID選擇器為12.5ms,所以事實(shí)上ID比類選擇器重繪要慢一點(diǎn)點(diǎn)。

ID選擇器和類選擇器在速度上的差異基本上沒有關(guān)系。

在一個(gè)標(biāo)簽選擇器(a)的測試上顯示,它比類或ID選擇器的速度慢了很多。在一個(gè)嵌套很深的后代選擇器的測試上,顯示數(shù)據(jù)為440左右!從這里我們可以看出ID/類選擇器 和 元素/后代選擇器中間的差異較大,但是相互之間的差異較小。

注意: 這些數(shù)據(jù)可能在不同計(jì)算機(jī)和瀏覽器中間的差異較大。強(qiáng)烈地建議大家在自己的機(jī)子上測試一下。

組合選擇器

你可以有一個(gè)標(biāo)準(zhǔn)的選擇器比如 #nav,來選擇任何帶有ID為”nav”的元素,或在你可以有一個(gè)組合選擇器比如#nav a,來選擇任何在ID為’nav’的元素里面的鏈接元素

此刻,我們讀這些是從左到右的方式。我們是先找到#nav,然后從它的里面找其他元素。但是瀏覽器解析這些不是這樣的:瀏覽器解析選擇器是從右到左的方式。

在我們看來,#nav里面帶了一個(gè)a,瀏覽器卻是看到的a在#nav里面。這些細(xì)微的差異對選擇器的效率有很大的影響,同時(shí)學(xué)這些差異也是很有價(jià)值的。

如果想要知道更多瀏覽器這樣解析的原因,請看Stack Overflow上的討論

瀏覽器從最右邊的元素開始(它想要渲染的元素),然后用它的方式回溯DOM樹比從DOM樹的最高層開始選擇向下尋找,甚至可能達(dá)不到最右邊的選擇器—關(guān)鍵的選擇器要高效。

這些對CSS選擇器的效率有很大的影響。

關(guān)鍵選擇器

關(guān)鍵選擇器,正如前面討論的一樣,是一個(gè)復(fù)雜的CSS選擇器中最右邊部分。它是瀏覽器最先尋找的。

現(xiàn)在我們回到討論開始的地方,哪類選擇器是最高效的?哪個(gè)是會影響選擇器效率的關(guān)鍵選擇器;寫CSS代碼的時(shí)候,關(guān)鍵選擇器是能否高效的決定因素。 一個(gè)關(guān)鍵CSS選擇器像這樣:

#content .intro {..}

是不是高效選擇器比如類選擇器天生就高效?瀏覽器會尋找.intro的實(shí)例(可能會很多),然后沿著DOM樹向上查找,確定剛才找到的實(shí)例是否在一個(gè)帶有ID為”content”的容器里面。

但是,下面的選擇器就表現(xiàn)的不是那么好了:

#content * {..}

這個(gè)選擇器所做的是選擇所有在頁面上的單個(gè)元素(是每個(gè)單個(gè)的元素),然后去看看它們是否有一個(gè) #content 的父元素。這是一個(gè)非常不高效選擇器因?yàn)樗年P(guān)鍵選擇器執(zhí)行開銷太大了。

運(yùn)用這些知識我們就可以在分類和選擇元素的時(shí)候做出更好的選擇。

假設(shè)你有一個(gè)復(fù)雜的頁面,它相當(dāng)巨大并且在你的一個(gè)很大很大的站點(diǎn)上。在那個(gè)頁面上有成百上千甚至上萬的 a 標(biāo)簽。它還有一個(gè)小的社交鏈接區(qū)域放在一個(gè)ID為#social的Ul里面。我們假設(shè)它們是Twitter,F(xiàn)acebook,Dribbble還有 Google+的鏈接吧。在這個(gè)頁面上我們有四個(gè)社交鏈接和成百上千的其他鏈接。 下面的這個(gè)選擇器就自然的不是那么高效和合理了:

#social a {…}

這里發(fā)生的情況是瀏覽器會在定位到#social區(qū)域下的四個(gè)鏈接之前得到頁面上所有成千上萬的鏈接。我們的關(guān)鍵選擇器匹配了太多我們不感興趣的其他元素。

為了補(bǔ)救我們可以給每個(gè)在社交鏈接區(qū)域的 a 增加一個(gè)更特殊、明確的選擇器 .social-link , 但是這好像有點(diǎn)違背我們的認(rèn)知:當(dāng)我們能用組合選擇器的時(shí)候就不要放不必要的類標(biāo)示在元素上。

這就是為什么我對選擇器的性能如此感興趣的原因了:必須在web 標(biāo)準(zhǔn)最佳實(shí)踐和速度之間的保持平衡。

通常我們有:

<ul id="social">    <li><a href="#" class="twitter">Twitter</a></li>    <li><a href="#" class="facebook">Facebook</a></li>    <li><a href="#" class="dribble">Dribbble</a></li>    <li><a href="#" class="gplus">Google+</a></li></ul>

CSS:

#social a {}

我們現(xiàn)在最好有:

<ul id="social">    <li><a href="#" class="social-link twitter">Twitter</a></li>    <li><a href="#" class="social-link facebook">Facebook</a></li>    <li><a href="#" class="social-link dribble">Dribbble</a></li>    <li><a href="#" class="social-link gplus">Google+</a></li></ul>

加上CSS:

#social .social-link {}

這個(gè)新的關(guān)鍵選擇器將會匹配更少的元素,這意味著瀏覽器能夠很快的找到它們并渲染特定的樣式,然后專注于下一件事。

另外,事實(shí)上我們可以用.social-link{}更清晰的選擇,而不是過分限制它。閱讀下一部分你會原因…

簡單的重述一次,你的關(guān)鍵選擇器會決定瀏覽器的工作量,因此,我們應(yīng)該重視一下關(guān)鍵選擇器

過度限制選擇器

現(xiàn)在我們知道了什么是關(guān)鍵選擇器,還有它是大部分工作的來源,但是我們可以更樂觀一點(diǎn)。擁有一個(gè)明確的關(guān)鍵選擇器最大的好處就是你可以避免使用過度限制選擇器。一個(gè)過度限制選擇器可能像:

html body .wrapper #content a {}

這里的寫的太多了,至少3個(gè)選擇器是完全不需要的。它可以最多像這個(gè)樣子:

#content a {}

這會發(fā)生什么呢? 首先第一個(gè)意味著瀏覽器不得不尋找所有的 a 元素,然后檢查他們是否在一個(gè)ID為”content”的元素中,然后如此循環(huán)直到HTML標(biāo)簽。這樣造成了太多的我們不太想要的花費(fèi)。了解了這個(gè),我們得到一些更現(xiàn)實(shí)的例子:

#nav li a{}

變成這個(gè):

#nav a {}

我們知道如果a在li里面,它也必定在#nav里面,所有我們可以馬上把li從選擇器組中拿掉。然后,既然我們知道在頁面中只有一個(gè)ID為nav的元素,那么它依附的元素就是完全沒有關(guān)系得了,我們也可以拿掉ul

過度限制選擇器使瀏覽器工作比它實(shí)際需要的更繁重,花費(fèi)的時(shí)間更多。我們可以刪掉不必需的限制,來使我們的選擇器更簡單和高效。

這些真的需要嗎?

最短的答案是:或許不是。

最長的答案是:它取決于你正在搭建的站點(diǎn)。如果你正在為你的晉升而努力,那么就好好寫出簡單、高效的CSS代碼吧,因?yàn)槟憧赡懿粫杏X到它給你帶來的改變。 如果你正在搭建下一個(gè)每個(gè)頁面都以毫秒計(jì)算的Amazon網(wǎng)站,這樣有時(shí)速度會很快,但有時(shí)可能不是。

瀏覽器將會在解析CSS的速度上變得更好,甚至在手機(jī)端。在一個(gè)網(wǎng)站上,你不太可能會覺察到一個(gè)低效的CSS選擇器,但是….

但是

它確實(shí)發(fā)生了,瀏覽器還是不得不去做我們討論的所有工作,無論它們變得多快。即使你不需要或者甚至不想實(shí)踐任何一個(gè),但是它都是我們值得學(xué)習(xí)的知識。請記住選擇器可能會讓你付出很大代價(jià),你應(yīng)該避免盯著一個(gè)看。這意味著如果你發(fā)現(xiàn)你自己在寫像這樣的:

div:nth-of-type(3) ul:last-child li:nth-of-type(odd) *{ font-weight:bold }

這時(shí),你可能就做錯(cuò)了。

現(xiàn)在,在高效選擇器的世界我還是一個(gè)新人。所以如果我忘記了什么,或者你有需要補(bǔ)充的,請?jiān)谠u論里面留言。

更多高效選擇器

我還不能完全介紹Steve Souders的網(wǎng)站和書籍(《更快速網(wǎng)站》、《高性能網(wǎng)站》),它們是如此之好,以至于值得你花更多時(shí)間來閱讀和推薦。這個(gè)家伙只有他自己才了解自己!

High Performance Web SitesEven Faster Web Sites

 

 

英文原文:Writing efficient CSS selectors,編譯:@freestyle21 和@沈濤-WEB工程師

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 东阳市| 松江区| 中方县| 隆化县| 融水| 曲松县| 南漳县| 巨鹿县| 诸暨市| 沈丘县| 资源县| 平果县| 丰顺县| 临沭县| 石台县| 佛学| 松滋市| 乌兰浩特市| 汝州市| 扶余县| 乌鲁木齐县| 临泉县| 苍溪县| 海安县| 广安市| 茂名市| 平利县| 微博| 大荔县| 吴旗县| 岳阳县| 岱山县| 东海县| 富蕴县| 营山县| 马公市| 阜阳市| 洪洞县| 修水县| 铜陵市| 永川市|