在工作中會碰到各種各樣效能問題,本文根據自己在工作中的實踐並且結合各方面了解到的知識形成,可能不會談到具體的實現,只描述可能的方向,包括如下:js/css載入、第三方js載入、cdn、懶載入、首屏渲染、react效能優化、webpack打包、瀏覽器快取、預載入、預解析快取可以顯著提高瀏覽器載入速度。
通常使用的快取有兩種:強快取、協商快取
瀏覽器使用快取過程如下:
瀏覽器每次髮器請求前,都會在瀏覽器快取中查詢該請求的結果和快取標識;如果找不到則髮器請求,找到通過expires
和cache-control
驗證是否命中強快取,是則直接使用,否則發起請求
若沒命中強快取,在請求的頭中會加上if-modified-since
和if-none-match
分別對應相應頭中的last-modified
和etag
,伺服器會判斷資源是否命中協商快取(資源是否被修改),沒有則返回304,瀏覽器使用本地資源
若資源被修改,重新返回新的資源,瀏覽器根據新的返回重新協商快取。
強快取需在伺服器配置expires
和cache-control
強快取會直接返回200(disk cache)或200(disk cache)
協商快取
協商快取會在請求頭中加上if-modified-since
和if-none-match
區別
etag優先順序比last-modified高
如果資源更新了,但內容沒變,last-modified會變,etag不會
last-modified是s級別的,所以在單位時間內修改多次無法檢測到
index.html可以使用協商快取、js/css可以使用強快取
在專案中會用到第三方服務,比如gtag
,可以在頁面最後載入並使用非同步載入,防止載入過慢阻塞頁面渲染,
非同步載入:async、defer
cdn即內容分發網路,將伺服器上的靜態網路分發到多台伺服器上,使用者訪問時從最近的伺服器上獲取,減少因分布、頻寬和伺服器效能的帶來的影響。
cdn好處
提高**開啟速度,速度不好,使用者容易流失
有利於google搜尋,google將**的開啟速度作為搜尋排名的乙個重要標誌,使用cdn後速度變快,使用者跳出率減少
減少宕機風險。沒有cdn時,當同一時間使用者訪問量太大,容易造成宕機;使用cdn之後減少宕機風險,提高**訪問量
減少託管成本。公司如果自己使用vps,會付出更高的成本,使用cdn可以減少成本,cdn伺服器不需要自己維護,檔案儲存在多台機器上,可以降低運維和流量成本。
cdn適用場景
網際網路
使用場景:
由於國外的客戶在訪問公司**時速度較慢,所以換成了cdn可以顯著提公升載入效率,目前國內服務也上傳至cdn網路
屬於比較大的檔案也需要使用cdn
國內的cdn服務商很多,我們目前使用七牛
在很少的情況下不會對網頁造成影響,非常多時會明顯感覺到頁面載入耗時比較長,使用者的等待時間就變長,降低使用者的體驗感。
所以在產品列表頁面使用懶載入,可以使用intersectionobserver
或者通過滾動事件監聽元素是否出現在視口。目前使用intersectionobserver來進行懶載入,具體實現可看官網文件mdn 優點
在開啟**時,會出現一段時間的空白頁面,對於spa應用來說主要由兩部分時間組成:index.html載入和渲染、js載入和執行,spa應用是在js載入執行之後才把相應路由的html渲染出來,在此之前頁面都是空白。優化主要從index.html入手。
新增首屏loading,在index.html中新增載入動畫,讓使用者知道頁面正在載入而不是卡住了。使用webpack打包時可以通過htmlwebpackplugin
注入相應的html和css,打包時用ejs渲染到首頁中。
進行ssr
伺服器端渲染,可以使用next.js來做
因為我們是2b的專案,所以採用了第一種方式。是2c專案的話,採用ssr方式比較好,ssr對頁面的seo有一定好處。
展示型元件使用purecomponet
避免沒用的渲染,purecomponent自動進行了淺比較,對於多層巢狀的資料,可以使用immutable.js
。
業務元件使用shouldcomponentupdate
,手動判斷元件是否需要渲染
列表通過map
遍歷時,需要加上key
標識資料的唯一性,key必須是唯一的資料,不推薦使用index來作為key。
class元件是通過new來生成例項來呼叫render方法的,function元件只是函式呼叫,所以多使用函式式元件。
class元件方法的繫結:
直接在dom中
在每次render的時候都會重新繫結,產生新的韓式onclick
=>
div>
使用箭頭函式
箭頭函式不會作為class的原型方法,只是作為了例項的方法,每次render也會產生新的函式handleclick = () => {}
onclick
=>
div>
建構函式方法
沒個例項都可以共享函式體,不需要額外的記憶體負擔,但是函式太多的話繫結起來比較麻煩。constructor
(props)
webpack可以通過抽離css,拆分js來實現,檔名使用[name].[chunkhash].js
css抽離
使用css-loader
壓縮css,使用mini-css-extract-plugin
把css抽離出來,使用瀏覽器進行快取
js拆分
將外掛程式與實際的業務邏輯**分離,比如react、react-dom、flux、react-intl、axios等一般不會變的分離出來,形成乙個或多個檔案,這樣每次修改**後只有業務**檔名的hash值會變,外掛程式的hash值不會變,使用者開啟頁面時只需要重新獲取變化的檔案,縮短載入時間
preload/prefetch告訴瀏覽器提前載入資源,在需要執行的地方再執行。
好處:
preload/prefetch區別:
當對同乙個資源同事使用preload、prefetch會載入兩次,帶來兩倍的網路開銷
使用preload載入跨域資源時應加上crossorigin
,避免資源不同源無法使用快取,不帶crossorigin
時請求頭沒有origin
字段。
當瀏覽器獲取資源的時候,需要先進行dns解析,才能獲取到資源。dns-prefetch
用預解析dns,當需要獲取資源時直接使用解析好的值
rel=
"dns-prefetch"
href
="xyz.com"
>
瀏覽器效能優化
1.開啟gzip壓縮 apache 使用 mod deflate 2.隱藏父元素,瀏覽器不會載入這張 parent div media max width 600px 3.用不同的 查詢告訴瀏覽器什麼螢幕尺寸載入什麼background image,瀏覽器會載入匹配 查詢和 media min wi...
瀏覽器效能優化(1)
你有遇到過瀏覽器很慢 很卡頓的情況嗎?在乙個簡單的網頁中,會占用大量的cpu 記憶體,頁面的動畫效果也不流暢,這時候你會有什麼反應?我猜想,大多數使用者會關閉這個頁面,改為訪問其他 作為乙個前端開發者,肯定不願意看到這種情況,那麼怎樣才能提高效能呢?說到這裡,先來看看網頁生成過程 網頁生成過程一般分...
瀏覽器渲染機制與效能優化
詳讀了很多文章,最終對比總結出來的瀏覽器渲染機制,並提出相應的優化原則 瀏覽器將從伺服器中獲取的html文件逐步解析,構建dom樹 在構建dom樹時,如果碰到js和css,會載入執行並阻塞html的解析,即html解析器會將控制權交給js或css解析器,當這個元素被解析完之後,將控制權重交回給htm...