在互聯(lián)網(wǎng)發(fā)展的當(dāng)下,webApp 項(xiàng)目越來(lái)越大,需求越來(lái)越繁重,功能越來(lái)越大,導(dǎo)致代碼打包體積越來(lái)越大,
頁(yè)面的打開(kāi)速度,頁(yè)面的流暢度 ,用戶體驗(yàn)也是一項(xiàng)對(duì)產(chǎn)品的考核標(biāo)準(zhǔn)之一,性能優(yōu)化也是前端開(kāi)發(fā)的必要工作。
對(duì)于性能優(yōu)化我們 通過(guò)工程化、加載、代碼優(yōu)化等方面分開(kāi)講解。
性能優(yōu)化核心 就是”小“字為先
工程化
打包
資源壓縮
代碼壓縮可以減少代碼體積,節(jié)約帶寬,提高下載速度
在線壓縮工具
- 壓縮:刪除 Javascript 代碼中所有注釋、跳格符號(hào)、換行符號(hào)及無(wú)用的空格,從而壓縮 JS 文件大小。
- 混淆:經(jīng)過(guò)編碼將變量和函數(shù)原命名改為毫無(wú)意義的命名,以防止他人窺視和竊取 Javascript 源代碼。
webpack 配置壓縮
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
optimization: {
minimizer: [ // 用于配置 minimizers 和選項(xiàng)
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
}),
new OptimizeCSSAssetsPlugin({})
]
}
tree shaking
tree-shaking可以理解為通過(guò)工具"搖"我們的JS文件,將其中用不到的代碼"搖"掉,是一個(gè)性能優(yōu)化的范疇
- webpack4 通過(guò)設(shè)置mode就可以支持 tree shaking
module.exports = {
mode: 'production',
}
注:webpack自身的Tree-shaking不能分析副作用的模塊
webpack-deep-scope-plugin: 這個(gè)插件主要用于填充webpack4自身Tree-shaking的不足,通過(guò)作用域分析來(lái)消除無(wú)用的代碼 在線演示demo
webpack5 tree shaking
module.exports = {
optimization: {
usedExports: true, // 識(shí)別無(wú)用代碼
minimize: true, // 將無(wú)用代碼在打包中刪除
concatenateModules: true, // 盡可能將所有模塊合并輸出到一個(gè)函數(shù)中
}
}
-
eslint-plugin-you-dont-need-momentjs
如果你正在使用ESLint,你可以安裝一個(gè)插件來(lái)幫助你識(shí)別你代碼庫(kù)中不需要(可能不需要)Moment.js的地方。
按需加載
首屏的加載很重要,對(duì)與SPA的項(xiàng)目來(lái)說(shuō),如果是大文件,使用按需加載就十分合適。比如一個(gè)近1M的全國(guó)城市省市縣的js文件,在我首屏加載的時(shí)候并不需要引入,而是當(dāng)用戶點(diǎn)擊選項(xiàng)的時(shí)候才加載。如果不點(diǎn)擊,則不會(huì)加載。就可以縮短首屏http請(qǐng)求的數(shù)量以及時(shí)間。
代碼拆分
在互聯(lián)網(wǎng)發(fā)展的當(dāng)下,webApp 項(xiàng)目越來(lái)越大,文件體積過(guò)大是很影響性能的一項(xiàng)。特別是對(duì)于移動(dòng)端的設(shè)備而言簡(jiǎn)直是災(zāi)難。
此外對(duì)于某些只要特定環(huán)境下才需要的代碼,一開(kāi)始就加載進(jìn)來(lái)顯然也不那么合理,這就引出了按需加載的概念了。為了解決這些情況,代碼拆分就應(yīng)運(yùn)而生了。代碼拆分故名思意就是將大的文件按不同粒度拆分,以滿足解決生成文件體積過(guò)大、按需加載等需求。
webpack代碼拆分
webpack通過(guò)一下三種方式實(shí)現(xiàn)了代碼拆分方式
- 多入口分開(kāi)打包
- 去重,抽離公共模塊和第三方庫(kù)
- 動(dòng)態(tài)加載
clean-css
uncss( 去除無(wú)用的 css)Simply UnCSS your styles online!
加載優(yōu)化
關(guān)于加載優(yōu)化,我們首先需要明確幾個(gè)瀏覽器的重要性能指標(biāo),參考可參考 performance,
- TTFB(Time to First Byte): 表示瀏覽器接收第一個(gè)字節(jié)的時(shí)間
- FP(First Paint):頁(yè)面的反應(yīng),第一個(gè)像素點(diǎn)落地 background:#ddd;看的見(jiàn)
頁(yè)面在導(dǎo)航后首次呈現(xiàn)出不同于導(dǎo)航前內(nèi)容的時(shí)間點(diǎn).當(dāng)瀏覽器開(kāi)始渲染頁(yè)面,白屏觸發(fā),這時(shí)候你如果設(shè)置了背景顏色的話,就可以看到頁(yè)面出現(xiàn)了背景色 - FCP(First Contentful Paint):首次繪制頁(yè)面“主要內(nèi)容”的時(shí)間點(diǎn)。
- FMP(First Meaningful Paint):首次繪制頁(yè)面“主要內(nèi)容”的時(shí)間點(diǎn)。 有意義的繪制 (自定義的)
- DCL(DOMContentLoaded): 表示 HTML 加載完成事件, L(onLoad) 表示頁(yè)面所有資源加載完成事件
- LCP(Largest Contentful Paint):第一個(gè)繪制的最大內(nèi)容 可視區(qū)域“內(nèi)容”最大的可見(jiàn)元素開(kāi)始出現(xiàn)在頁(yè)面上的時(shí)間點(diǎn)。
- CLS(Cumulative Layout Shift): 表示用戶經(jīng)歷的意外 layout 偏移的頻率。
- TBT(Total Blocking Time): 表示從 FCP 到 TTI 之間,所有 long task 的阻塞時(shí)間之和
- TTi(Time to Interactive):頁(yè)面可交互
performance timing
performance.timing:是一系列關(guān)鍵時(shí)間點(diǎn),它包含了網(wǎng)絡(luò)、加載、解析等一系列的時(shí)間數(shù)據(jù)。
通過(guò)下圖來(lái)解析下各個(gè)關(guān)鍵時(shí)間點(diǎn)的含義如下所示:

