瀏覽器的緩存機(jī)制(轉(zhuǎn)載)

一、前言

緩存可以說是性能優(yōu)化中簡單高效的一種優(yōu)化方式了锐涯。一個(gè)優(yōu)秀的緩存策略可以縮短網(wǎng)頁請求資源的距離磕诊,減少延遲,并且由于緩存文件可以重復(fù)利用,還可以減少帶寬霎终,降低網(wǎng)絡(luò)負(fù)荷滞磺。

對于一個(gè)數(shù)據(jù)請求來說,可以分為發(fā)起網(wǎng)絡(luò)請求莱褒、后端處理击困、瀏覽器響應(yīng)三個(gè)步驟。瀏覽器緩存可以幫助我們在第一和第三步驟中優(yōu)化性能广凸。比如說直接使用緩存而不發(fā)起請求阅茶,或者發(fā)起了請求但后端存儲的數(shù)據(jù)和前端一致,那么就沒有必要再將數(shù)據(jù)回傳回來谅海,這樣就減少了響應(yīng)數(shù)據(jù)脸哀。

接下來的內(nèi)容中我們將通過緩存位置、緩存策略以及實(shí)際場景應(yīng)用緩存策略來探討瀏覽器緩存機(jī)制扭吁。

** 如需獲取思維導(dǎo)圖或想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub 博客撞蜂。

二、緩存位置

從緩存位置上來說分為四種侥袜,并且各自有優(yōu)先級蝌诡,當(dāng)依次查找緩存且都沒有命中的時(shí)候,才會去請求網(wǎng)絡(luò)枫吧。

Service Worker 浦旱、Memory Cache? 、Disk Cache? 由蘑、Push Cache

1.Service Worker

Service Worker 是運(yùn)行在瀏覽器背后的獨(dú)立線程闽寡,一般可以用來實(shí)現(xiàn)緩存功能。使用 Service Worker 的話尼酿,傳輸協(xié)議必須為 HTTPS爷狈。因?yàn)?Service Worker 中涉及到請求攔截,所以必須使用 HTTPS 協(xié)議來保障安全裳擎。Service Worker 的緩存與瀏覽器其他內(nèi)建的緩存機(jī)制不同涎永,它可以讓我們自由控制緩存哪些文件、如何匹配緩存鹿响、如何讀取緩存羡微,并且緩存是持續(xù)性的

Service Worker 實(shí)現(xiàn)緩存功能一般分為三個(gè)步驟:首先需要先注冊 Service Worker惶我,然后監(jiān)聽到 install 事件以后就可以緩存需要的文件妈倔,那么在下次用戶訪問的時(shí)候就可以通過攔截請求的方式查詢是否存在緩存,存在緩存的話就可以直接讀取緩存文件绸贡,否則就去請求數(shù)據(jù)盯蝴。

當(dāng) Service Worker 沒有命中緩存的時(shí)候毅哗,我們需要去調(diào)用 fetch 函數(shù)獲取數(shù)據(jù)。也就是說捧挺,如果我們沒有在 Service Worker 命中緩存的話虑绵,會根據(jù)緩存查找優(yōu)先級去查找數(shù)據(jù)。但是不管我們是從 Memory Cache 中還是從網(wǎng)絡(luò)請求中獲取的數(shù)據(jù)闽烙,瀏覽器都會顯示我們是從 Service Worker 中獲取的內(nèi)容翅睛。

2.Memory Cache

Memory Cache 也就是內(nèi)存中的緩存,主要包含的是當(dāng)前中頁面中已經(jīng)抓取到的資源, 例如頁面上已經(jīng)下載的樣式黑竞、腳本捕发、圖片等。讀取內(nèi)存中的數(shù)據(jù)肯定比磁盤快, 內(nèi)存緩存雖然讀取高效摊溶,可是緩存持續(xù)性很短爬骤,會隨著進(jìn)程的釋放而釋放。一旦我們關(guān)閉 Tab 頁面莫换,內(nèi)存中的緩存也就被釋放了

那么既然內(nèi)存緩存這么高效骤铃,我們是不是能讓數(shù)據(jù)都存放在內(nèi)存中呢拉岁?

