Babel能夠將es6中的高級語法轉化成es5中的低級語法,須要安裝node
@babel/cli 用來解析corees6
@babel/core算法
@babel/preset-env 將es6-àes5瀏覽器
壓縮緩存
在項目優化中有兩個比較重要的頭,緩存和壓縮bash
首先客戶端要支持壓縮:Accept-Encodeing:gzip deflate br服務器
服務器要判斷一下瀏覽器是否支持壓縮,支持的是那種壓縮babel
let encoding=req.headers[‘accept-encoding’]網絡
if(eccoding){優化
用的是正則,判斷是否有gzip格式
if(encoding.match(/gzip/)){
壓縮以前要返回一個頭,告訴瀏覽器是使用哪一種方式壓縮的,編於瀏覽器解析
Res.setHeader(「Content-Encoding」,」gzip)
Return zlib.createGzip()
gzip(filePath,req,res,statObj){
//看一下瀏覽器是否支持壓縮,支持的是那種壓縮
let encoding=req.headers['accept-encoding']
//若是accept-encoding中有gzip
if(encoding){
//壓縮以前要先返回一個頭,告訴瀏覽器使用那種方式壓縮的,以便瀏覽器解析,不設置頭會出現亂碼
if(encoding.match(/gzip/)){
res.setHeader("Content -Encoding","gzip")
return zlib.createGzip()
}else if(encoding.match(/deflate/)){
res.setHeader("Content-Encoding","deflate")
return zlib.createDeflate()
}
return false
}
return false}
在返回文件以前先經過一個管道進行壓縮
let flag=this.gzip(filePath,req,res,statobj)
let flag= this.gzip(filePath,req,res,statObj)
//在響應數據以前設置一個頭 res.setHeader('ContentType',mime.getType(filePath)+"; charset=utf8")
//node中流很是重要
if(flag){
fs.createReadStream(filePath).pipe(flag).pipe(res)
}else{
//客戶端不支持壓縮,或者客戶端支持的壓縮格式服務器知足不了
fs.createReadStream(filePath).pipe(res)
}
緩存
強制緩存,須要服務器設置一個響應頭
res.setHeader('Cache-Control','max-age=20')
設置強制緩存後,在規定的時間內不會走緩存
res.setHeader('Cache-Control','no-cache')走網絡,但有緩存
res.setHeader('Cache-Control','no-store')走網絡,沒有緩存
對比緩存,也叫協商緩存
let lastModified=statObj.ctime.toGMTString()
let ifModifiedSince=req.headers['if-modified-since']
設置一個響應頭,告訴瀏覽器最新修改的時間,若是文件改動了瀏覽器會用Last-Modified來做爲最後的修改時間,在下一次訪問服務器的時候做爲請求頭帶過去
res.setHeader('Last-Modified',statObj.ctime.toGMTString())
若是文件修改了,就會自動添加一個請求頭,If-Modified-Since,表示瀏覽器上緩存頁面的最後修改時間
若是時間一致,那麼返回HTTP狀態碼304(不返回文件內容),客戶端接到以後,就直接把本地緩存文件顯示到瀏覽器中。
若是時間不一致,就返回HTTP狀態碼200和新的文件內容,客戶端接到以後,會丟棄舊文件,把新文件緩存起來,並顯示到瀏覽器中
if(ifModifiedSince){
if(ifModifiedSince !== lastModified){
// 修改了文件 走網絡
return false
}
return true
}
複製代碼
對比緩存有必定的不足,當修改了內容以後恢復原來的內容,ifModifiedSince和lastModified仍是不同,依然會走網絡
利用摘要作緩存
摘要算法:不可逆,長度是固定,相同的內容摘要相同,不一樣的內容摘要不一樣
引入crypto內置中間件,
let Etag=crypto.createHash('md5').update(fs.readFileSync(filePath)).digest('base64')
let ifNoneMatch=req.headers['if-none-match']
//if-none-match當你修改服務器上的文件時,請求頭上面會自動添加這個頭
res.setHeader('Etag',Etag)
//Etag是根據摘要來判斷是否緩存
//Etag是根據摘要來判斷是否緩存
if(ifNoneMatch){
//說明內容被修改了
if(ifNoneMatch !==Etag){
//修改了內容,而且沒恢復,走網絡
return false;
}else{
//修改了內容,而且修改完後,把內容恢復,至關於沒有修改
return true //仍是從緩存中取數據
}
}else{
//說明內容沒有改變
return true
}
複製代碼
利用對比緩存和利用摘要作緩存的代碼優化
if(ifModifiedSince&&ifNoneMatch){
if(ifNoneMatch !==Etag && ifModifiedSince !== lastModified){
return false
}
}else{
return false
}
return true
}
複製代碼
Content-Type 告訴客戶端返回文件的類型
能夠動態添加文件的類型
經過一個包mime
mime.getType(filePath)能夠將文件自動轉化爲對應的文件類型
res.setHeader('Content-Type',mime.getType(filePath)+";charset=utf8")
User-Agent 在pc端和移動端輸入同一個地址http://www.taobao.com,會出現兩套不同的項目
訪問時會自動添加一個請求頭User-Agent
HTTP中的頭: 請求頭: accept-encoding 告訴服務器,我接收的數據支持壓縮格式
if-modified-since: 對比緩存 修改時間 if-none-match: 摘要緩存 和Etag配對使用的
響應頭: Content-Type 告訴瀏覽器 我給你的內容的類型 Content-Encoding 告訴瀏覽器 我給你的內容的壓縮格式
Cache-Control 強緩 告訴瀏覽器,你多長時間之間,不要來訪問我 Expires 強緩 告訴瀏覽器,你多長時間之間,不要來訪問我
Last-Modified: 對比緩存 和 if-modified-since 配對使用 Etag 根據摘要作緩存 和 if-none-match 配對使用