CSS重構(gòu):樣式表性能調(diào)優(yōu)
css同樣需要好好寫捌肴。
序言
- 為什么要讀這本書?
其實(shí)這個(gè)問題說來話長历极,但是簡單的說。就是用團(tuán)隊(duì)年會(huì)拿的獎(jiǎng)金買的書衷佃。而且這是我讀的第一本書趟卸。
而且,這是我讀的第一本有關(guān)css的紙質(zhì)書氏义。因?yàn)樽鳛橐粋€(gè)前端锄列,css總是被忽視一個(gè)技能。隨著nodejs以及很多js框架的誕生惯悠,前端由以前的被UI兼職邻邮,現(xiàn)在獨(dú)立出來,并且開始逐步搶占后端以及native端的底盤克婶,我們?cè)絹碓蕉嗳リP(guān)注js的性能筒严,設(shè)計(jì)模式,垃圾回收機(jī)制等等情萤。
殊不知鸭蛙,CSS才是良好用戶體驗(yàn)的關(guān)鍵。
秉持這一觀點(diǎn)(僅代表個(gè)人)筋岛,我推薦買了這本書娶视。拿到手以后,薄薄的100多頁睁宰,然后興沖沖肪获。。柒傻。
- 是什么吸引我
這里我要引用書中的序言
人們常將前端技術(shù)HTML CSS 和JavaScript親切的稱為“三劍客”孝赫, 大抵說的是它們并肩而支撐起了數(shù)以億計(jì)的網(wǎng)站, 英勇红符、俠義之氣概不亞于桃園結(jié)義的劉關(guān)張青柄, 但若將網(wǎng)站比作一個(gè)少女劫映,HTML可視作她的身軀,CSS必然是伊人的著裝打扮刹前,而JavaScript則是其言談舉止泳赋。胭脂粉易得,化妝之術(shù)難學(xué)喇喉∽娼瘢……改動(dòng)一處樣式,結(jié)果頁面布局大亂拣技,修改起樣式來如履薄冰千诬,這哪里是哪里啊膏斤!樣式明明加上了徐绑,可千呼萬喚就是不生效!伺候好一個(gè)瀏覽器莫辨,別家的又亂了傲茄,這還能按時(shí)發(fā)布嗎?沮榜!
簡單的文字盘榨,寫出了前端選手們的心聲啊。
重構(gòu)的原則
- 什么是重構(gòu)
重構(gòu)是指在不改變代碼行為的前提下蟆融,重寫代碼草巡,使其更加簡潔、易于復(fù)用型酥。
在國內(nèi)的大環(huán)境里山憨,很多團(tuán)隊(duì)都急于嘗鮮,項(xiàng)目進(jìn)度飛快弥喉,需求上天入地郁竟、變化多端。重構(gòu)這個(gè)東西基本成了程序員的夢想档桃∏购ⅲ或者換一句話說,不想重構(gòu)自己代碼的程序員不是一個(gè)好程序員藻肄。
為什么要重構(gòu)呢?
顯然拒担,是因?yàn)楫?dāng)前的代碼不夠高效嘹屯,且不利于維護(hù)。我們盡量提倡做小范圍的重構(gòu)从撼,但是現(xiàn)實(shí)經(jīng)常不如人意州弟,很多基礎(chǔ)的架構(gòu)都冗余很多東西钧栖。那么問題來了。我們要重構(gòu)婆翔,就要知道什么的是良好的架構(gòu)
下面我列舉書中提到的幾點(diǎn):
- 優(yōu)秀的架構(gòu)是可預(yù)測的拯杠,就是當(dāng)其他人拿到你的代碼時(shí),可以很快理解它是做什么用的
- 優(yōu)秀的架構(gòu)可提升代碼復(fù)用性
- 優(yōu)秀的架構(gòu)可擴(kuò)展
- 優(yōu)秀的架構(gòu)可維護(hù)
如果我們重構(gòu)可以使得后來的架構(gòu)的達(dá)到以上目的啃奴,那么我們的重構(gòu)就是值得的潭陪。否則,不要輕易去重構(gòu)最蕾。
- 什么時(shí)候可以去重構(gòu)代碼
如果我們平時(shí)在修復(fù)bug依溯,或者在開發(fā)新功能時(shí),重構(gòu)代碼是最好的選擇瘟则。只有不斷的去重構(gòu)代碼黎炉,代碼的質(zhì)量才能達(dá)到卓越。
但是醋拧,現(xiàn)實(shí)是殘酷的慷嗜。很多時(shí)候,我所面臨的代碼里面有很多的依賴丹壕,重構(gòu)這些依賴就好比拆毛衣上的線洪添,拆的越多,需要重構(gòu)的部分也就越多雀费。這個(gè)時(shí)候干奢,如果時(shí)間比較緊,先把工作做完是更好的選擇盏袄。
還有忿峻,就是最好不要不要把重構(gòu)的眼光放在一些無關(guān)痛癢的編碼風(fēng)格上,不要患有“不是我寫的癥”辕羽。
在一個(gè)技術(shù)團(tuán)隊(duì)中逛尚,一個(gè)優(yōu)秀的領(lǐng)導(dǎo)能理解重構(gòu)代碼的重要性,但是未必所有人都是這樣他們可能會(huì)持有一下觀點(diǎn):
- 花時(shí)間重寫代碼刁愿,看不到功能上的變化绰寞,浪費(fèi)時(shí)間
- 這些代碼還能繼續(xù)正常工作,沒有必要修復(fù)
- 你應(yīng)該當(dāng)初就把代碼寫正確铣口。
如果有人持有以上建議滤钱,而且你對(duì)自己重構(gòu)有信心并且,不會(huì)影響項(xiàng)目進(jìn)度脑题,作者建議你去重構(gòu)件缸。在這個(gè)地方,我個(gè)人覺得還是要保持謹(jǐn)慎叔遂。確認(rèn)自己的重構(gòu)是有效的他炊,不要為了重構(gòu)而重構(gòu)争剿。因?yàn)椋怀墒斓膬?yōu)化痊末,也是一件讓人頭疼的事情蚕苇。
如何寫出更好的CSS
-
級(jí)聯(lián)
級(jí)聯(lián)是瀏覽器選擇為元素用哪一種樣式的方法。
-
選擇器的優(yōu)先級(jí)
樣式的優(yōu)先級(jí)(我暫且這么稱呼凿叠,書中用特指度來描述)決定你的哪一行css是在工作的涩笤。
-
用權(quán)重相加的方式來計(jì)算優(yōu)先級(jí)
一般而言,選擇器越特殊幔嫂,它的優(yōu)先級(jí)越高辆它。也就是選擇器指向的越準(zhǔn)確,它的優(yōu)先級(jí)就越高履恩。
通常我們用1表示標(biāo)簽名選擇器的優(yōu)先級(jí)锰茉,用10表示類選擇器的優(yōu)先級(jí),用100標(biāo)示ID選擇器的優(yōu)先級(jí)切心,如果是屬性后面加了飒筑!important那么屬性將會(huì)變?yōu)闊o窮。
舉例:
- div.test1 .span var 優(yōu)先級(jí) 1+10 +10 +1
- span#xxx .songs li 優(yōu)先級(jí)1+100 + 10 + 1
- #xxx li 優(yōu)先級(jí) 100 +1
-
通過選擇器特指度來計(jì)算優(yōu)先級(jí)
特指度是用來表示css識(shí)別元素的精確性绽昏,可以用(a, b, c, d)四個(gè)維度來表示
a 若果用style屬性來表示css樣式协屡,則a = 1 否則為0
b b為id選擇器的數(shù)量
c 類選擇器屬性選擇器,偽類選擇器的數(shù)量
d 類型選擇器和偽元素的數(shù)量
在計(jì)算特指度時(shí)全谤,左邊選擇的特指度最高肤晓,若兩個(gè)值相等,需要比較右側(cè)緊挨著的變量的值认然。如果兩個(gè)選擇器的特指度都相等补憾,那么在css文檔中排在后面的將生效。
舉例: #nav-g > ul > li > a.nav-link
- 樣式不是用style來加載的所以a = 1
- 有一個(gè)id選擇器 b = 2
- 有一個(gè)類選擇器 c = 1
- 有三個(gè)類型選擇器 d為3
最后就是卷员,除了盈匾!important之外,行內(nèi)樣式的特指度是最高的毕骡。
如果有兩個(gè)屬性都用削饵!important,則規(guī)則集排在后面的生效
-
-
如何寫好css
- 使用注釋未巫,我個(gè)人的觀點(diǎn)窿撬,注釋必須要有,但不宜過多橱赠,過多的注釋同樣會(huì)讓人產(chǎn)生誤解
- 結(jié)構(gòu)一致尤仍,比如,有的人喜歡吧規(guī)則集寫在一行里狭姨,例如li {color: #fff; font-size: 10px; ...}宰啦,不過我個(gè)人更喜歡每個(gè)規(guī)則一行,然后按照一定的次序?qū)⑺麄兣帕?/li>
- 保持選擇器的簡單
- 簡單的選擇器有利于樣式的重構(gòu)饼拍,即使改變了dom的結(jié)構(gòu)赡模,但其任然可以正常工作
- 簡單的選擇器,性能更好师抄,瀏覽器在關(guān)聯(lián)規(guī)則表的時(shí)漓柑,通常會(huì)從右邊開始匹配,使用特指度更高的選擇器使得叨吮,樣式能夠快速的匹配辆布。
- js與css的選擇器分開,js最好去操作類名達(dá)到改變樣式的目的茶鉴,除了一些特定的功能比如說隱藏锋玲。
- 要使用有意義的命名
- 命名不需要粒度太細(xì),否則就是過于模塊化涵叮,這樣的代碼顯得冗余惭蹂,且沒有達(dá)到代碼復(fù)用的效果
-
css的分類
通用樣式:瀏覽器通常會(huì)自帶一些樣式,我們需要一個(gè)通用的樣式來將這些樣式覆蓋掉割粮,以達(dá)到在不同的瀏覽器呈現(xiàn)統(tǒng)一的效果
-
基礎(chǔ)樣式 因?yàn)樵卦跊]有設(shè)置樣式的情況下會(huì)繼承父容器的樣式盾碗,有一些樣式例如
- color
- font-family
- Line-height
不需要每次都去設(shè)置它們,我們只需要定義一個(gè)基礎(chǔ)的樣式舀瓢。
- 文檔元素<head></head> <link></link><title><base><meta>這些標(biāo)簽不會(huì)顯示所以不需要樣式
- 區(qū)塊元素 <address> <article><aside><body><footer><header><nav><section>這些元素主要用來做布局用廷雅,所以要注意它們的盒模型屬性的設(shè)置
- 標(biāo)題和文本元素 <h1>-<h6> <p><pre><figure><ficaption>這些元素用來展示文本,所以要注意文本相關(guān)的屬性
- 錨點(diǎn)標(biāo)簽元素:link :visited :focus :hover :active,這些元素標(biāo)識(shí)了一些狀態(tài)可以去關(guān)注out-line等
- 文本語義元素<abbr><b><cite><code><data><dfn><em><i><kbd><s><strong><time><u>等
- 列表元素<ol>(有序)<ul>(無序)<dl>(定義列表)
- 組合元素<div><main><spsan>
- 表格
- 表單
- 多媒體
組件樣式京髓,包括組件的基本樣式以及其行為航缀,例如不同狀態(tài),動(dòng)畫等
結(jié)構(gòu)化樣式
功能樣式
瀏覽器特定樣式
通過樣式的分類朵锣,我們可以更好的去組織我們的樣式谬盐,吧同類的樣式放在一起,從而使得我們的樣式文件更加容易去維護(hù)诚些。
關(guān)于測試
這是一個(gè)永恒 的話題飞傀,下面列舉幾點(diǎn)
確定好自己的項(xiàng)目需要運(yùn)行的范圍,然后定制合適的測試環(huán)境诬烹,例如當(dāng)前項(xiàng)目可以運(yùn)行在多大屏幕上砸烦,可以在哪些瀏覽器上使用。
可以通過工具來查看绞吁,我們的css是否已經(jīng)準(zhǔn)確的掛載到dom樹上
-
視覺回歸測試
我之前以為視覺回歸測試就是傳說中“觀察法”幢痘,其實(shí)里面還是有一些學(xué)問的。
- 測試重要的點(diǎn)
- 保持測試粒度
- 在不同的瀏覽器上測試
- 使用Gemini工具測試
指定編碼規(guī)范家破,現(xiàn)在有很多工具例如eslint颜说,css-beauty等
建立模式庫购岗,有利于編碼規(guī)范,同樣可以建立對(duì)應(yīng)測試的模式庫门粪。
重構(gòu)吧
了解了上述知識(shí)后喊积,我們就可以來重構(gòu)我們的項(xiàng)目。
建立不同類型的css玄妈,將他們組織在不同的文件中
去除無用的id以及僵尸代碼乾吻。
重構(gòu)是一個(gè)持續(xù)的過程,我們無法做到一次絕對(duì)完美的重構(gòu)拟蜻,但是绎签,只要一直去做,那將會(huì)得到更好的用戶體驗(yàn)酝锅。