這是不可能的。計(jì)算機(jī)中的內(nèi)存一定比硬盤容量小得多惰爬,操作系統(tǒng)需要精打細(xì)算內(nèi)存的使用喊暖,所以能讓我們使用的內(nèi)存必然不多。

當(dāng)我們訪問過頁面以后撕瞧,再次刷新頁面陵叽,可以發(fā)現(xiàn)很多數(shù)據(jù)都來自于內(nèi)存緩存。

內(nèi)存緩存中有一塊重要的緩存資源是 preloader 相關(guān)指令(例如<link rel="prefetch">)下載的資源丛版。眾所周知 preloader 的相關(guān)指令已經(jīng)是頁面優(yōu)化的常見手段之一巩掺,它可以一邊解析 js/css 文件,一邊網(wǎng)絡(luò)請求下一個(gè)資源页畦。

需要注意的事情是胖替,內(nèi)存緩存在緩存資源時(shí)并不關(guān)心返回資源的 HTTP 緩存頭 Cache-Control 是什么值,同時(shí)資源的匹配也并非僅僅是對 URL 做匹配豫缨,還可能會對 Content-Type独令,CORS 等其他特征做校驗(yàn)

3.Disk Cache

Disk Cache 也就是存儲在硬盤中的緩存好芭,讀取速度慢點(diǎn)燃箭,但是什么都能存儲到磁盤中,比之 Memory Cache 勝在容量和存儲時(shí)效性上舍败。

在所有瀏覽器緩存中招狸,Disk Cache 覆蓋面基本是最大的敬拓。它會根據(jù) HTTP Herder 中的字段判斷哪些資源需要緩存,哪些資源可以不請求直接使用瓢颅,哪些資源已經(jīng)過期需要重新請求恩尾。并且即使在跨站點(diǎn)的情況下,相同地址的資源一旦被硬盤緩存下來挽懦,就不會再次去請求數(shù)據(jù)翰意。絕大部分的緩存都來自 Disk Cache,關(guān)于 HTTP 的協(xié)議頭中的緩存字段信柿,我們會在下文進(jìn)行詳細(xì)介紹冀偶。

瀏覽器會把哪些文件丟進(jìn)內(nèi)存中?哪些丟進(jìn)硬盤中渔嚷?

關(guān)于這點(diǎn)进鸠,網(wǎng)上說法不一,不過以下觀點(diǎn)比較靠得仔尾 :

對于大文件來說客年,大概率是不存儲在內(nèi)存中的,反之優(yōu)先漠吻;

當(dāng)前系統(tǒng)內(nèi)存使用率高的話量瓜,文件優(yōu)先存儲進(jìn)硬盤。

4.Push Cache

Push Cache(推送緩存)是 HTTP/2 中的內(nèi)容途乃,當(dāng)以上三種緩存都沒有命中時(shí)绍傲,它才會被使用。它只在會話(Session)中存在耍共,一旦會話結(jié)束就被釋放烫饼,并且緩存時(shí)間也很短暫,在 Chrome 瀏覽器中只有 5 分鐘左右试读,同時(shí)它也并非嚴(yán)格執(zhí)行 HTTP 頭中的緩存指令杠纵。

Push Cache 在國內(nèi)能夠查到的資料很少,也是因?yàn)?HTTP/2 在國內(nèi)不夠普及鹏往。這里推薦閱讀Jake Archibald的HTTP/2 push is tougher than I thought這篇文章淡诗,文章中的幾個(gè)結(jié)論:

所有的資源都能被推送,并且能夠被緩存, 但是 Edge 和 Safari 瀏覽器支持相對比較差伊履;

可以推送 no-cache 和 no-store 的資源韩容;

一旦連接被關(guān)閉,Push Cache 就被釋放唐瀑;

多個(gè)頁面可以使用同一個(gè) HTTP/2 的連接群凶,也就可以使用同一個(gè) Push Cache。這主要還是依賴瀏覽器的實(shí)現(xiàn)而定哄辣,出于對性能的考慮请梢,有的瀏覽器會對相同域名但不同的 tab 標(biāo)簽使用同一個(gè) HTTP 連接赠尾;

