1.瀏覽器緩存
? 瀏覽器每次發(fā)起請求逊谋,都會(huì)先在瀏覽器緩存中查找該請求的結(jié)果以及緩存標(biāo)識?
? 強(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ù)使用緩存缓呛。
? 強(qiáng)緩存 ? ? 1.Expires Expires: Wed, 22 Oct 2018 08:41:00 GMT
? ? ? ? ? ? ? ? ? ? 表示資源會(huì)在 Wed, 22 Oct 2018 08:41:00 GMT 后過期。(受限于本地時(shí)間杭隙,如果修改了本地時(shí)間哟绊,可能會(huì)造成緩存失效)
? ? ? ? ? ? ? ? ? ?2.Cache-Control? Cache-Control:max-age=300(超過300m,優(yōu)先級高于expires)
? 協(xié)商緩存 ??協(xié)商緩存就是強(qiáng)制緩存失效后痰憎,瀏覽器攜帶緩存標(biāo)識向服務(wù)器發(fā)起請求協(xié)商緩存生效票髓,返回304和Not Modified
? ? ? ? ? ? ? ? ? ? 1. Last-Modified(以秒計(jì)時(shí)攀涵,本地打開緩存文件,不能命中緩存)
? ? ? ? ? ? ? ? ? ? 2. ETag(當(dāng)前資源文件的一個(gè)唯一標(biāo)識(由服務(wù)器生成)洽沟,要優(yōu)于Last-Modified)
? ?實(shí)際應(yīng)用 ?不常變化的資源 (Cache-Control: max-age=31536000)?靜態(tài)組件(Expires不過期)
? ? ? ? ? ? ? ? ? ?頻繁變動(dòng)的資源 ? ?需要使用Cache-Control: no-cache 使瀏覽器每次都請求服務(wù)器以故,?配合 ETag 或者 Last-Modified 來驗(yàn)證資源是否生效
2.安全策略
1、跨站腳本攻擊(XSS)
? ? ?一種“HTML注入”裆操,用戶的數(shù)據(jù)被當(dāng)成了HTML代碼一部分來執(zhí)行怒详,從而產(chǎn)生了新的語義
? ? ?XSS的防御
? ??1、HttpOnly?(瀏覽器禁止頁面的Javascript訪問帶有HttpOnly屬性的cookie)
? ? 2.?輸入檢查?輸出檢查(XSS Filter)轉(zhuǎn)義字符跷车,對于用戶的輸入應(yīng)該是永遠(yuǎn)不信任的。最普遍的做法就是轉(zhuǎn)義輸 ? ? ? ? ? 入輸出的內(nèi)容橱野,對于引號朽缴、尖括號、斜杠進(jìn)行轉(zhuǎn)義
? ? 3水援、CSP ??CSP 本質(zhì)上就是建立白名單密强,開發(fā)者明確告訴瀏覽器哪些外部資源可以加載和執(zhí)行
? ? ? ? ? ? ? ? ? ? 1.設(shè)置 HTTP Header 中的?Content-Security-Policy
? ? ? ? ? ? ? ? ? ? ?2.設(shè)置?meta?標(biāo)簽的方式?<meta http-equiv="Content-Security-Policy">
2、CSRF(跨站點(diǎn)請求偽造)
? ? ??CSRF攻擊是攻擊者利用用戶身份操作用戶賬戶的一種攻擊方式蜗元,攻擊者構(gòu)造出一個(gè)后端請求地址
? ? ?1或渤、驗(yàn)證碼
? ? ?2、由于Token的存在奕扣,攻擊者無法再構(gòu)造出一個(gè)完整的URL實(shí)施CSRF攻擊
? ? ?3薪鹦、不讓第三方網(wǎng)站訪問到用戶 Cookie
5.url請求到渲染,中間優(yōu)化
? ?1. 用戶輸入U(xiǎn)RL地址
? ?2. 瀏覽器解析URL解析出主機(jī)名
? 3. 瀏覽器將主機(jī)名轉(zhuǎn)換成服務(wù)器ip地址(瀏覽器先查找本地DNS緩存列表 沒有的話 再向?yàn)g覽器默認(rèn)的DNS服務(wù)器 ? ? 發(fā)送查詢請求 同時(shí)緩存)
? 4. 瀏覽器將端口號從URL中解析出來
? 5. 瀏覽器建立一條與目標(biāo)Web服務(wù)器的TCP連接(三次握手)
? 6. 服務(wù)端返回html
? 7.瀏覽器渲染(渲染進(jìn)程是多線程的惯豆,GUI渲染線程池磁,js引擎線程,事件觸發(fā)線程楷兽,定時(shí)觸發(fā)器線程地熄,異步http請求線程)
? - DOM樹構(gòu)建
? - CSSOM樹構(gòu)建
? - RenderObject樹構(gòu)建
? - 布局
?- 繪制
**使用DNS預(yù)解析**
DNS ??在 一次請求中,DNS解析可以占到請求時(shí)間的三分之一左右(這點(diǎn)有待驗(yàn)證)芯杀,所以如果可以縮短DNS解析時(shí)間端考,就可以加快頁面的打開速度。?rel="dns-prefetch" 用以DNS預(yù)解析
減少DNS查找(例如原來有5個(gè)img server揭厚,分別為img1.xxx.com至img5.xxx.com却特,則現(xiàn)在可以減少到3個(gè))
**請求**
1.盡量減少HTTP請求??(CSS sprites將背景圖片合并成一個(gè)文件)多個(gè)接口合并
2.避免空src或者是href值?<a href="#"></a>
空的src和href都會(huì)導(dǎo)致多余的HTTP請求,雖然不影響加載時(shí)間筛圆,但是會(huì)對服務(wù)器產(chǎn)生不必要的流量和壓力核偿。瀏覽器仍然會(huì)向服務(wù)器發(fā)起一個(gè) HTTP 請求
3.**避免重定向**3xx是重定向相關(guān)的HTTP響應(yīng)代碼,避免404瀏覽器找不到資源的情況發(fā)生
4.**使Ajax可緩存**我們可能希望`GET`請求不被緩存$.ajaxSetup({ cache: false });
5.減小cookie大小? 減小cookie的大小顽染,因?yàn)樵诎l(fā)請求時(shí)瀏覽器會(huì)將cookie信息發(fā)送到server端漾岳,所以應(yīng)該只在cookie中存必要的信息且越長度越小越好
6.利用瀏覽器緩存
**瀏覽器渲染**
1.壓縮資源(webpack)
2.CSS放在頂部轰绵,JS放在底部`defer`和 `async` 在網(wǎng)絡(luò)讀取(下載)這塊兒是一樣的尼荆,都是異步的(相較于 HTML 解析)
3.重排reflow與重繪repaint
?只觸發(fā)重繪不觸發(fā)重排的一些CSS屬性:js盡量少訪問dom節(jié)點(diǎn)和css 屬性左腔,不要通過父級來改變子元素樣式,最好 直接改變子元素樣式捅儒,改變子元素樣式盡可能不要影響父元素和兄弟元素的大小和尺寸液样,盡量通過class來設(shè)計(jì)元素 樣式,切忌用style 多次操作單個(gè)屬性
#### 代碼部分
for循環(huán)巧还、迭代鞭莽、同步、重定向麸祷、阻塞請求澎怒,未刪除重復(fù)、無用的代碼阶牍,未加入Async異步機(jī)制
6.水平垂直居中喷面,兩邊固定中間自適應(yīng)布局
position transform?
position: absolute;left: 50%;top: 50%;transform: translate(-50%,-50%);
flex布局
display: flex;//flex布局 justify-content: center;//使子項(xiàng)目水平居中 align-items: center;//使子項(xiàng)目垂直居中?
table-cell布局?
.wp{display: table-cell;text-align: center;vertical-align: middle;}.box{display: inline-block;}
absolute + calc
.wp { position: relative;}.box { position: absolute;; top: calc(50% -50px); left: calc(50% -50px);}
兩邊固定中間自適應(yīng)布局
1).絕對定位法
2).使用自身浮動(dòng)法
3、css3新特性走孽,使用flex
4.. 雙飛翼布局
7.跨域惧辈,如何跨域,跨域圖片如何處理
? ? 域名磕瓷、協(xié)議盒齿、端口有一個(gè)不同就不是同源,三者均相同困食,這兩個(gè)網(wǎng)站才是同源
? ??瀏覽器會(huì)對上面提到的跨域請求作出限制县昂。瀏覽器之所以要對跨域請求作出限制,是出于安全方面的考慮陷舅,因?yàn)榭缬蛘埱笥锌赡鼙徊环ǚ肿永脕戆l(fā)動(dòng)?CSRF攻擊倒彰。
?JSONP
JSONP 本質(zhì)上是利用?<script><img><iframe>?等標(biāo)簽不受同源策略限制,可以從不同域加載并執(zhí)行資源的特性莱睁,來實(shí)現(xiàn)數(shù)據(jù)跨域傳輸待讳。
優(yōu)缺點(diǎn):
JSONP 的優(yōu)點(diǎn)是:它不像XMLHttpRequest對象實(shí)現(xiàn)的Ajax請求那樣受到同源策略的限制;它的兼容性更好仰剿,在更加古老的瀏覽器中都可以運(yùn)行创淡。
JSONP 的缺點(diǎn)是:它只支持 GET 請求,而不支持 POST 請求等其他類型的 HTTP 請求
CORS
? 跨源資源共享?Cross-Origin Resource Sharing(CORS)?是一個(gè)新的 W3C 標(biāo)準(zhǔn)南吮,它新增的一組HTTP首部字段琳彩,允許服務(wù)端其聲明哪些源站有權(quán)限訪問哪些資源
與 JSONP 的比較
JSONP 只能實(shí)現(xiàn) GET 請求,而 CORS 支持所有類型的 HTTP 請求
使用 CORS ,開發(fā)者可以是使用普通的 XMLHttpRequest 發(fā)起請求和獲取數(shù)據(jù)露乏,比起 JSONP 有更好的錯(cuò)誤處理
雖然絕大多數(shù)現(xiàn)代的瀏覽器都已經(jīng)支持 CORS碧浊,但是 CORS 的兼容性比不上 JSONP,一些比較老的瀏覽器只支持 JSONP
8.vuex
Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式瘟仿。每一個(gè) Vuex 應(yīng)用的核心就是 store(倉庫)箱锐。“store” 基本上就是一個(gè)容器劳较,它包含著你的應(yīng)用中大部分的狀態(tài) ( state )驹止。
(1)Vuex 的狀態(tài)存儲(chǔ)是響應(yīng)式的。當(dāng) Vue 組件從 store 中讀取狀態(tài)的時(shí)候观蜗,若 store 中的狀態(tài)發(fā)生變化臊恋,那么相應(yīng)的組件也會(huì)相應(yīng)地得到高效更新。
(2)改變 store 中的狀態(tài)的唯一途徑就是顯式地提交 (commit) mutation墓捻。這樣使得我們可以方便地跟蹤每一個(gè)狀態(tài)的變化抖仅。
主要包括以下幾個(gè)模塊:
State:定義了應(yīng)用狀態(tài)的數(shù)據(jù)結(jié)構(gòu),可以在這里設(shè)置默認(rèn)的初始狀態(tài)毙替。
Getter:允許組件從 Store 中獲取數(shù)據(jù)岸售,mapGetters 輔助函數(shù)僅僅是將 store 中的 getter 映射到局部計(jì)算屬性践樱。
Mutation:是唯一更改 store 中狀態(tài)的方法厂画,且必須是同步函數(shù)。
Action:用于提交 mutation拷邢,而不是直接變更狀態(tài)袱院,可以包含任意異步操作。
Module:允許將單一的 Store 拆分為多個(gè) store 且同時(shí)保存在單一的狀態(tài)樹中瞭稼。
state
通過在根實(shí)例中注冊?store?選項(xiàng)忽洛,該 store 實(shí)例會(huì)注入到根組件下的所有子組件中,且子組件能通過this.$store?訪問到?this.$store.state.count
mapState?輔助函數(shù)
import{mapState}from'vuex'
computed:mapState([// 映射 this.count 為 store.state.count'count'])
Getters
我們需要從 store 中的 state 中派生出一些狀態(tài)环肘,例如對列表進(jìn)行過濾并計(jì)數(shù):
getters:{doneTodos:state=>{returnstate.todos.filter(todo=>todo.done)}}
mapGetters?輔助函數(shù)
import{mapGetters}from'vuex'
export default{// ...computed:{// 使用對象展開運(yùn)算符將 getter 混入 computed 對象中...mapGetters(['doneTodosCount','anotherGetter',// ...])}}
Mutation
更改 Vuex 的 store 中的狀態(tài)的唯一方法是提交 mutation欲虚。
mutations:{increment(state){// 變更狀態(tài)state.count++}
store.commit('increment')
Action
store.dispatch('increment')
9.vue nextick與宏任務(wù)微任務(wù)瀏覽器循環(huán)
vue的nextTick方法的實(shí)現(xiàn)原理了,總結(jié)一下就是:
vue用異步隊(duì)列的方式來控制DOM更新和nextTick回調(diào)先后執(zhí)行
microtask因?yàn)槠涓邇?yōu)先級特性悔雹,能確保隊(duì)列中的微任務(wù)在一次事件循環(huán)前被執(zhí)行完畢
因?yàn)榧嫒菪詥栴}复哆,vue不得不做了microtask向macrotask的降級方案
任務(wù)隊(duì)列又分為macro-task(宏任務(wù))與micro-task(微任務(wù)),在最新標(biāo)準(zhǔn)中腌零,它們被分別稱為task與jobs梯找。
macro-task大概包括:script(整體代碼), setTimeout, setInterval, setImmediate, I/O, UI rendering。
micro-task大概包括: process.nextTick, Promise, Object.observe(已廢棄), MutationObserver(html5新特性)
其中益涧,nextTick隊(duì)列會(huì)比Promie先執(zhí)行锈锤。nextTick中的可執(zhí)行任務(wù)執(zhí)行完畢之后,才會(huì)開始執(zhí)行Promise隊(duì)列中的任務(wù)。
當(dāng)所有可執(zhí)行的微任務(wù)執(zhí)行完畢之后久免,這一輪循環(huán)就表示結(jié)束了浅辙。下一輪循環(huán)繼續(xù)從宏任務(wù)隊(duì)列開始執(zhí)行。
這個(gè)時(shí)候妄壶,script已經(jīng)執(zhí)行完畢摔握,所以就從setTimeout隊(duì)列開始執(zhí)行。
10.vue 原理以及diff算法和虛擬dom
輸入框內(nèi)容變化時(shí)丁寄,Data 中的數(shù)據(jù)同步變化氨淌。即 View => Data 的變化。
Data 中的數(shù)據(jù)變化時(shí)伊磺,文本節(jié)點(diǎn)的內(nèi)容同步變化盛正。即 Data => View 的變化。
其中屑埋,View?變化更新?Data?豪筝,可以通過事件監(jiān)聽的方式來實(shí)現(xiàn),所以 Vue 的數(shù)據(jù)雙向綁定的工作主要是如何根據(jù)?Data?變化更新?View摘能。
Vue 主要通過以下 4 個(gè)步驟來實(shí)現(xiàn)數(shù)據(jù)雙向綁定的:
實(shí)現(xiàn)一個(gè)監(jiān)聽器 Observer:對數(shù)據(jù)對象進(jìn)行遍歷续崖,包括子屬性對象的屬性,利用 Object.defineProperty() 對屬性都加上 setter 和 getter团搞。這樣的話严望,給這個(gè)對象的某個(gè)值賦值,就會(huì)觸發(fā) setter逻恐,那么就能監(jiān)聽到了數(shù)據(jù)變化像吻。
實(shí)現(xiàn)一個(gè)解析器 Compile:解析 Vue 模板指令,將模板中的變量都替換成數(shù)據(jù)复隆,然后初始化渲染頁面視圖拨匆,并將每個(gè)指令對應(yīng)的節(jié)點(diǎn)綁定更新函數(shù),添加監(jiān)聽數(shù)據(jù)的訂閱者挽拂,一旦數(shù)據(jù)有變動(dòng)惭每,收到通知,調(diào)用更新函數(shù)進(jìn)行數(shù)據(jù)更新亏栈。
實(shí)現(xiàn)一個(gè)訂閱者 Watcher:Watcher 訂閱者是 Observer 和 Compile 之間通信的橋梁 台腥,主要的任務(wù)是訂閱 Observer 中的屬性值變化的消息,當(dāng)收到屬性值變化的消息時(shí)仑扑,觸發(fā)解析器 Compile 中對應(yīng)的更新函數(shù)览爵。
虛擬 DOM 的實(shí)現(xiàn)原理主要包括以下 3 部分:
用 JavaScript 對象模擬真實(shí) DOM 樹,對真實(shí) DOM 進(jìn)行抽象镇饮;
diff 算法 — 比較兩棵虛擬 DOM 樹的差異蜓竹;
pach 算法 — 將兩個(gè)虛擬 DOM 對象的差異應(yīng)用到真正的 DOM 樹。
優(yōu)點(diǎn):
保證性能下限:框架的虛擬 DOM 需要適配任何上層 API 可能產(chǎn)生的操作,它的一些 DOM 操作的實(shí)現(xiàn)必須是普適的俱济,所以它的性能并不是最優(yōu)的嘶是;但是比起粗暴的 DOM 操作性能要好很多,因此框架的虛擬 DOM 至少可以保證在你不需要手動(dòng)優(yōu)化的情況下蛛碌,依然可以提供還不錯(cuò)的性能聂喇,即保證性能的下限;
無需手動(dòng)操作 DOM:我們不再需要手動(dòng)去操作 DOM蔚携,只需要寫好 View-Model 的代碼邏輯希太,框架會(huì)根據(jù)虛擬 DOM 和 數(shù)據(jù)雙向綁定,幫我們以可預(yù)期的方式更新視圖酝蜒,極大提高我們的開發(fā)效率誊辉;
diff算法(一哈哈學(xué)不完)
11proxy與defineproperty
利用Proxy或Object.defineProperty生成的Observer針對對象/對象的屬性進(jìn)行"劫持",在屬性發(fā)生變化后通知訂閱者
Object.defineProperty()??只能對屬性進(jìn)行數(shù)據(jù)劫持,不能對整個(gè)對象進(jìn)行劫持亡脑,同理無法對數(shù)組進(jìn)行劫持我們就能知道 Vue 框架是通過遍歷數(shù)組 和遞歸遍歷對象堕澄,從而達(dá)到利用 Object.defineProperty() 也能對對象和數(shù)組(部分方法的操作)進(jìn)行監(jiān)聽。
Proxy 的優(yōu)勢如下:
Proxy 可以直接監(jiān)聽對象而非屬性霉咨;
Proxy 可以直接監(jiān)聽數(shù)組的變化蛙紫;
Proxy 有多達(dá) 13 種攔截方法,不限于 apply、ownKeys途戒、deleteProperty坑傅、has 等等是 Object.defineProperty 不具備的;
Proxy 返回的是一個(gè)新對象,我們可以只操作新的對象達(dá)到目的,而 Object.defineProperty 只能遍歷對象屬性直接修改棺滞;
Proxy 作為新標(biāo)準(zhǔn)將受到瀏覽器廠商重點(diǎn)持續(xù)的性能優(yōu)化裁蚁,也就是傳說中的新標(biāo)準(zhǔn)的性能紅利矢渊;
Object.defineProperty 的優(yōu)勢如下:
兼容性好继准,支持 IE9,而 Proxy 的存在瀏覽器兼容性問題,而且無法用 polyfill 磨平矮男,因此 Vue 的作者才聲明需要等到下個(gè)大版本( 3.0 )才能用 Proxy 重寫移必。
12.項(xiàng)目中用的哪些模式(一哈哈學(xué)不完)
13.純函數(shù)
如果函數(shù)的調(diào)用參數(shù)相同,則永遠(yuǎn)返回相同的結(jié)果毡鉴。它不依賴于程序執(zhí)行期間函數(shù)外部任何狀態(tài)或數(shù)據(jù)的變化崔泵,必須只依賴于其輸入?yún)?shù)。
14.vue-router 路由模式有幾種猪瞬?
hash: 使用 URL hash 值來作路由憎瘸。支持所有瀏覽器,包括不支持 HTML5 History Api 的瀏覽器陈瘦;
我們可以使用 hashchange 事件來監(jiān)聽 hash 值的變化幌甘,從而對頁面進(jìn)行跳轉(zhuǎn)(渲染)。
history :? 依賴 HTML5 History API 和服務(wù)器配置。具體可以查看 HTML5 History 模式锅风;
history.pushState() 和 history.repalceState()酥诽。前者是新增一個(gè)歷史記錄,后者是直接替換當(dāng)前的歷史記錄皱埠,如下所示: