前端基礎(chǔ)之瀏覽器(一)

瀏覽器

1.1 cookie sessionStorage localStorage 區(qū)別

共同點(diǎn):

都是保存在瀏覽器端、且同源的

區(qū)別:

  1. cookie數(shù)據(jù)始終在同源的http請(qǐng)求中攜帶(即使不需要)况增,即cookie在瀏覽器和服務(wù)器間來(lái)回傳遞劣纲,而sessionStorage和localStorage不會(huì)自動(dòng)把數(shù)據(jù)發(fā)送給服務(wù)器压真,僅在本地保存氮采。cookie數(shù)據(jù)還有路徑(path)的概念体捏,可以限制cookie只屬于某個(gè)路徑下

  2. 存儲(chǔ)大小限制也不同塔插,cookie數(shù)據(jù)不能超過(guò)4K梗摇,同時(shí)因?yàn)槊看蝖ttp請(qǐng)求都會(huì)攜帶cookie、所以cookie只適合保存很小的數(shù)據(jù)想许,如會(huì)話標(biāo)識(shí)伶授。sessionStorage和localStorage雖然也有存儲(chǔ)大小的限制,但比cookie大得多流纹,可以達(dá)到5M或更大

  3. 數(shù)據(jù)有效期不同糜烹,sessionStorage:僅在當(dāng)前瀏覽器窗口關(guān)閉之前有效;localStorage:始終有效捧颅,窗口或?yàn)g覽器關(guān)閉也一直保存景图,因此用作持久數(shù)cookie:只在設(shè)置的cookie過(guò)期時(shí)間之前有效,即使窗口關(guān)閉或?yàn)g覽器關(guān)閉

  4. 作用域不同碉哑,sessionStorage不在不同的瀏覽器窗口中共享挚币,即使是同一個(gè)頁(yè)面;localstorage在所有同源窗口中都是共享的扣典;cookie也是在所有同源窗口中都是共享的

  5. web Storage支持事件通知機(jī)制妆毕,可以將數(shù)據(jù)更新的通知發(fā)送給監(jiān)聽(tīng)者

  6. Storage的api接口使用更方便

1.2 如何寫(xiě)一個(gè)會(huì)過(guò)期的localStorage,說(shuō)說(shuō)想法

惰性刪除 和 定時(shí)刪除

惰性刪除

惰性刪除是指贮尖,某個(gè)鍵值過(guò)期后笛粘,該鍵值不會(huì)被馬上刪除,而是等到下次被使用的時(shí)候湿硝,才會(huì)被檢查到過(guò)期薪前,此時(shí)才能得到刪除。

var lsc = (function (self) {
var prefix = 'lsc_'
    /**
    * 增加一個(gè)鍵值對(duì)數(shù)據(jù)
    * @param key 鍵
    * @param val 值
    * @param expires 過(guò)期時(shí)間关斜,單位為秒
    */
    self.set = function(key, val, expires) {
        key = prefix + key;
        val = JSON.stringify({'val': val, 'expires': new Date().getTime() + expires * 1000});
        localStorage.setItem(key, val);
    };
    /**
    * 讀取對(duì)應(yīng)鍵的值數(shù)據(jù)
    * @param key 鍵
    * @returns {null|*} 對(duì)應(yīng)鍵的值
    */
    self.get = function(key) {
        key = prefix + key;
        var val = localStorage.getItem(key);
        if (!val) {
            return null;
        }
        val = JSON.parse(val);
        if (val.expires < new Date().getTime()) {
            localStorage.removeItem(key);
            return null;
        }
        return val.val;
    };
    return self;
}(lsc || {}));

定時(shí)刪除

定時(shí)刪除是指示括,每隔一段時(shí)間執(zhí)行一次刪除操作

  1. 隨機(jī)測(cè)試20個(gè)設(shè)置了過(guò)期時(shí)間的key。
  2. 刪除所有發(fā)現(xiàn)的已過(guò)期的key痢畜。
  3. 若刪除的key超過(guò)5個(gè)則重復(fù)步驟****1垛膝,直至重復(fù)500次鳍侣。