Push Cache 中的緩存只能被使用一次;

瀏覽器可以拒絕接受已經(jīng)存在的資源推送毅弧;

你可以給其他域名推送資源气嫁。

如果以上四種緩存都沒有命中的話,那么只能發(fā)起請求來獲取資源了够坐。

那么為了性能上的考慮寸宵,大部分的接口都應(yīng)該選擇好緩存策略,通常瀏覽器緩存策略分為兩種:強(qiáng)緩存和協(xié)商緩存元咙,并且緩存策略都是通過設(shè)置 HTTP Header 來實(shí)現(xiàn)的梯影。

三、緩存過程分析

瀏覽器與服務(wù)器通信的方式為應(yīng)答模式庶香,即是:瀏覽器發(fā)起 HTTP 請求 – 服務(wù)器響應(yīng)該請求甲棍,那么瀏覽器怎么確定一個(gè)資源該不該緩存,如何去緩存呢赶掖?瀏覽器第一次向服務(wù)器發(fā)起該請求后拿到請求結(jié)果后感猛,將請求結(jié)果和緩存標(biāo)識存入瀏覽器緩存,瀏覽器對于緩存的處理是根據(jù)第一次請求資源時(shí)返回的響應(yīng)頭來確定的奢赂。具體過程如下圖:

由上圖我們可以知道:

瀏覽器每次發(fā)起請求唱遭,都會先在瀏覽器緩存中查找該請求的結(jié)果以及緩存標(biāo)識;

瀏覽器每次拿到返回的請求結(jié)果都會將該結(jié)果和緩存標(biāo)識存入瀏覽器緩存中呈驶。

以上兩點(diǎn)結(jié)論就是瀏覽器緩存機(jī)制的關(guān)鍵,它確保了每個(gè)請求的緩存存入與讀取疫鹊,只要我們再理解瀏覽器緩存的使用規(guī)則袖瞻,那么所有的問題就迎刃而解了,本文也將圍繞著這點(diǎn)進(jìn)行詳細(xì)分析。為了方便大家理解,這里我們根據(jù)是否需要向服務(wù)器重新發(fā)起 HTTP 請求將緩存過程分為兩個(gè)部分磨淌,分別是強(qiáng)緩存和協(xié)商緩存笆檀。

四、強(qiáng)緩存

強(qiáng)緩存:不會向服務(wù)器發(fā)送請求罐旗,直接從緩存中讀取資源,在 chrome 控制臺的 Network 選項(xiàng)中可以看到該請求返回 200 的狀態(tài)碼,并且 Size 顯示 from disk cache 或 from memory cache牺堰。強(qiáng)緩存可以通過設(shè)置兩種 HTTP Header 實(shí)現(xiàn):Expires 和 Cache-Control。

1.Expires

緩存過期時(shí)間颅围,用來指定資源到期的時(shí)間伟葫,是服務(wù)器端的具體的時(shí)間點(diǎn)。也就是說院促,Expires=max-age + 請求時(shí)間筏养,需要和 Last-modified 結(jié)合使用斧抱。Expires 是 Web 服務(wù)器響應(yīng)消息頭字段,在響應(yīng) http 請求時(shí)告訴瀏覽器在過期時(shí)間前瀏覽器可以直接從瀏覽器緩存取數(shù)據(jù)渐溶,而無需再次請求辉浦。

Expires 是 HTTP/1 的產(chǎn)物,受限于本地時(shí)間茎辐,如果修改了本地時(shí)間宪郊,可能會造成緩存失效。Expires: Wed, 22 Oct 2018 08:41:00 GMT表示資源會在 Wed, 22 Oct 2018 08:41:00 GMT 后過期荔茬,需要再次請求废膘。

2.Cache-Control

在 HTTP/1.1 中,Cache-Control 是最重要的規(guī)則慕蔚,主要用于控制網(wǎng)頁緩存丐黄。比如當(dāng)Cache-Control:max-age=300時(shí),則代表在這個(gè)請求正確返回時(shí)間(瀏覽器也會記錄下來)的 5 分鐘內(nèi)再次加載資源孔飒,就會命中強(qiáng)緩存灌闺。