- navigationStart 瀏覽器窗口的前一個(gè)網(wǎng)頁(yè)關(guān)閉時(shí)發(fā)生 unload 事件時(shí)的 Unix 時(shí)間戳,屬于最前的測(cè)量時(shí)間點(diǎn)
- unloadEventStart 前網(wǎng)頁(yè)與當(dāng)前網(wǎng)頁(yè)同屬一個(gè)域名時(shí),返回前一個(gè)網(wǎng)頁(yè)的 unload 事件發(fā)生時(shí)的 Unix 時(shí)間戳
- unloadEventEnd 前網(wǎng)頁(yè)與當(dāng)前網(wǎng)頁(yè)同屬一個(gè)域名時(shí),返回前一個(gè)網(wǎng)頁(yè) unload 事件的回調(diào)函數(shù)結(jié)束時(shí)的 Unix 時(shí)間戳
- redirectStart 返回第一個(gè) HTTP 跳轉(zhuǎn)開(kāi)始時(shí)的 Unix 時(shí)間戳
- redirectEnd 返回最后一個(gè) HTTP 跳轉(zhuǎn)結(jié)束時(shí)的 Unix 時(shí)間戳
- fetchStart 返回瀏覽器準(zhǔn)備使用 HTTP 請(qǐng)求讀取文檔等資源時(shí)的 Unix 時(shí)間戳,在網(wǎng)頁(yè)查詢本地緩存之前發(fā)生
- domainLookupStart 返回域名查詢開(kāi)始時(shí)的 Unix 時(shí)間戳。如果使用持久連接,或者信息是從本地緩存獲取的,則返回值等同于 fetchStart 屬性的值
- domainLookupEnd 返回域名查詢結(jié)束時(shí)的 Unix 毫秒時(shí)間戳。如果使用持久連接,或者信息是從本地緩存獲取的,則返回值等同于 fetchStart 屬性的值
- connectStart 返回 HTTP 請(qǐng)求開(kāi)始向服務(wù)器發(fā)送時(shí)的 Unix 毫秒時(shí)間戳。如果使用持久連接(persistent connection),則返回值等同于 fetchStart 屬性的值
- connectEnd 返回瀏覽器與服務(wù)器之間的連接建立時(shí)的 Unix 毫秒時(shí)間戳。如果建立的是持久連接,則返回值等同于 fetchStart 屬性的值。連接建立指的是所有握手和認(rèn)證過(guò)程全部結(jié)束
- secureConnectionStart 返回瀏覽器與服務(wù)器開(kāi)始安全鏈接的握手時(shí)的 Unix 毫秒時(shí)間戳。如果當(dāng)前網(wǎng)頁(yè)不要求安全連接,則返回 0
- requestStart 返回瀏覽器向服務(wù)器發(fā)出 HTTP 請(qǐng)求時(shí)(或開(kāi)始讀取本地緩存時(shí))的 Unix 毫秒時(shí)間戳
- responseStart 返回瀏覽器從服務(wù)器收到(或從本地緩存讀?。┑谝粋€(gè)字節(jié)時(shí)的 Unix 毫秒時(shí)間戳
- responseEnd 返回瀏覽器從服務(wù)器收到(或從本地緩存讀?。┳詈笠粋€(gè)字節(jié)時(shí)(如果在此之前 HTTP 連接已經(jīng)關(guān)閉,則返回關(guān)閉時(shí))的 Unix 毫秒時(shí)間戳
- domLoading 返回當(dāng)前網(wǎng)頁(yè) DOM 結(jié)構(gòu)開(kāi)始解析時(shí)(即 Document.readyState 屬性變?yōu)椤發(fā)oading”、相應(yīng)的 readystatechange 事件觸發(fā)時(shí))的 Unix 毫秒時(shí)間戳
- domInteractive 返回當(dāng)前網(wǎng)頁(yè) DOM 結(jié)構(gòu)結(jié)束解析、開(kāi)始加載內(nèi)嵌資源時(shí)(即 Document.readyState 屬性變?yōu)椤癷nteractive”、相應(yīng)的 readystatechange 事件觸發(fā)時(shí))的 Unix 毫秒時(shí)間戳
- domContentLoadedEventStart 返回當(dāng)前網(wǎng)頁(yè) DOMContentLoaded 事件發(fā)生時(shí)(即 DOM 結(jié)構(gòu)解析完畢、所有腳本開(kāi)始運(yùn)行時(shí))的 Unix 毫秒時(shí)間戳
- domContentLoadedEventEnd 返回當(dāng)前網(wǎng)頁(yè)所有需要執(zhí)行的腳本執(zhí)行完成時(shí)的 Unix 毫秒時(shí)間戳
- domComplete 返回當(dāng)前網(wǎng)頁(yè) DOM 結(jié)構(gòu)生成時(shí)(即 Document.readyState 屬性變?yōu)椤癱omplete”,以及相應(yīng)的 readystatechange 事件發(fā)生時(shí))的 Unix 毫秒時(shí)間戳
- loadEventStart 返回當(dāng)前網(wǎng)頁(yè) load 事件的回調(diào)函數(shù)開(kāi)始時(shí)的 Unix 毫秒時(shí)間戳。如果該事件還沒(méi)有發(fā)生,返回 0
- loadEventEnd 返回當(dāng)前網(wǎng)頁(yè) load 事件的回調(diào)函數(shù)運(yùn)行結(jié)束時(shí)的 Unix 毫秒時(shí)間戳。如果該事件還沒(méi)有發(fā)生,返回 0
一個(gè)網(wǎng)頁(yè)加載的時(shí)間周期

