当前位置:网站首页>Practical examples of node strong cache and negotiation cache
Practical examples of node strong cache and negotiation cache
2022-07-04 20:29:00 【1024 questions】
Preface
What is browser caching
advantage
Strong cache
Expires
Cache-Control
Negotiate the cache
Last-Modified、If-Modified-Since
ETag、If-None-Match
node practice
koa Start the service
Create project
koa Code
Start the service
Native koa Realize simple static resource service
Define resource type list
Resolve the requested resource type
fs Read the file
koa Handle
Strong cache validation
Set up Expire
Cache-Control
Negotiate cache validation
Last-Modified,If-Modified-Since
etag、If-None-Match
Summary
summary
PrefaceBrowser caching is a very important solution for performance optimization , Using cache reasonably can improve the user experience , It can also save the cost of the server . Mastering the principle and reasonable use of cache is very important for both front-end and operation and maintenance .
What is browser cachingBrowser cache (http cache ) It refers to that the browser stores the documents recently requested by the user on the local disk , When visitors visit the same page again , The browser can load the document directly from the local disk .
advantageReduced redundant data transfer , Save bandwidth , Reduce server pressure
Speed up client loading , Enhance user experience .
Strong cacheStrong caching does not send requests to the server , Instead, read resources directly from the cache , Strong caching can be set in two ways HTTP Header Realization :Expires and Cache-Control, These two heads are HTTP1.0 and HTTP1.1 The implementation of the .
ExpiresExpires yes HTTP1.0 A method is proposed to represent the resource expiration time header, It describes an absolute time , Returned by server .
Expires Limited by local time , If the local time is changed , Will cause cache invalidation .
Cache-ControlCache-Control Appear in HTTP/1.1, Common fields are max-age, The unit is seconds , quite a lot web Servers have default configurations , Priority over Expires, It means relative time .
for example Cache-Control:max-age=3600 The validity period of the representative resource is 3600 second . Take the... In the response header Date, Time the request was sent , Indicates that the current resource is in Date ~ Date +3600s It's effective all this time .Cache-Control It also has multiple values :
no-cache Don't use cache directly , That is, skip strong cache .
no-store Disable browsers from caching data , Each request for resources will ask the server for complete resources .
public It can be cached by all users , Including end users and CDN Such as middleware proxy server .
private Only end users' browsers are allowed to cache , Other intermediate proxy servers are not allowed to cache .
It's important to note that no-cache and no-store The difference between ,no-cache Skip strong cache , I will still go through the steps of negotiating caching , and no-store It's really not going to cache at all , All resources will not be cached locally
Negotiate the cacheWhen a browser's request for a resource fails to hit the strong cache , A request will be sent to the server , Verify that the negotiation cache hits , If the negotiation cache hits , Response to the request http Status as 304 And it will show a Not Modified String .
The negotiation cache uses 【Last-Modified,If-Modified-Since】 and 【ETag、If-None-Match】 These two pairs Header To manage .
Be careful !! Negotiation cache needs to be used with strong cache , To use negotiation cache, you need to set Cache-Control:no-cache perhaps pragma:no-cache To tell the browser not to strengthen the cache
Last-Modified、If-Modified-Sincethese two items. Header yes HTTP1.0 Version of , The two fields are used together .
Last-Modified Indicates the last modification date of the local file , The browser will be on the request header If-Modified-Since( Last time back Last-Modified Value ), The server will match this value with the time of resource modification , If the time is inconsistent , The server will return a new resource , And will Last-Modified Value update , Return to the browser as a response header . If the time is the same , Indicates that the resource is not updated , Server return 304 Status code , After getting the response status code, the browser reads the resource from the local cache .
but Last-Modified There are several problems .
Although the file has been modified , But the final content has not changed , In this way, the modification time of the file will still be updated
Some files are modified within seconds , At this time, it is not enough to record in seconds
Some servers cannot accurately obtain the last modification time of the file .
So it's here ETAG.
ETag、If-None-Matchstay HTTP1.1 In the version , Server pass Etag To set the response header cache id .Etag The value of is generated by the server . On the first request , The server will transfer resources and Etag Return to browser , The browser caches both to the local cache database . On the second request , The browser will Etag Put information in If-None-Match The request header accesses the server , After the server receives the request , It will compare the file ID in the server with the ID sent by the browser , If it's not the same , The server returns the updated resources and the new Etag , If the same , Server return 304 Status code , The browser reads the cache .
Process summary
Summarize these fields :
Cache-Control —— Before requesting the server
Expires —— Before requesting the server
If-None-Match (Etag) —— Request server
If-Modified-Since (Last-Modified) —— Request server
node practiceThis article uses koa For example , because koa It's more lightweight 、 More pure , There is no middleware bundled with it , comparison express I brought a lot of router、static And other middleware functions ,koa It is more suitable for this article as an example .
koa Start the serviceWith the purpose of learning and being easier to understand , Don't use koa-static and koa-router middleware , use koa Simple implementation web Server to verify the previous conclusion .
Create project# Create and enter a directory and create index.js file mkdir koa-cachecd koa-cachetouch index.js# Initialize project git inityarn init# take koa Install as local dependency yarn add koa
koa Code /*app.js*/const Koa = require('koa')const app = new Koa()app.use(async (ctx) => { ctx.body = 'hello koa'})app.listen(3000, () => { console.log('starting at port 3000')})
Start the service node index.js
Such a koa The service is up , visit localhost:3000 You can see hello koa.
For the convenience of debugging , Modify the code without restarting , Recommended nodemon perhaps pm2 Start the service .
Native koa Realize simple static resource serviceThe key point of implementing a static resource server is to judge the requested resource type according to the address requested by the front end , Set the returned Content-Type, Let the browser know the content type returned , The browser can decide in what form , What code to read the returned content .
Define resource type listconst mimes = { css: 'text/css', less: 'text/css', gif: 'image/gif', html: 'text/html', ico: 'image/x-icon', jpeg: 'image/jpeg', jpg: 'image/jpeg', js: 'text/javascript', json: 'application/json', pdf: 'application/pdf', png: 'image/png', svg: 'image/svg+xml', swf: 'application/x-shockwave-flash', tiff: 'image/tiff', txt: 'text/plain', wav: 'audio/x-wav', wma: 'audio/x-ms-wma', wmv: 'video/x-ms-wmv', xml: 'text/xml',}
Resolve the requested resource type function parseMime(url) { // path.extname Get the suffix of the file in the path let extName = path.extname(url) extName = extName ? extName.slice(1) : 'unknown' return mimes[extName]}
fs Read the file const parseStatic = (dir) => { return new Promise((resolve) => { resolve(fs.readFileSync(dir), 'binary') })}
koa Handle app.use(async (ctx) => { const url = ctx.request.url if (url === '/') { // Access the root path and return index.html ctx.set('Content-Type', 'text/html') ctx.body = await parseStatic('./index.html') } else { ctx.set('Content-Type', parseMime(url)) ctx.body = await parseStatic(path.relative('/', url)) }})
This basically completes a simple static resource server . Then create a new one in the root directory html Document and static Catalog , And in static Put down some files . At this time, the directory should be like this :
|-- koa-cache |-- index.html |-- index.js |-- static |-- css |-- color.css |-- ... |-- image |-- soldier.png |-- ... ... ...
It's time to go through localhost:3000/static Access the specific resource file .
index.html
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>test cache</title> <link rel="stylesheet" href="/static/css/index.css" rel="external nofollow" /> </head> <body> <div id="app"> test css file </div> <img src="/static/image/soldier.png" alt="" /> </body></html>
css/color.css
#app { color: blue;}
Open at this time localhost:3000, You can see the following effect :
The basic environment here will be set up . Next, enter the verification stage .
Strong cache validationBefore there is any configuration , May have a look network:
At this time, no matter for the first time or for several times , Will request resources from the server .
Be careful !!! Before starting the experiment network Panel Disable cache Check out , This option means to disable browser caching , The browser request will bring Cache-Control: no-cache and Pragma: no-cache Header information , At this time, all requests will not go to the cache
Set up Expiremodify index.js Medium app.use Code segment .
app.use(async (ctx) => { const url = ctx.request.url if (url === '/') { // Access the root path and return index.html ctx.set('Content-Type', 'text/html') ctx.body = await parseStatic('./index.html') } else { const filePath = path.resolve(__dirname, `.${url}`) ctx.set('Content-Type', parseMime(url)) // Set the expiration time at 30000 millisecond , That is to say 30 Seconds later ctx.set('Expires', new Date(Date.now() + 30000)) ctx.body = await parseStatic(filePath) }})
use ctx.set(‘Expires’, new Date(Date.now() + 30000)), Set the expiration time to the current time 30000 millisecond , That is to say 30 Seconds later ( The following setting header information is modified here ).
Visit again localhost:3000, You can see more Expires This Header.
There is 30 You can see it in seconds network Of Size,css The file shows disk cache, and image Resources show from memory cache. At this time, the browser cache is read directly , No request server , You can try css Change the name or delete the image file to verify , Page display normal , Explain that the previous conclusion is correct .
Cache-Controlctx.set(‘Cache-Control’, ‘max-age=300’) Set up 300 Seconds valid , The verification method is the same as above .
Negotiate cache validation Last-Modified,If-Modified-SinceHTTP1.0 The key point of negotiation cache is to bring according to the client request ifModifiedSince Field time and the corresponding modification time of the requested resource to determine whether the resource has been updated .
The first set Cache-Control: no-cache, So that the client does not strengthen the cache , Then judge whether the client request has a ifModifiedSince Field , Set without Last-Modified Field , And return the resource file . If you have it, use it fs.stat Read the modification time of the resource file , And make a comparison , If the time is the same , Then return the status code 304.
ctx.set('Cache-Control', 'no-cache') const ifModifiedSince = ctx.request.header['if-modified-since'] const fileStat = await getFileStat(filePath) if (ifModifiedSince === fileStat.mtime.toGMTString()) { ctx.status = 304 } else { ctx.set('Last-Modified', fileStat.mtime.toGMTString()) ctx.body = await parseStatic(filePath) }
etag、If-None-Matchetag The key point of is to calculate the uniqueness of resource files , Use here nodejs Built in crypto Module to calculate the hash value , And expressed by hexadecimal string .cypto The usage of can see nodejs Its official website .
crpto Not only supports string encryption , It also supports incoming buffer encryption , As nodejs The built-in modules , The unique identification used to calculate the file here is very suitable .
ctx.set('Cache-Control', 'no-cache') const fileBuffer = await parseStatic(filePath) const ifNoneMatch = ctx.request.headers['if-none-match'] const hash = crypto.createHash('md5') hash.update(fileBuffer) const etag = `"${hash.digest('hex')}"` if (ifNoneMatch === etag) { ctx.status = 304 } else { ctx.set('etag', etag) ctx.body = fileBuffer }
The effect is as follows , The browser will bring the second request If-None-Match, The server calculates the of the file hash Values are compared again , Same returns 304, Different and then return to the new file . And if you modify the file , Of documents hash The value changes , At this time two hash Mismatch , The server returns the new file and brings the new file hash Value as etag.
SummaryThrough the above code, the effect of each cache field is practiced , The code is only for demonstration , The production of static resource servers will be more complex , for example etag You won't get the file again every time to calculate the file hash value , It takes too much performance , Generally, there will be a response caching mechanism , For example, the demand for resources last-modified and etag Value to build index cache .
summaryUsually web Servers have default cache configurations , The specific implementation may also be different , image nginx、tomcat、express etc. web The server has the corresponding source code , Those who are interested can read and study .
Reasonable use of strong cache and negotiation cache depends on the use scenarios and requirements of the project . Like the current common single page application , Because packages are usually newly generated html And the corresponding static resource dependency , So you can be right html File configuration negotiation cache , And the dependencies generated by packaging , for example js、css These files can be strongly cached . Or use strong caching only for third-party libraries , Because third-party libraries usually have slow version updates , You can lock the version .
node Sample full code https://github.com/chen-junyi/code/blob/main/node/cache/koa2.js
That's all node Details of practical examples of strong caching and negotiated caching , More about node For information about strong cache negotiation cache, please pay attention to other relevant articles on software development network !
边栏推荐
- Oracle database, numbers Force 2 decimal places to display-Alibaba Cloud
- Informatics Olympiad 1336: [example 3-1] find roots and children
- kotlin 继承
- Thinking on demand development
- Cbcgpprogressdlg progress bar used by BCG
- 应用实践 | 蜀海供应链基于 Apache Doris 的数据中台建设
- 多表操作-外连接查询
- What are the consequences of closing the read / write channel?
- 什么是区块哈希竞猜游戏系统开发?哈希竞猜游戏系统开发(案例成熟)
- Cann operator: using iterators to efficiently realize tensor data cutting and blocking processing
猜你喜欢
c# .net mvc 使用百度Ueditor富文本框上传文件(图片,视频等)
Actual combat simulation │ JWT login authentication
Dark horse programmer - software testing - stage 08 2-linux and database-23-30-process port related, modify file permissions, obtain port number information, program and process related operations, Li
FS4061A升压8.4V充电IC芯片和FS4061B升压12.6V充电IC芯片规格书datasheet
Siemens HMI download prompts lack of panel image solution
Multi table operation inner join query
NLP, vision, chip What is the development direction of AI? Release of the outlook report of Qingyuan Association [download attached]
c# . Net MVC uses Baidu ueditor rich text box to upload files (pictures, videos, etc.)
多表操作-外连接查询
How to adapt your games to different sizes of mobile screen
随机推荐
On communication bus arbitration mechanism and network flow control from the perspective of real-time application
Kotlin condition control
Dark horse programmer - software testing - 09 stage 2-linux and database -31-43 instructions issued by modifying the file permission letter, - find the link to modify the file, find the file command,
Selected review | machine learning technology for Cataract Classification / classification
Template_ Large integer subtraction_ Regardless of size
What is the application technology of neural network and Internet of things
针对深度学习的“失忆症”,科学家提出基于相似性加权交错学习,登上PNAS
ICML 2022 | Meta提出鲁棒的多目标贝叶斯优化方法,有效应对输入噪声
Huawei Nova 10 series supports the application security detection function to build a strong mobile security firewall
Multi table operation inner join query
应用实践 | 蜀海供应链基于 Apache Doris 的数据中台建设
QT writing the Internet of things management platform 38- multiple database support
Integritee通过XCM集成至Moonriver,为其生态系统带来企业级隐私解决方案
c# . Net MVC uses Baidu ueditor rich text box to upload files (pictures, videos, etc.)
泰山OFFICE技术讲座:关于背景(底纹和高亮)的顺序问题
更强的 JsonPath 兼容性及性能测试之2022版(Snack3,Fastjson2,jayway.jsonpath)
【ISMB2022教程】图表示学习的精准医疗,哈佛大学Marinka Zitnik主讲,附87页ppt
Delete the characters with the least number of occurrences in the string [JS, map sorting, regular]
Why is the maximum speed the speed of light
How is the entered query SQL statement executed?