一孩饼、拯救移動(dòng)端圖標(biāo) —— SVG
常見(jiàn)的字體方案經(jīng)歷了三種:PNG亲铡、Iconfont才写、SVG。
(一)PNG
先說(shuō)說(shuō)PNG奖蔓,是比較早的方案了赞草。PNG 屬于一種圖片格式,顏色豐富吆鹤、邊緣平滑厨疙,而且還支持透明度,所以最早被設(shè)計(jì)師作為 Icon 輸出的格式疑务,從而沿用到前端代碼中沾凄;但這種圖片icon也存在很大的缺陷:
1、尺寸問(wèn)題知允,必須關(guān)注圖片的寬高撒蟀、比例,以免導(dǎo)致失真温鸽、變形保屯。
2、請(qǐng)求數(shù)量和體積問(wèn)題嗤朴,多個(gè)圖片Icon需要通過(guò)雪碧圖等技術(shù)來(lái)規(guī)避請(qǐng)求數(shù)量,而雪碧圖的應(yīng)用還需要關(guān)心icon的定位虫溜。
3雹姊、靈活性,比較難以使用CSS3中的一些屬性衡楞,效果不佳吱雏。比如:hover敦姻、陰影、transform歧杏、filter镰惦。
(二)Iconfont
Iconfont 是將圖標(biāo)制作成為了字體,從而利用上了字體的諸多優(yōu)點(diǎn)犬绒,基本上能夠規(guī)避 PNG 大部分缺點(diǎn):
1旺入、請(qǐng)求數(shù)量,只需要考慮字體文件的加載即可凯力。
2茵瘾、矢量圖形足夠靈活,像字體能夠使用的 CSS 屬性皆可使用咐鹤,從而不必關(guān)心寬高拗秘、比例等問(wèn)題(只需設(shè)置字體大小即可)。
Iconfont 也存在一個(gè)致命問(wèn)題:Icon 是單色的祈惶,或者僅能使用 CSS3 變色雕旨。
Iconfont 背后原理是怎樣的呢?
1捧请、將Icon制作成字體文件
2凡涩、字符是如何被計(jì)算機(jī)渲染的?通過(guò) i 標(biāo)簽(比較常見(jiàn))血久,并設(shè)置 class 來(lái)添加偽元素突照,而偽元素的值為字體文件中的字形編碼,瀏覽器通過(guò)字形編碼找到字符并渲染出來(lái)的氧吐。
字符是如何被計(jì)算機(jī)渲染的讹蘑?
絕大多數(shù)的字體都包含一個(gè)或多個(gè)Charmap,它的作用是就是把一個(gè)字符從它的字符編碼印射到字形索引筑舅。
一般一個(gè)字符的渲染過(guò)程是這樣的:
1座慰、加載字體文件
2、確定要輸出的字體大小
3翠拣、輸入這個(gè)字符的編碼值
4版仔、根據(jù)字體文件中的 Charmap,把編碼值轉(zhuǎn)換成字形索引(就是這個(gè)字符對(duì)應(yīng)字體文件中的第幾個(gè)形狀)
5误墓、根據(jù)索引從字體中加載這個(gè)字形
6蛮粮、將這個(gè)字形渲染成位圖,有可能進(jìn)行加粗谜慌、傾斜等變換然想。
(三)SVG
SVG 的優(yōu)點(diǎn):
1、作為普通的頁(yè)面元素欣范,更具語(yǔ)義化
2变泄、矢量圖形令哟,足夠靈活
3、保持圖片能力妨蛹,支持彩色圖標(biāo)
4屏富、節(jié)省體積(Iconfont 往往需要一整套字體)
二、最新的布局方案——Grid & Flex
布局經(jīng)歷了幾種方案:table布局蛙卤、傳統(tǒng)布局(float狠半、position、display表窘、盒模型)典予、flex布局、grid布局乐严。
table布局已經(jīng)徹底淘汰了瘤袖,傳統(tǒng)布局PC端還有一些使用,尤其是CSS響應(yīng)式昂验;相較于最新的Grid捂敌、Flex來(lái)說(shuō),兼容性最好既琴,但是效率最低占婉,開(kāi)發(fā)起來(lái)比較麻煩。
當(dāng)下用的最多的是flex布局和grid布局甫恩。
flex布局移動(dòng)端用的特別多逆济,學(xué)習(xí)成本低,開(kāi)發(fā)效率高磺箕,兼容性也還不錯(cuò)奖慌,它依據(jù)某個(gè)軸布局,可以看做是一維布局松靡。
grid布局在水平垂直兩個(gè)方向上同時(shí)控制简僧,可以稱(chēng)之為二維布局。Grid布局非常強(qiáng)大雕欺,但概念也最多岛马,學(xué)習(xí)成本高一些,兼容性不如flex屠列。
(一)flex布局
(1)核心概念
flex 容器(Flex Container)
它是所有flex項(xiàng)的直接父元素啦逆。
我們把一個(gè)元素的display屬性值改為 flex 或者 inline-flex后,這個(gè)元素就會(huì)成為flex容器笛洛,而容器中的直接子元素就會(huì)變?yōu)?flex元素夏志。
flex容器會(huì)有一些屬性,通過(guò)它可以控制flex元素的大小撞蜂、順序盲镶、對(duì)齊以及間隔。
1蝌诡、flex-direction
flex容器最典型的特征就是擁有水平和垂直方向兩個(gè)軸溉贿,它決定了flex容器的主軸是哪個(gè)方向(與主軸相對(duì)的是交叉軸),也就是flex項(xiàng)的排列方向浦旱。
2宇色、flex-wrap
決定flex項(xiàng)是否換行,默認(rèn)是不換行的颁湖,當(dāng)容器小于flex項(xiàng)所需要的面積時(shí)宣蠕,flex項(xiàng)會(huì)等比例縮小。
3甥捺、flex-flow
上面兩個(gè)屬性的簡(jiǎn)寫(xiě)方式抢蚀。
4、justify-content
決定flex項(xiàng)目在主軸上的對(duì)齊方式镰禾。
5皿曲、align-items
決定flex項(xiàng)目在交叉軸上的對(duì)其方式。
6吴侦、align-content
控制“多條主軸”的 flex 項(xiàng)目在交叉軸的對(duì)齊屋休。所謂“多條主軸”是指存在換行。
flex 項(xiàng)(Flex Item)
它是flex容器的直接子元素备韧,也有一些屬性可以控制flex項(xiàng):
1劫樟、order
定義flex項(xiàng)在排列時(shí)的順序,數(shù)值越小優(yōu)先級(jí)越高织堂。
2叠艳、flex-grow
決定了flex項(xiàng)寬度或者高度的增長(zhǎng)系數(shù),它指定了flex容器中剩余空間的多少應(yīng)該分配給項(xiàng)目捧挺,所謂剩余的空間是指flex容器的大小減去所有flex項(xiàng)的大小加起來(lái)的大小虑绵。如果所有的兄弟項(xiàng)目都有相同的flex-grow系數(shù),那么所有的項(xiàng)目將獲得相同的剩余空間闽烙,否則將根據(jù)不同的flex-grow系數(shù)定義的比例進(jìn)行分配翅睛。
3、flex-shrink
決定了flex容器空間不足時(shí)黑竞,flex項(xiàng)目的縮小系數(shù)捕发,與flex-grow相對(duì)。
4很魂、flex-basis
決定了主軸方向上的初始大小扎酷,也就是主軸空間。
有以下幾點(diǎn)需要注意:
單獨(dú)使用 flex-basis遏匆,其實(shí)是定義了最小寬度法挨,當(dāng)內(nèi)容撐大時(shí)谁榜,flex項(xiàng)目也變大。
單獨(dú)使用width凡纳,正常使用窃植。
兩者同時(shí)使用,會(huì)采用較大的寬度荐糜,并且內(nèi)容會(huì)溢出巷怜。(不設(shè)置break-all)
5、flex
屬性2暴氏、3延塑、4的簡(jiǎn)寫(xiě)方式。
6答渔、align-self
決定了flex項(xiàng)目在交叉軸上的排列方向关带,覆蓋flex容器中設(shè)置的align-items。
(二)grid布局
(1)grid 布局的核心概念
1沼撕、網(wǎng)格容器(Grid Container)豫缨,它是所有網(wǎng)格項(xiàng)的直接父元素
2、網(wǎng)格項(xiàng)(Grid Item)端朵,它是網(wǎng)格容器的直接子元素
3好芭、網(wǎng)格線(xiàn)(Grid Line),是組成網(wǎng)格結(jié)構(gòu)的分隔線(xiàn)冲呢,分為水平方向和垂直方向
4舍败、網(wǎng)格單元(Grid cell),由網(wǎng)格線(xiàn)將網(wǎng)格容器切分而成
5敬拓、網(wǎng)格軌跡(Grid track)邻薯,可以簡(jiǎn)單理解為網(wǎng)個(gè)容器的行和列
6、網(wǎng)格區(qū)域(Grid area)乘凸,由網(wǎng)格單元組成的塊
Grid布局主要有兩種元素厕诡,即網(wǎng)格容器和網(wǎng)格項(xiàng),因此就有作用于這兩種元素上的屬性营勤。
(2)網(wǎng)格容器屬性
1灵嫌、display:grid | inline-grid
grid 中的容器元素都是塊級(jí)元素,而inline-grid中的容器元素是行內(nèi)元素葛作。
2寿羞、grid-template-columns 和 grid-template-rows
它們分別用來(lái)定義網(wǎng)格的行和列,它們的取值用來(lái)定義網(wǎng)格的大小赂蠢,而之間的間隔表示網(wǎng)格線(xiàn)绪穆,網(wǎng)格線(xiàn)可以使用中括號(hào)進(jìn)行命名。例如:grid-template-columns: [firstline] 40px [secondline] 40px [thirdline] 40px [endline]。
對(duì)于重復(fù)的取值可以用 repeat 函數(shù)簡(jiǎn)寫(xiě)玖院,例如:grid-template-columns: 40px 40px 40px等價(jià)為repeat(3, 40px)菠红。
再來(lái)看看有取值有哪些單位:
傳統(tǒng)單位,例如:px难菌、百分比途乃、auto等等
fr,這是網(wǎng)格特有的單位扔傅,表示行和列中可用空間的一等份。
3烫饼、grid-template-areas猎塞,用來(lái)定義網(wǎng)格區(qū)域。
上述網(wǎng)格容器屬性就是將網(wǎng)格分割成行列杠纵,而行列又可以組成區(qū)域荠耽。劃分好區(qū)域以后,我們就可以利用網(wǎng)格項(xiàng)屬性將區(qū)域分配給網(wǎng)格項(xiàng)比藻。
4铝量、column-gap、row-gap用來(lái)定義行列之間的間隔银亲。
5慢叨、justify-items用來(lái)定義網(wǎng)格單元的水平對(duì)齊方式。
6务蝠、align-items用來(lái)定義網(wǎng)格單元的垂直對(duì)齊方式拍谐。
7、place-items 是上述兩個(gè)屬性的簡(jiǎn)寫(xiě)方式馏段。
8轩拨、justify-content用來(lái)定義容器內(nèi)容的水平排布方式。
9院喜、align-content用來(lái)定義容器內(nèi)容的垂直排布方式亡蓉。
10、place-content是上述兩個(gè)屬性的簡(jiǎn)寫(xiě)方式喷舀。
11砍濒、grid-auto-columns為那些隱式列指明寬度。
12硫麻、grid-auto-rows為那些隱式行指明高度梯影。
13、grid-auto-flow為那些沒(méi)有分配區(qū)域的網(wǎng)格項(xiàng)指明流動(dòng)方式庶香,是按行流動(dòng)還是按列流動(dòng)甲棍。
(3)網(wǎng)格項(xiàng)屬性
1、grid-column-start、grid-column-end感猛、grid-row-start七扰、grid-row-end都是描述網(wǎng)格線(xiàn)的,通過(guò)這四個(gè)屬性可以畫(huà)出一個(gè)區(qū)域陪白,而這個(gè)區(qū)域即分配給了網(wǎng)格項(xiàng)颈走。
2、grid-column咱士、grid-row為上述四個(gè)屬性的簡(jiǎn)寫(xiě)屬性立由。
3、grid-area為上述四個(gè)屬性的進(jìn)一步簡(jiǎn)寫(xiě)形式序厉,同時(shí)其值也可以直接寫(xiě)為區(qū)域名稱(chēng)锐膜。
4、justify-self指明網(wǎng)格項(xiàng)自身的水平對(duì)齊方式弛房。
5道盏、align-self指明網(wǎng)格項(xiàng)自身的垂直對(duì)齊方式。
6文捶、place-self是上述兩個(gè)屬性的簡(jiǎn)寫(xiě)屬性荷逞。
三、優(yōu)化資源加載的順序
1粹排、Preload
<link rel="preload" href="test.jpg">
2种远、Prefetch包括資源預(yù)加載、DNS預(yù)解析顽耳、http預(yù)連接和頁(yè)面預(yù)渲染院促。
資源預(yù)加載:<link rel="prefetch" href="test.css">
DNS預(yù)解析:<link rel="dns-prefetch" >
http預(yù)連接:<link rel="prefetch" > 將建立對(duì)該域名的TCP鏈接
頁(yè)面預(yù)渲染:<link rel="prerender" > 將會(huì)預(yù)先加載鏈接文檔的所有資源
那么Prefetch和Preload有什么區(qū)別呢?
具體來(lái)講斧抱,Preload來(lái)告訴瀏覽器預(yù)先請(qǐng)求當(dāng)前頁(yè)需要的資源常拓,從而提高這些資源的請(qǐng)求優(yōu)先級(jí)。比如辉浦,對(duì)于那些本來(lái)請(qǐng)求優(yōu)先級(jí)較低的關(guān)鍵請(qǐng)求弄抬,我們可以通過(guò)設(shè)置Preload來(lái)提升這些請(qǐng)求的優(yōu)先級(jí)。
Prefetch來(lái)告訴瀏覽器用戶(hù)將來(lái)可能在其他頁(yè)面(非本頁(yè)面)可能使用到的資源宪郊,那么瀏覽器會(huì)在空閑時(shí)掂恕,就去預(yù)先加載這些資源放在http緩存內(nèi),最常見(jiàn)的dns-prefetch弛槐。比如懊亡,當(dāng)我們?cè)跒g覽A頁(yè)面,如果會(huì)通過(guò)A頁(yè)面中的鏈接跳轉(zhuǎn)到B頁(yè)面乎串,而B(niǎo)頁(yè)面中我們有些資源希望盡早提前加載店枣,那么我們就可以在A(yíng)頁(yè)面里添加這些資源Prefetch,那么當(dāng)瀏覽器空閑時(shí),就會(huì)去加載這些資源鸯两。
所以闷旧,對(duì)于那些可能在當(dāng)前頁(yè)面使用到的資源可以利用Preload,而對(duì)一些可能在將來(lái)的某些頁(yè)面中被使用的資源可以利用Prefetch钧唐。如果從加載優(yōu)先級(jí)上看忙灼,Preload會(huì)提升請(qǐng)求優(yōu)先級(jí);而Prefetch會(huì)把資源的優(yōu)先級(jí)放在最低钝侠,當(dāng)瀏覽器空閑時(shí)才去預(yù)加載该园。
資源加載優(yōu)先級(jí)可以放在首屏資源優(yōu)化中,通過(guò)首屏那一幀找出對(duì)應(yīng)的關(guān)鍵請(qǐng)求鏈帅韧,然后調(diào)整這些資源的加載優(yōu)先級(jí)可以提高首屏加載速度里初。
另外,首屏速度也可以基于關(guān)鍵請(qǐng)求鏈做文章弱匪,從Localstorage、緩存等角度著手璧亮。
四萧诫、預(yù)渲染優(yōu)化頁(yè)面首屏
大型單頁(yè)應(yīng)用的性能瓶頸:JS下載 + 解析 + 執(zhí)行
可以通過(guò) SSR 來(lái)優(yōu)化,但存在問(wèn)題:需要犧牲 TTFB 來(lái)補(bǔ)救 First Paint枝嘶,實(shí)現(xiàn)起來(lái)也更加復(fù)雜帘饶。
可以通過(guò)預(yù)渲染來(lái)解決首屏問(wèn)題,Pre-rendering 打包時(shí)提前渲染頁(yè)面群扶,沒(méi)有服務(wù)端參與及刻。
五、通過(guò) windowing 優(yōu)化大型列表的渲染
加載大的列表竞阐、大表單的每一行嚴(yán)重影響性能缴饭,Lazy loading 仍然會(huì)讓 DOM 變得很大。
可以參考 react-window 的做法骆莹,它僅僅渲染大數(shù)據(jù)中的部分?jǐn)?shù)據(jù)(僅僅填滿(mǎn)視窗)的方法颗搂,從而解決一些常見(jiàn)的問(wèn)題:
1、減少初始渲染和數(shù)據(jù)更新時(shí)的節(jié)點(diǎn)數(shù)量幕垦,從而獲得一個(gè)更好的滾動(dòng)體驗(yàn)
2丢氢、減少內(nèi)存占用,從而避免大量DOM節(jié)點(diǎn)引起的內(nèi)存泄露
六先改、使用骨架組件減少布局移動(dòng)(Layout Shift)
骨架組件(Skeleton/Placeholder)的作用:
1疚察、占位
2、提升用戶(hù)感知性能
注意:Placeholder要根據(jù)要替換的組件進(jìn)行定制仇奶,從而避免 Layout Shift貌嫡。