關(guān)鍵的指標(biāo)性能計(jì)算
- 上個(gè)頁(yè)面的到這個(gè)頁(yè)面的時(shí)長(zhǎng) fetchStartfet-navigationStart
- 重定向時(shí)常 : redirectEnd-redirectStart
- DNS 查詢耗時(shí) :domainLookupEnd - domainLookupStart
- TCP 鏈接耗時(shí) :connectEnd - connectStart
- request 請(qǐng)求耗時(shí) :responseEnd - responseStart
- 解析 dom 樹(shù)耗時(shí) : domComplete - domInteractive
- 白屏?xí)r間 :responseStart - navigationStart
- domready 時(shí)間(用戶可操作時(shí)間節(jié)點(diǎn)) :domContentLoadedEventEnd - navigationStart
- onload 時(shí)間(總下載時(shí)間) :loadEventEnd - navigationStart
優(yōu)化的時(shí)間可參考web.dev
網(wǎng)絡(luò)
QPS即每秒查詢率,是對(duì)一個(gè)特定的查詢服務(wù)器在規(guī)定時(shí)間內(nèi)所處理流量多少的衡量標(biāo)準(zhǔn)。
QPS = 并發(fā)量 / 平均響應(yīng)時(shí)間
合理計(jì)算 QPS 未雨綢繆
開(kāi)啟 cnd 加速(并行最多 5 個(gè))。節(jié)約 cookie 帶寬 節(jié)約主域名的連接數(shù),優(yōu)化頁(yè)面響應(yīng)速度
開(kāi)啟頁(yè)面懶加載
緩存靜態(tài)資源文件 localstrage
nginx:
nginx 開(kāi)啟 gzip 壓縮 etag expires 緩存
nginx 開(kāi)啟 反向代理 負(fù)載均衡
(html webpsack plugin)
preload 提前加載
prefetch 預(yù)判加載
Preconnect 預(yù)解析
DNS預(yù)解析
DNS
域名系統(tǒng)(英文:Domain Name System,縮寫:DNS)是互聯(lián)網(wǎng)的一項(xiàng)服務(wù)。它作為將域名和 IP 地址相互映射的一個(gè)分布式數(shù)據(jù)庫(kù),能夠使人更方便地訪問(wèn)互聯(lián)網(wǎng)。
dns-prefetch域名解析:從域名查詢IP的過(guò)程,這個(gè)過(guò)程一般都很快的,但也會(huì)引起延遲。一般瀏覽器會(huì)適當(dāng)?shù)膶?duì)解析結(jié)果緩存,并對(duì)頁(yè)面中出現(xiàn)的新域名進(jìn)行預(yù)解析,但并不是所有的瀏覽器都會(huì)這么做,為了幫助其它瀏覽器對(duì)某些域名進(jìn)行預(yù)解析,你可以在頁(yè)面的html標(biāo)簽中添加dns-prefetch告訴瀏覽器對(duì)指定域名預(yù)解析
典型的一次DNS解析需要耗費(fèi) 20-120 毫秒,減少DNS解析時(shí)間和次數(shù)是個(gè)很好的優(yōu)化方式
DNS解析方式
瀏覽器對(duì)網(wǎng)站第一次的域名DNS解析查找流程依次為:瀏覽器緩存——系統(tǒng)緩存——路由器緩存——ISP DNS緩存——遞歸搜索