var lsc = (function (self) {
    var prefix = 'lsc_'
    var list = [];
    //初始化
    self.init = function () {
        var keys = Object.keys(localStorage);
        var reg = new RegExp('^' + prefix);
        var temp = [];
        //遍歷所有l(wèi)ocalStorage中的所有key
        for (var i = 0; i < keys.length; i++) {
            //找出可過(guò)期緩存的key
            if (reg.test(keys[i])) {
                temp.push(keys[i]);
            }
        }
        list = temp;
    };
    self.init();
    self.check = function () {
        if (!list || list.length == 0) {
            return;
        }
        var checkCount = 0;
    while (checkCount < 500) {
        var expireCount = 0;
        // 隨機(jī)測(cè)試20個(gè)設(shè)置了過(guò)期時(shí)間的key
        for (var i = 0; i < 20; i++) {
            if (list.length == 0) {
                break;
            }
            var index = Math.floor(Math.random() * list.length);
            var key = list[index];
            var val = localStorage.getItem(list[index]);
            // 從list中刪除被惰性刪除的key
            if (!val) {
                list.splice(index, 1);
                expireCount++;
                continue;
            }
            val = JSON.parse(val);
            // 刪除所有發(fā)現(xiàn)的已過(guò)期的key
            if (val.expires < new Date().getTime()) {
                list.splice(index, 1);
                localStorage.removeItem(key);
                expireCount++;
            }
        }
        // 若刪除的key不超過(guò)5個(gè)則跳出循環(huán)
        if (expireCount <= 5 || list.length == 0) {
            break;
        }
        checkCount++;
        }
    }
    //每隔一秒執(zhí)行一次定時(shí)刪除
    window.setInterval(self.check, 1000);
    return self;
}(lsc || {}));

1.3 localStorage 能跨域嗎

不能

解決辦法

  • 通過(guò)postMessage來(lái)實(shí)現(xiàn)跨源通信
  • 可以實(shí)現(xiàn)一個(gè)公共的iframe部署在某個(gè)域名中,作為共享域
  • 將需要實(shí)現(xiàn)localStorage跨域通信的頁(yè)面嵌入這個(gè)iframe

1.4 memory cache 如何開(kāi)啟

memory cache 如何開(kāi)啟是一種比較特殊的緩存吼拥,他不受max-age倚聚、no-cache等配置的影響,即使我們不設(shè)置緩存凿可,如果當(dāng)前的內(nèi)存空間比較充裕的話惑折,一些資源還是會(huì)被緩存下來(lái)。但這種緩存是暫時(shí)的矿酵,一旦關(guān)閉了瀏覽器唬复,這一部分用于緩存的內(nèi)存空間就會(huì)被釋放掉。如果真的不想使用緩存全肮,可以設(shè)置no-store,這樣棘捣,即便是內(nèi)存緩存辜腺,也不會(huì)生效

1.5 localstorage的注意哪些問(wèn)題

  1. 兼容性問(wèn)題
  2. localStorage在瀏覽器的隱私模式下面是不可讀取的
  3. localStorage本質(zhì)上是對(duì)字符串的讀取,如果存儲(chǔ)內(nèi)容多的話會(huì)消耗內(nèi)存空間乍恐,會(huì)導(dǎo)致頁(yè)面變卡
  4. localStorage不能被爬蟲(chóng)抓取到

1.6 瀏覽器輸入U(xiǎn)RL發(fā)生了什么

  1. URL 解析
  2. DNS 查詢
  3. TCP 連接
  4. 處理請(qǐng)求
  5. 接受響應(yīng)
  6. 渲染頁(yè)面

1.7 瀏覽器是如何渲染頁(yè)面的评疗?

不同瀏覽器內(nèi)核渲染機(jī)制有所區(qū)別

  1. HTML 被 HTML 解析器解析成 DOM 樹(shù);
  2. CSS 被 CSS 解析器解析成 CSSOM 樹(shù)茵烈;
  3. 結(jié)合 DOM 樹(shù)和 CSSOM 樹(shù)百匆,生成一棵渲染樹(shù)(Render Tree),這一過(guò)程稱為 Attachment呜投;
  4. 生成布局(flow)加匈,瀏覽器在屏幕上“畫(huà)”出渲染樹(shù)中的所有節(jié)點(diǎn);
  5. 將布局繪制(paint)在屏幕上仑荐,顯示出整個(gè)頁(yè)面雕拼。

webkit

Gecko

1.8 重繪、重排

概念

  1. 重排(Reflow):當(dāng)渲染樹(shù)的一部分必須更新并且節(jié)點(diǎn)的尺寸發(fā)生了變化粘招,瀏覽器會(huì)使渲染樹(shù)中受到影響的部分失效啥寇,并重新構(gòu)造渲染樹(shù)
  2. 重繪(Repaint):是在一個(gè)元素的外觀被改變所觸發(fā)的瀏覽器行為,瀏覽器會(huì)根據(jù)元素的新屬性重新繪制洒扎,使元素呈現(xiàn)新的外觀辑甜。比如改變某個(gè)元素的背景色、文字顏色袍冷、邊框顏色等等

