瀏覽器
-
緩存
強緩存:也稱為本地緩存,不向服務(wù)器發(fā)送請求,直接使用客戶端本地緩存數(shù)據(jù);
協(xié)商緩存:也稱為304緩存,向服務(wù)器發(fā)送請求,由服務(wù)器判斷請求文件是否發(fā)生改變。如果未發(fā)生改變,則返回304狀態(tài)碼,通知客戶端直接使用本地緩存;如果發(fā)生改變,則直接返回請求文件。

-
強緩存
瀏覽器在加載資源時,會先根據(jù)本地緩存資源的 header 中的 expires 和 cahe-control 判斷是否命中強緩存,如果命中則直接使用緩存中的資源不會再向服務(wù)器發(fā)送請求。
Expires:HTTP1.0,值為GMT格式的時間字符串,緩存過期時間,在這時間之前則命中緩存;是一個絕對時間,服務(wù)器時間和本地時間偏差大時候,緩存不能有效的命中;
Cache-Control:HTTP1.1,主要取值如下
public:所有內(nèi)容都將被緩存(客戶端和代理服務(wù)器都可緩存);
private:所有內(nèi)容只有客戶端可以緩存,Cache-Control的默認取值;
no-cache:客戶端緩存內(nèi)容,但是是否使用緩存則需要經(jīng)過協(xié)商緩存來驗證決定;
no-store:所有內(nèi)容都不會被緩存,即不使用強制緩存,也不使用協(xié)商緩存;
max-age=xxx(xxx is number):緩存內(nèi)容將在xxx秒后失效;
must-revalidate:強制瀏覽器嚴格遵守你設(shè)置的cache規(guī)則;
proxy-revalidate:強制proxy嚴格遵守你設(shè)置的cache規(guī)則;
-
協(xié)商緩存
Last-Modified與If-Modified-Since:HTTP1.0
首次請求;
服務(wù)器告知啟用協(xié)商緩存規(guī)則,并在響應(yīng)頭帶上
Last-Modified,告知緩存到期時間;隨后的每次請求,請求頭都會攜帶
If-Modified-Since,該值等于上一次響應(yīng)頭中的Last-Modified的值;服務(wù)器收到
If-Modified-Since后,會將該屬性的值與服務(wù)器上資源的最后修改時間進行匹配,從而判斷資源是否發(fā)生了變化;-
如果發(fā)生變化會返回一個完整的響應(yīng)內(nèi)容,在響應(yīng)頭中添加新的
Last-Modified值,否則,只返回 header 部分,狀態(tài)碼為304,響應(yīng)頭不會再添加Last-Modified;Last-Modified是感知文件修改時間,而且是秒級別;所以當文件內(nèi)容未修改,但編輯時間修改了,則無法命中緩存;同樣在毫秒內(nèi)改變文件并請求,則會命中緩存,無法得到最新的文件;Etag與If-None-Match:HTTP1.1
首次請求;
服務(wù)器啟用協(xié)商緩存情況下,會在響應(yīng)頭中帶上
Etag;隨后每次請求,請求頭上都會帶上
If-None-Match,該值等于上一次響應(yīng)頭中的Etag的值;服務(wù)器收到
If-None-Match后,會進行比對,從而判斷資源是否發(fā)生變化;-
如果變化返回一個完整響應(yīng)內(nèi)容,在響應(yīng)頭上添加新的
Etag值,否則返回 304,響應(yīng)頭不會在添加EtagEtag的生成需要服務(wù)器付出額外的開銷,會影響服務(wù)端性能
-
不能緩存的請求
HTTP信息頭中包含
Cache-Control:no-cache,pragma:no-cache(HTTP1.0),或Cache-Control:max-age=0等告訴瀏覽器不用緩存的請求;需要根據(jù)
Cookie,認證信息等決定輸入內(nèi)容的動態(tài)請求是不能被緩存的;經(jīng)過HTTPS安全加密的請求;
POST請求無法被緩存;
HTTP響應(yīng)頭中不包含
Last-Modified/Etag,也不包含Cache-Control/Expires的請求無法被緩存;
重定向
301:永久移動,請求的資源已被永久的移動到新的URL,返回信息會包括新的URL,瀏覽器還會自動定向到新的URL,今后任何新的請求都應(yīng)該使用新的URL來代替;
302:臨時移動。與301類似,但是資源只是臨時被移動,客戶端應(yīng)該繼續(xù)使用原有的URI;
304:未修改,所請求的資源未修改,服務(wù)器返回此狀態(tài)碼時,不會返回任何資源;客戶端通常會緩存所訪問過的資源,通過提供一個頭信息指出客戶端希望只返回在指定日期之后修改的資源;
-
輸入URL到頁面呈現(xiàn)過程
-
DNS解析
①、瀏覽器緩存
②、系統(tǒng)DNS緩存
③、路由器緩存
④、ISP(運營商)DNS緩存
⑤、迭代遞歸查詢DNS
-
HTTP請求
①、生成請求報文
②、TCP三次握手建立連接
③、服務(wù)端響應(yīng)發(fā)送內(nèi)容
④、客戶端接收響應(yīng)內(nèi)容
⑤、TCP四次揮手斷開連接
-
瀏覽器解析渲染頁面
①、解析HTML、CSS,構(gòu)建DOM Tree和CSSOM Tree
②、根據(jù)DOM Tree和CSSOM Tree,構(gòu)建Render Tree
③、根據(jù)Render Tree,構(gòu)建生成RenderLayer樹布局(計算每個節(jié)點信息、確認布局位置)
④、渲染:繪制階段,系統(tǒng)會遍歷呈現(xiàn)樹,并調(diào)用呈現(xiàn)器的“paint”方法,將呈現(xiàn)器的內(nèi)容顯示在屏幕上;
-
-
跨域
域:由協(xié)議、域名、端口組成;
跨域:因為瀏覽器出于安全考慮,有同源策略,所以瀏覽器從一個域的網(wǎng)頁去請求另一個域的資源時就是跨域;
-
跨域解決方案:
①、JSONP:利用script標簽,只支持get請求,存在xss安全隱患,需要服務(wù)端配合改造;
②、CORS:利用請求header
Access-Control-Allow-Origin控制來源域?qū)崿F(xiàn)跨域;③、反向代理:nginx、node等;
-
同源策略
瀏覽器的同源策略,限制了來自不同源的"document"或腳本,對當前"document"讀取或設(shè)置某些屬性。從一個域上加載的腳本不允許訪問另外一個域的文檔屬性;同源策略是瀏覽器上為安全性考慮實施的非常重要的安全策略。
要求同源:Ajax請求、cookie、LocalStorage、IndexDB、DOM操作
-
HTTP1、HTTP1.1、HTTP2、HTTP3
HTTP1.0:TCP短連接,可以利用Connection: keep-alive保持
HTTP1.1:持久鏈接,多數(shù)瀏覽器建立6個連接,然后將請求壓隊執(zhí)行,可能造成隊頭阻塞
HTTP2.0:二進制分幀協(xié)議、多路復(fù)用、頭部壓縮、服務(wù)器推送、流控,單個TCP連接、隊頭阻塞問題會影響整個連接
HTTP3.0:QUIC,UDP+多路復(fù)用+安全加密+擁塞控制,不需要建聯(lián)斷連的開銷
-
跨域如何處理cookie
前端的請求用jsonp的形式
-
前端加上配置:
xhrFields: { withCredentials: true },
服務(wù)端加上配置:
header('Access-Control-Allow-Credentials: true');
-
cookie SameSite
Strict:嚴格模式,cookie不能跨域使用
Lax:允許部分第三方請求攜帶cookie(a標簽鏈接、預(yù)加載link、get表單)
None:無論是否跨站都會發(fā)送cookie
-
首屏加載優(yōu)化
使用CDN資源,vue、vue-router、vuex、element-ui等從vendor.js中分離出來,使用CDN資源引入(國內(nèi)推薦BootCDN);
開啟gzip壓縮,nginx開啟gzip壓縮;
vue-router使用懶加載,異步方式分模塊加載文件,配置chunkFilename;
圖片資源壓縮,icon資源使用雪碧圖/iconfont;
webpack配置優(yōu)化,用uglifyjs-webpack-plugin壓縮js文件,清除log日志和注釋,配置SplitChunks抽取公共代碼;使用mini-xss-extract-plugin提取CSS 到單獨的文件, 并使用optimize-css-assets-webpack-plugin來壓縮CSS文件;
骨架屏
SSR、node聚合
-
網(wǎng)頁從請求到呈現(xiàn)花了很長時間,如何排查
可以用Chrome dev-tools中的performance工具,截取第一個白屏到渲染完成的過程;可以看到loading、scripting、rendering、painting、system、idle的時間花費分布;
Web Components
- Custom elements(自定義元素):一組JavaScript API,允許您定義custom elements及其行為,然后可以在您的用戶界面中按照需要使用它們
<body>
<user-card></user-card>
<template>...</template>
<script>
class UserCard extends HTMLElement {
constructor() {
super();
var templateElem = document.getElementById('userCardTemplate');
var content = templateElem.content.cloneNode(true);
this.appendChild(content);
}
}
window.customElements.define('user-card', UserCard);
</script>
</body>
- Shadow DOM(影子DOM):一組JavaScript API,用于將封裝的“影子”DOM樹附加到元素(與主文檔DOM分開呈現(xiàn))并控制其關(guān)聯(lián)的功能。通過這種方式,您可以保持元素的功能私有,這樣它們就可以被腳本化和樣式化,而不用擔心與文檔的其他部分發(fā)生沖突
class UserCard extends HTMLElement {
constructor() {
super();
var shadow = this.attachShadow( { mode: 'closed' } );
var templateElem = document.getElementById('userCardTemplate');
var content = templateElem.content.cloneNode(true);
content.querySelector('img').setAttribute('src', this.getAttribute('image'));
content.querySelector('.container>.name').innerText = this.getAttribute('name');
content.querySelector('.container>.email').innerText = this.getAttribute('email');
shadow.appendChild(content);
}
}
window.customElements.define('user-card', UserCard);
-
HTML templates(HTML模板):
<template>和<slot>元素使您可以編寫不在呈現(xiàn)頁面中顯示的標記模板。然后它們可以作為自定義元素結(jié)構(gòu)的基礎(chǔ)被多次重用