<!--用meta信息來(lái)告知瀏覽器, 當(dāng)前頁(yè)面要做DNS預(yù)解析-->
<meta http-equiv="x-dns-prefetch-control" content="on" />
<!--在頁(yè)面header中使用link標(biāo)簽來(lái)強(qiáng)制對(duì)DNS預(yù)解析-->
<link rel="dns-prefetch" />
CDN
CDN 的全稱是 Content Delivery Network,即內(nèi)容分發(fā)網(wǎng)絡(luò)。CDN 是構(gòu)建在現(xiàn)有網(wǎng)絡(luò)基礎(chǔ)之上的智能虛擬網(wǎng)絡(luò),依靠部署在各地的邊緣服務(wù)器,通過(guò)中心平臺(tái)的負(fù)載均衡、內(nèi)容分發(fā)、調(diào)度等功能模塊,使用戶就近獲取所需內(nèi)容,降低網(wǎng)絡(luò)擁塞,提高用戶訪問(wèn)響應(yīng)速度和命中率。CDN 的關(guān)鍵技術(shù)主要有內(nèi)容存儲(chǔ)和分發(fā)技術(shù)
緩存刷新
源站內(nèi)容更新后,希望用戶可以獲取到最新資源,CDN 租戶可以通過(guò)提交刷新請(qǐng)求將 CDN 節(jié)點(diǎn)上指定的緩存內(nèi)容強(qiáng)制過(guò)期。當(dāng)用戶再次訪問(wèn)時(shí),CDN 節(jié)點(diǎn)將回源獲取已更新內(nèi)容返回給用戶并在節(jié)點(diǎn)緩存最新資源。(簡(jiǎn)單來(lái)說(shuō)就是刪除 cdn 各節(jié)點(diǎn)上的緩存,有用戶獲取文件的時(shí)候,直接回源取文件?。?/p>
緩存預(yù)熱
提交指定資源的緩存預(yù)熱請(qǐng)求后,對(duì)應(yīng)源站資源將分發(fā)到 CDN 節(jié)點(diǎn),當(dāng)用戶發(fā)起訪問(wèn)請(qǐng)求時(shí),可以直接從 CDN 節(jié)點(diǎn)獲取,有效地降低了回源率。(簡(jiǎn)單來(lái)說(shuō)就是直接從源站下發(fā)文件到 cdn 各節(jié)點(diǎn)上的緩存,有用戶獲取文件的時(shí)候就可以直接取到最新文件!)
HTTP
keep-alive
在早期的HTTP/1.0中,每次http請(qǐng)求都要?jiǎng)?chuàng)建一個(gè)連接,而創(chuàng)建連接的過(guò)程需要消耗資源和時(shí)間,為了減少資源消耗,縮短響應(yīng)時(shí)間,就需要重用連接。在后來(lái)的HTTP/1.0中以及HTTP/1.1中,引入了重用連接的機(jī)制,就是在http請(qǐng)求頭中加入Connection: keep-alive來(lái)告訴對(duì)方這個(gè)請(qǐng)求響應(yīng)完成后不要關(guān)閉,下一次咱們還用這個(gè)請(qǐng)求繼續(xù)交流。協(xié)議規(guī)定HTTP/1.0如果想要保持長(zhǎng)連接,需要在請(qǐng)求頭中加上Connection: keep-alive,而HTTP/1.1默認(rèn)是支持長(zhǎng)連接的,有沒(méi)有這個(gè)請(qǐng)求頭都行
http2.0
HTTP2.0大幅度的提高了web性能,在HTTP1.1完全語(yǔ)義兼容的基礎(chǔ)上,進(jìn)一步減少了網(wǎng)絡(luò)的延遲。實(shí)現(xiàn)低延遲高吞吐量。對(duì)于前端開(kāi)發(fā)者而言,減少了優(yōu)化工作,http2.0請(qǐng)求demo。
http2.0優(yōu)勢(shì)
- 二進(jìn)制分幀:在應(yīng)用層(HTTP/2)和傳輸層(TCP or UDP)之間增加一個(gè)二進(jìn)制分幀層,HTTP/2 會(huì)將所有傳輸?shù)男畔⒎指顬楦〉南⒑蛶╢rame),并對(duì)它們采用二進(jìn)制格式的編碼 。
- 首部壓縮:HTTP/2 使用了專門為首部壓縮而設(shè)計(jì)的 HPACK 算法,達(dá)到請(qǐng)求頭壓縮的目的。
- 多路復(fù)用:多路復(fù)用允許同時(shí)通過(guò)單一的 HTTP/2 連接發(fā)起多重的請(qǐng)求-響應(yīng)消息
- 請(qǐng)求優(yōu)先級(jí):把HTTP消息分為很多獨(dú)立幀之后,就可以通過(guò)優(yōu)化這些幀的交錯(cuò)和傳輸順序進(jìn)一步優(yōu)化性能
- 服務(wù)器推送:服務(wù)端推送是一種在客戶端請(qǐng)求之前發(fā)送數(shù)據(jù)的機(jī)制
Nginx
nginx:是一個(gè)高性能的HTTP和反向代理web服務(wù)器,同時(shí)也提供了IMAP/POP3/SMTP服務(wù)。
緩存
強(qiáng)緩存
Expires: 頭能有效的利用瀏覽器的緩存能力來(lái)改善頁(yè)面的性能,能在后續(xù)的頁(yè)面中有效避免很多不必要的Http請(qǐng)求,WEB服務(wù)器使用Expires頭來(lái)告訴Web客戶端它可以使用一個(gè)組件的當(dāng)前副本,直到指定的時(shí)間為止,Expires有一個(gè)非常大的缺陷,它使用一個(gè)固定的時(shí)間,要求服務(wù)器與客戶端的時(shí)鐘保持嚴(yán)格的同步,并且這一天到來(lái)后,服務(wù)器還得重新設(shè)定新的時(shí)間。
Cathe-Control:http1.1 引入,它使用max-age指定組件被緩存多久,從請(qǐng)求開(kāi)始在max-age時(shí)間內(nèi)瀏覽器使用緩存,之外的使用請(qǐng)求,這樣就可以消除Expires的限制,
注: Cache-Control(1.1版本) 的優(yōu)先級(jí)高于 Expires(1.0 版本)
協(xié)商緩存
etag:數(shù)據(jù)簽名,資源內(nèi)容會(huì)對(duì)應(yīng)有一個(gè)唯一的簽名(sha1),如果資源數(shù)據(jù)更改,簽名也會(huì)變。配合If-Match或者If-None-Match使用,
last-modified:上次修改時(shí)間(精確到秒),配合If-Modified-Since或If-Unmodified-Since使用,通常瀏覽器使用If-Modified-Since
瀏覽器緩存流程圖