Cache-Control 可以在請求頭或者響應(yīng)頭中設(shè)置,并且可以組合使用多種指令:

public所有內(nèi)容都將被緩存(客戶端和代理服務(wù)器都可緩存)坏瞄。具體來說響應(yīng)可被任何中間節(jié)點(diǎn)緩存桂对,如 Browser <-- proxy1 <--? proxy2 <-- Server,中間的 proxy 可以緩存資源鸠匀,比如下次再請求同一資源 proxy1 直接把自己緩存的東西給 Browser 而不再向 proxy2 要蕉斜。

private所有內(nèi)容只有客戶端可以緩存,Cache-Control 的默認(rèn)取值缀棍。具體來說宅此,表示中間節(jié)點(diǎn)不允許緩存,對于 Browser <-- proxy1 <--? proxy2 <-- Server爬范,proxy 會老老實(shí)實(shí)把 Server 返回的數(shù)據(jù)發(fā)送給 proxy1, 自己不緩存任何數(shù)據(jù)父腕。當(dāng)下次 Browser 再次請求時(shí) proxy 會做好請求轉(zhuǎn)發(fā)而不是自作主張給自己緩存的數(shù)據(jù)。

no-cache:客戶端緩存內(nèi)容青瀑,是否使用緩存則需要經(jīng)過協(xié)商緩存來驗(yàn)證決定璧亮。表示不使用 Cache-Control 的緩存控制方式做前置驗(yàn)證,而是使用 Etag 或者 Last-Modified 字段來控制緩存斥难。需要注意的是枝嘶,no-cache 這個(gè)名字有一點(diǎn)誤導(dǎo)。設(shè)置了 no-cache 之后蘸炸,并不是說瀏覽器就不再緩存數(shù)據(jù)躬络,只是瀏覽器在使用緩存數(shù)據(jù)時(shí),需要先確認(rèn)一下數(shù)據(jù)是否還跟服務(wù)器保持一致搭儒。

no-store:所有內(nèi)容都不會被緩存穷当,即不使用強(qiáng)制緩存提茁,也不使用協(xié)商緩存

max-age:max-age=xxx (xxx is numeric) 表示緩存內(nèi)容將在 xxx 秒后失效

s-maxage(單位為 s):同 max-age 作用一樣,只在代理服務(wù)器中生效(比如 CDN 緩存)馁菜。比如當(dāng) s-maxage=60 時(shí)茴扁,在這 60 秒中,即使更新了 CDN 的內(nèi)容汪疮,瀏覽器也不會進(jìn)行請求峭火。max-age 用于普通緩存,而 s-maxage 用于代理緩存智嚷。s-maxage 的優(yōu)先級高于 max-age卖丸。如果存在 s-maxage,則會覆蓋掉 max-age 和 Expires header盏道。

max-stale:能容忍的最大過期時(shí)間稍浆。max-stale 指令標(biāo)示了客戶端愿意接收一個(gè)已經(jīng)過期了的響應(yīng)。如果指定了 max-stale 的值猜嘱,則最大容忍時(shí)間為對應(yīng)的秒數(shù)衅枫。如果沒有指定,那么說明瀏覽器愿意接收任何 age 的響應(yīng)(age 表示響應(yīng)由源站生成或確認(rèn)的時(shí)間與當(dāng)前時(shí)間的差值)朗伶。

min-fresh:能夠容忍的最小新鮮度弦撩。min-fresh 標(biāo)示了客戶端不愿意接受新鮮度不多于當(dāng)前的 age 加上 min-fresh 設(shè)定的時(shí)間之和的響應(yīng)。

從圖中我們可以看到论皆,我們可以將多個(gè)指令配合起來一起使用益楼,達(dá)到多個(gè)目的。比如說我們希望資源能被緩存下來点晴,并且是客戶端和代理服務(wù)器都能緩存偏形,還能設(shè)置緩存失效時(shí)間等等。

3.Expires 和 Cache-Control 兩者對比