區(qū)別:

重繪不一定需要重排(比如顏色的改變)磷醋,重排必然導(dǎo)致重繪(比如改變網(wǎng)頁(yè)位置)

引發(fā)重排

  1. 添加、刪除可見(jiàn)的dom
  2. 元素的位置改變
  3. 元素的尺寸改變(外邊距难裆、內(nèi)邊距子檀、邊框厚度镊掖、寬高、等幾何屬性)
  4. 頁(yè)面渲染初始化
  5. 瀏覽器窗口尺寸改變
  6. 獲取某些屬性褂痰。當(dāng)獲取一些屬性時(shí)亩进,瀏覽器為取得正確的值也會(huì)觸發(fā)重排,它會(huì)導(dǎo)致隊(duì)列刷新,這些屬性包括:offsetTop缩歪、offsetLeft归薛、 offsetWidth、offsetHeight匪蝙、scrollTop主籍、scrollLeft、scrollWidth逛球、scrollHeight千元、clientTop、clientLeft颤绕、clientWidth幸海、clientHeight、getComputedStyle() (currentStyle in IE)奥务。所以物独,在多次使用這些值時(shí)應(yīng)進(jìn)行緩存

優(yōu)化方案

瀏覽器會(huì)維護(hù)1個(gè)隊(duì)列,把所有會(huì)引起重排氯葬,重繪的操作放入這個(gè)隊(duì)列挡篓,等隊(duì)列中的操作到一定數(shù)量或者到了一定時(shí)間間隔防楷,瀏覽器就會(huì)flush隊(duì)列寸五,進(jìn)行一批處理茶没,這樣多次重排坦报,重繪變成一次重排重繪

減少 reflow/repaint:

  1. 不要一條一條地修改 DOM 的樣式吝沫≈墒В可以先定義好 css 的 class鸣皂,然后修改 DOM 的className瞪讼。

  2. 不要把 DOM 結(jié)點(diǎn)的屬性值放在一個(gè)循環(huán)里當(dāng)成循環(huán)里的變量瞻坝。

  3. 為動(dòng)畫(huà)的 HTML 元件使用 fixed 或 absoult 的 position蛛壳,那么修改他們的 CSS 是不會(huì)reflow 的。

  4. 千萬(wàn)不要使用 table 布局所刀。因?yàn)榭赡芎苄〉囊粋€(gè)小改動(dòng)會(huì)造成整個(gè) table 的重新布局衙荐。(table及其內(nèi)部元素除外,它可能需要多次計(jì)算才能確定好其在渲染樹(shù)中節(jié)點(diǎn)的屬性浮创,通常要花3倍于同等元素的時(shí)間忧吟。這也是為什么我們要避免使用table做布局的一個(gè)原因。)

  5. 不要在布局信息改變的時(shí)候做查詢(會(huì)導(dǎo)致渲染隊(duì)列強(qiáng)制刷新)

1.9 事件循環(huán)(Event loop)

主線程從"任務(wù)隊(duì)列"中讀取執(zhí)行事件斩披,這個(gè)過(guò)程是循環(huán)不斷的溜族,這個(gè)機(jī)制被稱為事件循環(huán)

JavaScript 的事件分兩種

  1. 宏任務(wù):包括整體代碼 script讹俊,setTimeout,setInterval
  2. 微任務(wù):Promise.then(非 new Promise)煌抒,process.nextTick(node 中)

具體執(zhí)行:

事件的執(zhí)行順序——先執(zhí)行宏任務(wù)仍劈,然后執(zhí)行微任務(wù),任務(wù)有同步的任務(wù)和異步的任務(wù)寡壮,同步的進(jìn)入主線程贩疙,異步的進(jìn)入 Event Table 并注冊(cè)函數(shù),異步事件完成后况既,會(huì)將回調(diào)函數(shù)放在隊(duì)列中这溅,如果還有異步的宏任務(wù),那么就會(huì)進(jìn)行循環(huán)執(zhí)行上述的操作

主 線程會(huì)不斷從任務(wù)隊(duì)列中按順序取任務(wù)執(zhí)行棒仍,每執(zhí)行完一個(gè)任務(wù)都會(huì)檢查microtask隊(duì)列是否為空(執(zhí)行完一個(gè) 任務(wù)的具體標(biāo)志是函數(shù)執(zhí)行棧為空)悲靴,如果不為空則會(huì)一次性執(zhí)行完所有microtask。然后再進(jìn)入下一個(gè)循環(huán)去 任務(wù)隊(duì)列中取下一個(gè)任務(wù)執(zhí)行