開(kāi)啟gzip
GZIP是若干文件壓縮程序的簡(jiǎn)稱,通常指GNU計(jì)劃的實(shí)現(xiàn),此處的GZIP代表的就是GUN ZIP,這也是HTTP1.1協(xié)議定義的兩種壓縮方法中最常用的一種壓縮方法,客戶端瀏覽器大都支持這種壓縮格式。
gzip on;
gzip_static on; //靜態(tài)資源
gzip_vary on; //是否在 http header 中添加 Vary: Accept-Encoding,建議開(kāi)啟
gzip_comp_level 5; //(建議) gzip 壓縮比,1 壓縮比最小處理速度最快,9 壓縮比最大但處理最慢(傳輸快但比較消耗 cpu)
gzip_min_length 0 ; //默認(rèn)值是 0,不管頁(yè)面多大都?jí)嚎s。 建議設(shè)置成大于 1k 的字節(jié)數(shù),小于 1k 可能會(huì)越壓越大
gzip_http_version 1.1; //版本信息
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
負(fù)載均衡
upstream web_mgrsys {
server 127.0.0.1:8090 weight=10;
server 127.0.0.1:3000 weight=3;
}
proxy_pass http://web_mgrsys;
可參考 幸福拾荒者文檔
預(yù)加載
prefetch: 它的作用是告訴瀏覽器加載下一頁(yè)面可能會(huì)用到的資源,注意,是下一頁(yè)面,而不是當(dāng)前頁(yè)面。因此該方法的加載優(yōu)先級(jí)非常低,也就是說(shuō)該方式的作用是加速下一個(gè)頁(yè)面的加載速度
-
preload: 提供了一種聲明式的命令,讓瀏覽器提前加載指定資源(加載后并不執(zhí)行),需要執(zhí)行時(shí)再執(zhí)行
1、將加載和執(zhí)行分離開(kāi),不阻塞渲染和document的onload事件
2、提前加載指定資源,不再出現(xiàn)依賴的font字體隔了一段時(shí)間才刷出的情況
async & defer