其實(shí)這兩者差別不大觉鼻,區(qū)別就在于 Expires 是 http1.0 的產(chǎn)物,Cache-Control 是 http1.1 的產(chǎn)物队橙,兩者同時(shí)存在的話坠陈,Cache-Control 優(yōu)先級高于 Expires;在某些不支持 HTTP1.1 的環(huán)境下捐康,Expires 就會發(fā)揮用處仇矾。所以 Expires 其實(shí)是過時(shí)的產(chǎn)物,現(xiàn)階段它的存在只是一種兼容性的寫法解总。

強(qiáng)緩存判斷是否緩存的依據(jù)來自于是否超出某個(gè)時(shí)間或者某個(gè)時(shí)間段贮匕,而不關(guān)心服務(wù)器端文件是否已經(jīng)更新,這可能會導(dǎo)致加載文件不是服務(wù)器端最新的內(nèi)容花枫,那我們?nèi)绾潍@知服務(wù)器端內(nèi)容是否已經(jīng)發(fā)生了更新呢刻盐?此時(shí)我們需要用到協(xié)商緩存策略掏膏。

五、協(xié)商緩存

協(xié)商緩存就是強(qiáng)制緩存失效后敦锌,瀏覽器攜帶緩存標(biāo)識向服務(wù)器發(fā)起請求馒疹,由服務(wù)器根據(jù)緩存標(biāo)識決定是否使用緩存的過程,主要有以下兩種情況

協(xié)商緩存生效乙墙,返回 304 和 Not Modified

協(xié)商緩存失效颖变,返回 200 和請求結(jié)果

協(xié)商緩存可以通過設(shè)置兩種 HTTP Header 實(shí)現(xiàn):Last-Modified 和 ETag 。

1.Last-Modified 和 If-Modified-Since

瀏覽器在第一次訪問資源時(shí)听想,服務(wù)器返回資源的同時(shí)腥刹,在 response header 中添加 Last-Modified 的 header,值是這個(gè)資源在服務(wù)器上的最后修改時(shí)間汉买,瀏覽器接收后緩存文件和 header衔峰;

復(fù)制代碼

Last-Modified: Fri,22Jul201601:47:00GMT

瀏覽器下一次請求這個(gè)資源,瀏覽器檢測到有 Last-Modified 這個(gè) header录别,于是添加 If-Modified-Since 這個(gè) header朽色,值就是 Last-Modified 中的值;服務(wù)器再次收到這個(gè)資源請求组题,會根據(jù) If-Modified-Since 中的值與服務(wù)器中這個(gè)資源的最后修改時(shí)間對比葫男,如果沒有變化,返回 304 和空的響應(yīng)體崔列,直接從緩存讀取梢褐,如果 If-Modified-Since 的時(shí)間小于服務(wù)器中這個(gè)資源的最后修改時(shí)間,說明文件有更新赵讯,于是返回新的資源文件和 200盈咳。

但是 Last-Modified 存在一些弊端:

如果本地打開緩存文件,即使沒有對文件進(jìn)行修改边翼,但還是會造成 Last-Modified 被修改鱼响,服務(wù)端不能命中緩存導(dǎo)致發(fā)送相同的資源;

因?yàn)?Last-Modified 只能以秒計(jì)時(shí)组底,如果在不可感知的時(shí)間內(nèi)修改完成文件丈积,那么服務(wù)端會認(rèn)為資源還是命中了,不會返回正確的資源债鸡。

既然根據(jù)文件修改時(shí)間來決定是否緩存尚有不足江滨,能否可以直接根據(jù)文件內(nèi)容是否修改來決定緩存策略?所以在 HTTP / 1.1 出現(xiàn)了ETag和If-None-Match厌均。

2.ETag 和 If-None-Match

