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 配对使用