藍(lán)色線代表網(wǎng)絡(luò)讀取,紅色線代表執(zhí)行時(shí)間,綠色線代表 HTML 解析。
- async:加載和渲染后續(xù)文檔元素的過(guò)程將和 script.js 的加載與執(zhí)行并行進(jìn)行(異步)
- defer:加載后續(xù)文檔元素的過(guò)程將和 script.js 的加載并行進(jìn)行(異步),但是 script.js 的執(zhí)行要在所有元素解析完成之后,DOMContentLoaded 事件觸發(fā)之前完成,并且多個(gè) defer 會(huì)按照順序進(jìn)行加載。
代碼優(yōu)化
雅虎軍規(guī)
雅虎軍規(guī):無(wú)論是在工作中,還是在面試中,web 前端性能的優(yōu)化都是很重要的,那么我們進(jìn)行優(yōu)化需要從哪些方面入手呢?可以遵循雅虎的前端優(yōu)化 34 條軍規(guī),不過(guò)現(xiàn)在已經(jīng)是 35 條了,所以可以說(shuō)是雅虎前端優(yōu)化的 35 條軍規(guī)。已經(jīng)分類,這樣對(duì)于優(yōu)化有一個(gè)比較清晰的方向。
js
js優(yōu)化方案
- 精簡(jiǎn) js 代碼 巧用數(shù)據(jù)結(jié)構(gòu)與算法
- 避免內(nèi)存泄漏,避免全局變量、閉包、降低循環(huán)
- 脫離的 dom 元素及時(shí)清理其綁定的事件
css
Reflow (重排)
當(dāng)涉及到DOM節(jié)點(diǎn)的布局屬性發(fā)生變化時(shí),就會(huì)重新計(jì)算該屬性,瀏覽器會(huì)重新描繪相應(yīng)的元素,此過(guò)程叫 回流(Reflow)
Repaint(重繪)
當(dāng)影響DOM元素可見(jiàn)性的屬性發(fā)生變化 (如 color) 時(shí), 瀏覽器會(huì)重新描繪相應(yīng)的元素, 此過(guò)程稱為 重繪(Repaint)。因此重排必然會(huì)引起重繪。