Etag 是服務(wù)器響應(yīng)請求時(shí)唬滑,返回當(dāng)前資源文件的一個(gè)唯一標(biāo)識 (由服務(wù)器生成),只要資源有變化,Etag 就會重新生成晶密。瀏覽器在下一次加載資源向服務(wù)器發(fā)送請求時(shí)擒悬,會將上一次返回的 Etag 值放到 request header 里的 If-None-Match 里,服務(wù)器只需要比較客戶端傳來的 If-None-Match 跟自己服務(wù)器上該資源的 ETag 是否一致惹挟,就能很好地判斷資源相對客戶端而言是否被修改過了茄螃。如果服務(wù)器發(fā)現(xiàn) ETag 匹配不上,那么直接以常規(guī) GET 200 回包形式將新的資源(當(dāng)然也包括了新的 ETag)發(fā)給客戶端连锯;如果 ETag 是一致的归苍,則直接返回 304 知會客戶端直接使用本地緩存即可。

3. 兩者之間對比:

首先在精確度上运怖,Etag 要優(yōu)于 Last-Modifie拼弃,Last-Modified 的時(shí)間單位是秒,如果某個(gè)文件在 1 秒內(nèi)改變了多次摇展,那么他們的 Last-Modified 其實(shí)并沒有體現(xiàn)出來修改吻氧,但是 Etag 每次都會改變確保了精度;如果是負(fù)載均衡的服務(wù)器咏连,各個(gè)服務(wù)器生成的 Last-Modified 也有可能不一致盯孙;

第二在性能上,Etag 要遜于 Last-Modified祟滴,畢竟 Last-Modified 只需要記錄時(shí)間振惰,而 Etag 需要服務(wù)器通過算法來計(jì)算出一個(gè) hash 值;

第三在優(yōu)先級上垄懂,服務(wù)器校驗(yàn)優(yōu)先考慮 Etag骑晶。

六、緩存機(jī)制

強(qiáng)制緩存優(yōu)先于協(xié)商緩存進(jìn)行草慧,若強(qiáng)制緩存 (Expires 和 Cache-Control) 生效則直接使用緩存桶蛔,若不生效則進(jìn)行協(xié)商緩存 (Last-Modified / If-Modified-Since 和 Etag / If-None-Match),協(xié)商緩存由服務(wù)器決定是否使用緩存漫谷,若協(xié)商緩存失效仔雷,那么代表該請求的緩存失效,返回 200舔示,重新返回資源和緩存標(biāo)識朽寞,再存入瀏覽器緩存中;生效則返回 304斩郎,繼續(xù)使用緩存。具體流程圖如下:

看到這里喻频,不知道你是否存在這樣一個(gè)疑問:如果什么緩存策略都沒設(shè)置缩宜,那么瀏覽器會怎么處理?

對于這種情況,瀏覽器會采用一個(gè)啟發(fā)式的算法锻煌,通常會取響應(yīng)頭中的 Date 減去 Last-Modified 值的 10% 作為緩存時(shí)間妓布。

七、實(shí)際場景應(yīng)用緩存策略

1. 頻繁變動(dòng)的資源

Cache-Control: no-cache

對于頻繁變動(dòng)的資源宋梧,首先需要使用Cache-Control: no-cache使瀏覽器每次都請求服務(wù)器匣沼,然后配合 ETag 或者 Last-Modified 來驗(yàn)證資源是否有效。這樣的做法雖然不能節(jié)省請求數(shù)量捂龄,但是能顯著減少響應(yīng)數(shù)據(jù)大小释涛。

2. 不常變化的資源

Cache-Control: max-age=31536000

通常在處理這類資源時(shí),給它們的 Cache-Control 配置一個(gè)很大的max-age=31536000(一年)倦沧,這樣瀏覽器之后請求相同的 URL 會命中強(qiáng)制緩存唇撬。而為了解決更新的問題,就需要在文件名 (或者路徑) 中添加 hash展融, 版本號等動(dòng)態(tài)字符窖认,之后更改動(dòng)態(tài)字符,從而達(dá)到更改引用 URL 的目的告希,讓之前的強(qiáng)制緩存失效 (其實(shí)并未立即失效扑浸,只是不再使用了而已)。

在線提供的類庫 (如jquery-3.3.1.min.js,lodash.min.js等) 均采用這個(gè)模式燕偶。

八喝噪、用戶行為對瀏覽器緩存的影響

所謂用戶行為對瀏覽器緩存的影響,指的就是用戶在瀏覽器如何操作時(shí)杭跪,會觸發(fā)怎樣的緩存策略仙逻。主要有 3 種:

打開網(wǎng)頁,地址欄輸入地址: 查找 disk cache 中是否有匹配涧尿。如有則使用系奉;如沒有則發(fā)送網(wǎng)絡(luò)請求;

普通刷新 (F5):因?yàn)?TAB 并沒有關(guān)閉姑廉,因此 memory cache 是可用的缺亮,會被優(yōu)先使用 (如果匹配的話)。其次才是 disk cache桥言;

強(qiáng)制刷新 (Ctrl + F5):瀏覽器不使用緩存萌踱,因此發(fā)送的請求頭部均帶有Cache-control: no-cache(為了兼容,還帶了Pragma: no-cache), 服務(wù)器直接返回 200 和最新內(nèi)容号阿。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末并鸵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子扔涧,更是在濱河造成了極大的恐慌园担,老刑警劉巖届谈,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異弯汰,居然都是意外死亡艰山,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門咏闪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來曙搬,“玉大人,你說我怎么就攤上這事鸽嫂∽葑埃” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵溪胶,是天一觀的道長搂擦。 經(jīng)常有香客問我,道長哗脖,這世上最難降的妖魔是什么瀑踢? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮才避,結(jié)果婚禮上橱夭,老公的妹妹穿的比我還像新娘。我一直安慰自己桑逝,他們只是感情好棘劣,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著楞遏,像睡著了一般茬暇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上寡喝,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天糙俗,我揣著相機(jī)與錄音,去河邊找鬼预鬓。 笑死巧骚,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的格二。 我是一名探鬼主播劈彪,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼顶猜!你這毒婦竟也來了沧奴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤长窄,失蹤者是張志新(化名)和其女友劉穎滔吠,沒想到半個(gè)月后远寸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡屠凶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肆资。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矗愧。...
    茶點(diǎn)故事閱讀 38,064評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖郑原,靈堂內(nèi)的尸體忽然破棺而出唉韭,到底是詐尸還是另有隱情,我是刑警寧澤犯犁,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布属愤,位于F島的核電站,受9級特大地震影響酸役,放射性物質(zhì)發(fā)生泄漏住诸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一涣澡、第九天 我趴在偏房一處隱蔽的房頂上張望贱呐。 院中可真熱鬧,春花似錦入桂、人聲如沸奄薇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽馁蒂。三九已至,卻和暖如春蜘腌,著一層夾襖步出監(jiān)牢的瞬間沫屡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工逢捺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谁鳍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓劫瞳,卻偏偏與公主長得像倘潜,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子志于,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 瀏覽器對于請求資源, 流程如圖所示: 可以看到瀏覽器的緩存機(jī)制分為兩個(gè)部分: 1涮因、當(dāng)前緩存是否過期? 2伺绽、服務(wù)器中...
    zhoulujun閱讀 1,183評論 0 3
  • 一养泡、前言 緩存可以說是性能優(yōu)化中簡單高效的一種優(yōu)化方式了嗜湃。一個(gè)優(yōu)秀的緩存策略可以縮短網(wǎng)頁請求資源的距離,減少延遲澜掩,...
    浪里行舟閱讀 205,038評論 46 520
  • 針對瀏覽器的http緩存的分析也算是老生常談了购披,每隔一段時(shí)間就會冒出一篇不錯(cuò)的文章,其原理也是各大公司面試時(shí)幾乎必...
    全端玩法閱讀 874評論 0 9
  • 淺談瀏覽器Http的緩存機(jī)制 ? ? ? ? ? ? ? ? 針對瀏覽器的http緩存的分析也算是老生常談了肩榕,每隔...
    meng_philip123閱讀 998評論 0 10
  • by 亦舒 “多浪漫刚陡,幕天席地,看星星株汉,聽瀑布筐乳。”“世界上最美好的東西乔妈,其實(shí)全屬免費(fèi)蝙云。”“至于其他路召,可用錢買勃刨。” ...
    AgnesAware閱讀 201評論 0 0