詳細(xì)步驟

  1. 選擇當(dāng)前要執(zhí)行的宏任務(wù)隊(duì)列莫其,選擇一個(gè)最先進(jìn)入任務(wù)隊(duì)列的宏任務(wù)对竣,如果沒(méi)有宏任務(wù)可以選擇,則會(huì) 跳轉(zhuǎn)至microtask的執(zhí)行步驟榜配。

  2. 將事件循環(huán)的當(dāng)前運(yùn)行宏任務(wù)設(shè)置為已選擇的宏任務(wù)。

  3. 運(yùn)行宏任務(wù)吕晌。

  4. 將事件循環(huán)的當(dāng)前運(yùn)行任務(wù)設(shè)置為null蛋褥。

  5. 將運(yùn)行完的宏任務(wù)從宏任務(wù)隊(duì)列中移除。

  6. microtasks步驟:進(jìn)入microtask檢查點(diǎn)睛驳。

  7. 更新界面渲染烙心。

  8. 返回第一步。

執(zhí)行進(jìn)入microtask檢查的的具體步驟如下:

  1. 設(shè)置進(jìn)入microtask檢查點(diǎn)的標(biāo)志為true乏沸。
  2. 當(dāng)事件循環(huán)的微任務(wù)隊(duì)列不為空時(shí):選擇一個(gè)最先進(jìn)入microtask隊(duì)列的microtask淫茵;設(shè)置事

件循環(huán)的當(dāng) 前運(yùn)行任務(wù)為已選擇的microtask;運(yùn)行microtask蹬跃;設(shè)置事件循環(huán)的當(dāng)前運(yùn)行任務(wù)

為null匙瘪;將運(yùn)行結(jié)束 的microtask從microtask隊(duì)列中移除。

  1. 對(duì)于相應(yīng)事件循環(huán)的每個(gè)環(huán)境設(shè)置對(duì)象(environment settings object),通知它們哪些

promise為 rejected蝶缀。

  1. 清理indexedDB的事務(wù)丹喻。
  2. 設(shè)置進(jìn)入microtask檢查點(diǎn)的標(biāo)志為false。

注意

當(dāng)前執(zhí)行棧執(zhí)行完畢時(shí)會(huì)立刻先處理所有微任務(wù)隊(duì)列中的事件,然后再去宏任務(wù)隊(duì)列中取出一個(gè)事件翁都。同一次事件循環(huán)中,微任務(wù)永遠(yuǎn)在宏任務(wù)之前執(zhí)行

1.10 let a = 1 掛載在哪里碍论?

var a 掛載在window下。而let是掛載在 全局函數(shù)下面

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末柄慰,一起剝皮案震驚了整個(gè)濱河市鳍悠,隨后出現(xiàn)的幾起案子税娜,更是在濱河造成了極大的恐慌,老刑警劉巖藏研,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件敬矩,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡遥倦,警方通過(guò)查閱死者的電腦和手機(jī)谤绳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)袒哥,“玉大人缩筛,你說(shuō)我怎么就攤上這事”こ疲” “怎么了瞎抛?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)却紧。 經(jīng)常有香客問(wèn)我桐臊,道長(zhǎng),這世上最難降的妖魔是什么晓殊? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任断凶,我火速辦了婚禮,結(jié)果婚禮上巫俺,老公的妹妹穿的比我還像新娘认烁。我一直安慰自己,他們只是感情好介汹,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布却嗡。 她就那樣靜靜地躺著,像睡著了一般嘹承。 火紅的嫁衣襯著肌膚如雪窗价。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,554評(píng)論 1 305
  • 那天叹卷,我揣著相機(jī)與錄音撼港,去河邊找鬼。 笑死豪娜,一個(gè)胖子當(dāng)著我的面吹牛餐胀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瘤载,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼否灾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了鸣奔?” 一聲冷哼從身側(cè)響起墨技,我...
    開(kāi)封第一講書(shū)人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤惩阶,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后扣汪,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體断楷,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年崭别,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了冬筒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡茅主,死狀恐怖舞痰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情诀姚,我是刑警寧澤响牛,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站赫段,受9級(jí)特大地震影響呀打,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜糯笙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一贬丛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧给涕,春花似錦瘫寝、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)咪啡。三九已至首启,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間撤摸,已是汗流浹背毅桃。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留准夷,地道東北人钥飞。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像衫嵌,于是被迫代替她去往敵國(guó)和親读宙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

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