重排觸發(fā)機(jī)制
- 添加或刪除可見(jiàn)的DOM元素
- 元素位置改變
- 元素本身的尺寸發(fā)生改變
- 內(nèi)容改變
- 頁(yè)面渲染器初始化
- 瀏覽器窗口大小發(fā)生改變
重繪觸發(fā)機(jī)制
- 背景顏色樣式修改
重繪&重排優(yōu)化方式
- 對(duì)需要修改的dome,盡量使用文檔片段一次插入頁(yè)面
- 對(duì)動(dòng)畫盡量使用css3 動(dòng)畫,開(kāi)啟動(dòng)畫的GPU加速,把渲染計(jì)算交給GPU。
本文原創(chuàng)發(fā)布于慕課網(wǎng) ,轉(zhuǎn)載請(qǐng)注明出處,謝謝合作 - 將需要多次重排的元素,position屬性設(shè)為absolute或fixed,元素脫離了文檔流,它的變化不會(huì)影響到其他元素
css 優(yōu)化方案
- 降低層級(jí)復(fù)雜度 減少css層級(jí)嵌套
- 降低渲染阻塞
- 使用css3動(dòng)畫 開(kāi)啟3d加速,減少動(dòng)畫對(duì)頁(yè)面的重排重繪
- contain:layout
- 隱藏元素使用display為none,
- 將需要多次重排的元素,position屬性設(shè)為absolute或fixed,元素脫離了文檔流,它的變化不會(huì)影響到其他元素
html
- iframe 延遲加載
- 壓縮刪除注釋 html-minifier :HTMLMinifier is a highly configurable, well-tested, JavaScript-based HTML minifier.
- 降低節(jié)點(diǎn)過(guò)渡嵌套
- css javascript 盡量外鏈
font
字體優(yōu)化方式
font-display:auto
auto:默認(rèn)值。典型的瀏覽器字體加載的行為會(huì)發(fā)生,也就是使用自定義字體的文本會(huì)先被隱藏,直到字體加載結(jié)束才會(huì)顯示。著作權(quán)歸作者所有。
- block: 阻塞等字體下載完成在顯示 3s
- swap:默認(rèn)字體-后期替換
- Fallback:不顯示
- optional:移動(dòng)端 默認(rèn) 或者自定義
圖片
1.tiny 在線壓縮圖片工具
https://tinyjpg.com/
圖片 imagemin
漸進(jìn)式圖片方式:baseline jpeg 一次將圖像由左到右、由上到下順序處理。當(dāng)您的 JPEG 圖像低于 10K 時(shí),最好保存為基本 JPEG(估計(jì)有 75%的可能性會(huì)更?。?/p>

Progressive jpeg 當(dāng)圖像傳輸?shù)臅r(shí)間較長(zhǎng)時(shí),可將圖像分?jǐn)?shù)次處理,以從模糊到清晰的方式來(lái)傳送圖像(效果類似 GIF 在網(wǎng)絡(luò)上的傳輸)。

圖片優(yōu)化npm依賴包
Progressive-image
: A dead simple progressive-image module for Vanilla JavaScript and Vue.js 1.0+ & 2.0+ progressive-image-demoImageMagick: 是一套功能強(qiáng)大、穩(wěn)定而且開(kāi)源的工具集和開(kāi)發(fā)包,可以用來(lái)讀、寫和處理超過(guò) 89 種基本格式的圖片文件,包括流行的 TIFF、JPEG、GIF、 PNG、PDF 以及 PhotoCD 等格式。利用 ImageMagick,你可以根據(jù) web 應(yīng)用程序的需要?jiǎng)討B(tài)生成圖片, 還可以對(duì)一個(gè)(或一組)圖片進(jìn)行改變大小、旋轉(zhuǎn)、銳化、減色或增加特效等操作,并將操作的結(jié)果以相同格式或其它格式保存,對(duì)圖片的操作,即可以通過(guò)命令行進(jìn)行,也可以用 C/C++、Perl、Java、PHP、Python 或 Ruby 編程來(lái)完成。同時(shí) ImageMagick 提供了一個(gè)高質(zhì)量的 2D 工具包,部分支持 SVG。ImageMagic 的主要精力集中在性能,減少 bug 以及提供穩(wěn)定的 API 和 ABI 上。
jpeg-recompress:Compress JPEGs by re-encoding to the smallest JPEG quality while keeping perceived visual quality the same and by making sure huffman tables are optimized
imagemin:Minify images seamlessly