前端面試技巧與技術棧準備梳理

前言

這個是我以前看前端跳槽面試必備技巧這個系列視頻整理的一個筆記,其中還有一些內容沒有細化,會持續更新細化內容。比較短的就會直接寫在下面,長一點的就單獨寫篇文章。css

說實話,這個大佬真的講的挺好的,尤爲是對原型和繼承那一塊講的通俗易懂。有些店以前看視頻的時候看不懂或者沒有在乎,其實仍是有蠻多點可挖的,我也還會針對一些沒太吃透的點重點再寫文章記錄。html

1.面試準備

1.1 對職位描述的分析
  • 首先要逐條讀懂職位描述中對崗位能力的要求,在真實的面試投遞以前經過這個分析首先就能夠知道要面試的這個崗位與本身能力的匹配程度,不過平時根據本身的目標薪資瀏覽崗位描述時就必定要細化本身具體哪一個點不足,以及如何補上或者提升相應能力。
  • 具體來講崗位描述分爲基礎能力和難度點
  • 職位描述的目的一個是快速識別這個崗位是否是本身喜歡的是否是本身想要的,二個是我能不能勝任這個崗位或者說通過準備短時間內hold住這個崗位
  • 具有前端工程化知識已經成爲一名合格前端的基本要求,具體到技術就是要了解並使用過==webpack、grunt、gulp、sass、less==這幾個。
1.2 針對目標公司的技術棧分析
  • 能夠拿目標網站的源碼分析,能夠看到他們大致上用到了一些什麼技術棧,對於那些本身徹底沒接觸過的點必定要重點了解。

2.根據常見面試題梳理知識體系

2.1 頁面佈局

例子:假設高度已知,請寫出三欄佈局,其中左右欄寬度都是300px,中間自適應前端

  • 這個問題目前就我已知的有五種解決方案:
html * {
    margin: 0; 
    padding: 0;
}
.layout .item {
    height: 100px;
} 
.layout {
    margin-bottom: 30px;
}
  • 浮動佈局
<!-- 浮動佈局 -->
  <section class="layout float">
      <style>
          .layout.float .left {
              float: left;
              width: 300px;
              background-color: #555;
              margin-right: 10px;
          }
          .layout.float .center {
              background-color: #777;
          }
          .layout.float .right {
              float: right;
              width: 300px;
              background-color: #999;
          }
      </style>
      <article class="left_center_right">
          <div class="item left"></div>
          <div class="item right"></div>
          <div class="item center">
              <h2>浮動佈局</h2>
              <p>這是浮動佈局的內容</p>
          </div>
      </article>
  </section>
  • 相對定位
<!-- 絕對佈局 -->
  <section class="layout absolute">
      <style>
          .layout.absolute .left_center_right .item {
              position: absolute;
          }
          .layout.absolute .left {
              left: 0;
              width: 300px;
              background-color: #555;
          }
          .layout.absolute .center {
              left: 300px;
              right: 300px;
              background-color: #777;
              padding-left: 10px;
          }
          .layout.absolute .right {
              right: 0;
              width: 300px;
              background-color: #999;
          }
      </style>
      <article class="left_center_right">
          <div class="item left"></div>
          <div class="item center">
              <h2>絕對佈局</h2>
              <p>這是絕對定位佈局的內容</p>
              <p>這是絕對定位佈局的內容</p>
              <p>這是絕對定位佈局的內容</p>
          </div>
          <div class="item right"></div>
      </article>
  </section>
  • flx佈局 (http://www.runoob.com/w3cnote/flex-grammar.html)
    • 如下6個屬性設置在容器上
      • flex-direction (flex-direction屬性決定主軸的方向(即項目的排列方向)
        • row(默認值):主軸爲水平方向,起點在左端
        • row-reverse:主軸爲水平方向,起點在右端
        • column:主軸爲垂直方向,起點在上沿。
        • column-reverse:主軸爲垂直方向,起點在下沿。
      • flex-wrap
        • nowrap(默認):不換行
        • wrap:換行,第一行在上方
        • wrap-reverse:換行,第一行在下方。
      • flex-flow
        • flex-flow屬性是flex-direction屬性和flex-wrap屬性的簡寫形式,默認值爲row nowrap。
      • justify-content (justify-content屬性定義了項目在主軸上的對齊方式)
        • flex-start(默認值):左對齊
        • flex-end:右對齊
        • center: 居中
        • space-between:兩端對齊,項目之間的間隔都相等。
        • space-around:每一個項目兩側的間隔相等。因此,項目之間的間隔比項目與邊框的間隔大一倍。
      • align-items
        • flex-start:交叉軸的起點對齊。
        • flex-end:交叉軸的終點對齊
        • center:交叉軸的中點對齊
        • baseline: 項目的第一行文字的基線對齊
        • stretch(默認值):若是項目未設置高度或設爲auto,將佔滿整個容器的高度
      • align-content (定義了多根軸線的對齊方式。若是項目只有一根軸線,該屬性不起做用) 豎直方向的
        • flex-start:與交叉軸的起點對齊。
        • flex-end:與交叉軸的終點對齊。
        • center:與交叉軸的中點對齊。
        • space-between:與交叉軸兩端對齊,軸線之間的間隔平均分佈。
        • space-around:每根軸線兩側的間隔都相等。因此,軸線之間的間隔比軸線與邊框的間隔大一倍。
        • stretch(默認值):軸線佔滿整個交叉軸。
    • 如下6個屬性設置在項目上
      • order (order屬性定義項目的排列順序。數值越小,排列越靠前,默認爲0)
      • flex-grow (flex-grow屬性定義項目的放大比例,默認爲0,即若是存在剩餘空間,也不放大)
      • flex-shrink (flex-shrink屬性定義了項目的縮小比例,默認爲1,即若是空間不足,該項目將縮小)
      • flex-basis: | auto; /* default auto */ (項目佔據的主軸空間)
      • flex flex屬性是flex-grow, flex-shrink 和 flex-basis的簡寫,默認值爲0 1 auto。後兩個屬性可選
      • align-self: auto | flex-start | flex-end | center | baseline | stretch; (align-self屬性容許單個項目有與其餘項目不同的對齊方式,可覆蓋align-items屬性。默認值爲auto,表示繼承父元素的align-items屬性,若是沒有父元素,則等同於stretch)
      <!-- flexbox 佈局 -->
      <section class="layout flexbox">
        <style>
            .layout.flexbox {
                margin-top: 160px;
            }
            .layout.flexbox .left_center_right  {
                display: flex;
                display: -webkit-flex;
            }
            .layout.flexbox .left {
                width: 300px;
                background-color: #555;
            }
            .layout.flexbox .center {;
                background-color: #777;
                flex: 1;
                padding-left: 10px;
            }
            .layout.flexbox .right {
                width: 300px;
                background-color: #999;
            }
        </style>
        <article class="left_center_right">
            <div class="item left"></div>
            <div class="item center">
                <h2>flex佈局</h2>
                <p>這是flex佈局的內容</p>
                <p>這是flex佈局的內容</p>
                <p>這是flex佈局的內容</p>
            </div>
            <div class="item right"></div>
        </article>
      </section>
  • table佈局
<!-- table 佈局 -->
  <section class="layout table">
      <style>
          .layout.table .left_center_right {
              width: 100%;
              height: 100px;
              display: table;
          }
          .layout.table .left_center_right .item {
              display: table-cell;
          }
          .layout.table .left {
              width: 300px;
              background-color: #555;
          }
          .layout.table .center {;
              background-color: #777;
              padding-left: 10px;
          }
          .layout.table .right {
              width: 300px;
              background-color: #999;
          }
      </style>
      <article class="left_center_right">
          <div class="item left"></div>
          <div class="item center">
              <h2>table佈局</h2>
              <p>這是table佈局的內容</p>
              <p>這是table佈局的內容</p>
              <p>這是table佈局的內容</p>
          </div>
          <div class="item right"></div>
      </article>
  </section>
  • grid網格佈局
    • 目前瀏覽器基本上默認不支持,不過多是將來的一種網頁佈局方式
    • 開啓瀏覽器grid模塊功能 (https://www.w3cplus.com/css3/how-to-enable-support-for-grid-layout-in-various-browsers.html
    • grid-template-columns: 設置行的寬度
    • grid-template-rows: 設置列的高度webpack

      <!-- 網格 佈局 -->
      <section class="layout grid">
        <style>
            .layout.grid .left_center_right {
                width: 100%;
                height: 100px;
                display: grid;
                grid-template-columns: 300px auto 300px;
                grid-template-rows: 100px;
            }
            .layout.grid .left {
                width: 300px;
                background-color: #555;
            }
            .layout.grid .center {;
                background-color: #777;
                padding-left: 10px;
            }
            .layout.grid .right {
                width: 300px;
                background-color: #999;
            }
        </style>
        <article class="left_center_right">
            <div class="item left"></div>
            <div class="item center">
                <h2>網格佈局</h2>
                <p>這是grid佈局的內容</p>
                <p>這是grid佈局的內容</p>
                <p>這是grid佈局的內容</p>
            </div>
            <div class="item right"></div>
        </article>
      </section>
  • 寫代碼時要注意幾點:
    • 使用標籤時要儘可能使用語義化標籤,不要通篇div
    • 注意縮進與書寫的規範化
  • 知道這幾種解決方案以後還要思考幾個問題:
    • 他們各自的優缺點,經過比較這幾種佈局方式的不一樣來在實際開發中知道如何取捨,好比常見的移動端的上下高度固定,中間高度自適應等。
    • 在實際開發中會優先選擇哪一種解決方案
    • 當高度不固定時又要如何處理
2.2 CSS盒模型
  • 基本概念:標準模型 + IE模型
  • 標準模型和IE模型的區別
    • 兩種盒模型都包含content,padding,border,margin這四個部分,不一樣在與標準模型是將content的寬度和高度計算爲盒子的寬度與高度,而IE模型是將content、padding與border之和計算爲盒子的寬度與高度
  • CSS如何設置這兩種模型
    • box-sizing: content-box (標準模型,默認方式)
    • box-sizing:border-box (IE模型)
  • JS如何設置獲取盒模型對應的寬和高
    • dom.style.width/height (這種方法只能取到內聯樣式中聲明的寬或者高)
    • dom.currentStyle.width/height (這種方法獲得的是渲染以後的準確結果,可是隻有IE支持)
    • window.getComputedStyle(dom).width/height (兼容性更好,可以兼容FF和Chrom)
    • dom.getBoundingClientRect().width/height (可以計算元素的絕對位置,同時也能得到寬高)
  • 實例題(根據盒模型解釋邊距重疊)
  • BFC (邊距重疊解決方案)
    • BFC的基本概念 (塊級隔離化上下文)
    • BFC的渲染規則
      • 在BFC的垂直方向的邊距會發生重疊
      • BFC的區域不會與浮動元素的BOX重疊
      • BFC在頁面上是一個獨立的容器,容器內與外的元素不會相互影響
      • 計算BFC元素高度時浮動元素也會被計算進去
    • 如何建立BFC
      • float值不爲none
      • position的值不是stastic或者reletice
      • overflow
      • table
    • BFC的使用場景
2.3 DOM事件類
  • 基本概念:DOM事件的級別
    • 事件級別
    - DOM0:   element.onclick=function(){} 
    - DOM1:   element.addEventListener('click',function(){},false)
    - DOM3:   element.addEventListener('keyup',function(){},false) (增長了不少事件)
  • DOM事件模型 (捕獲和冒泡)
  • DOM事件流 (從捕獲階段到目標階段再到冒泡階段)
    • 捕獲階段 (最後那個參數默認是false,是冒泡階段的,設爲true就是捕獲階段的)
    window:  
    window.addEventListener('click', function(){
      console.log('window');
    }, true)
    document:
    document.addEventListener('click', function(){
              console.log('document');
          }, true)
    html:
    document.documentElement.addEventListener('click', function(){
              console.log('html');
          }, true)
    body:
    document.body.addEventListener('click', function(){
              console.log('body');
          }, true)
  • 描述DOM事件捕獲的具體流程
    • window --> document --> html -->body --> ... -->具體元素
    • 獲取document:document.documentElement
  • Event對象的常見應用
- event.preventDefault()  阻止默認事件
- event.stopProgation()  阻止冒泡
- event.stopImmediateProgation()    設定事件響應優先級
- event.currentTarget  當前所綁定的事件
- event.targe  當前被點擊的元素
  • 自定義事件
例如:自定義一個自定義事件'custome'
var eve=new Event('custome');
ev.addEventListener('custom',function(){
  console.log('custome');  
})
ev.dispatchEvent(eve);
2.4 HTTP協議類
  • HTTP協議的主要特色
    • 簡單快速 (URL是固定的)
    • 靈活 (經過一個HTTP協議就能完成不一樣數據類型的傳輸)
    • 無鏈接 (鏈接一次就會斷掉)
    • 無狀態 (屢次鏈接是無狀態的)
  • HTTP報文的組成部分
    • 請求報文(請求行,請求頭,空行,請求體)
    • 響應報文(狀態行,響應頭,空行,響應體)
  • HTTP方法
    • GET、POST、PUT、DELETE、HEAD(得到報文頭部)
  • POST和GET的區別
    • GET在瀏覽器回退時時無害的,而POST會再次請求
    • GET產生的URL地址是能夠被收藏,而POST不能夠
    • GET請求會被瀏覽器主動緩存,而POST不會,除非手動設置
    • GET請求只能進行URL編碼,而POST支持多種編碼方式
    • GET請求參數會被完整地保留在瀏覽器歷史記錄了,而POST請求不會被保留
    • GET請求在URL中傳送的參數是有長度限制的,而POST請求沒有限制
    • 對參數數據類型,GET只接受ASCII字符,而POST沒有限制
    • GET比POST更不安全,由於參數直接暴露在URL上,因此不能用來傳遞敏感信息
    • GET參數經過URL傳遞,POST放在Request body中
  • HTTP狀態碼
    • 1xx:提示信息-表示請求已接收,繼續處理
    • 2xx:成功-表示請求已被成功接收
    • 3xx:重定向-要完成請求必須進行更進一步操做
    • 4xx:客戶端錯誤-請求有語法錯誤或者請求沒法實現
    • 5xx:服務器錯誤-服務器未能實現合法的請求
  • 什麼是持久鏈接 (keep-alive)
  • 什麼是管線化 (通道是持久創建的,先發送幾個請求,再同時返回這幾個請求的結果)
    • 管線化經過持久鏈接完成,進HTTP1.1支持此技術
    • 只有GET和HEAD請求能夠管線化,而POST有所限制
    • 管線化不會影響響應到來的順序css3

      2.5 原型鏈
  • 建立對象有幾種方法nginx

    // 第一種很方式:字面量
      var o1 = {name: 'o1'};
      var o11 = new Object({name: 'o11'});
      // 第二種方式:經過構造函數
      var M = function(){
          this.name = 'o2';
      }
      var o2 = new M();
      // 第三種方式:Object,create
      var P = {name: 'o3'};
      var o3 = Object.create(P);
  • 原型、構造函數、實例、原型鏈
    • 任何函數均可以做爲構造函數,只要被new了,就是一個構造函數
    • 每一個函數都有一個prototype屬性,這個是生成函數時自動加上的,函數的這個prototype屬性指向的就是函數的原型對象
    M的原型對象:M.prototype
    • 每一個原型對象都有一個constructor構造器,這個屬性指向的就是引用的那個構造函數,也就是聲明這個原型對象的函數
    M.prototype.constructor === M
    任意一個實例對象o2
    o2.__proto__.constructor === M
    這個能夠用來判斷實例對象的構造函數
    • 每一個對象都有一個__proto__屬性,這個屬性指向的是這個的對象的構造函數的的原型對象,也就是說一個實例對象的原型是等於它的構造函數的原型對象
    o2.__proto__ === M.prototype
    • ~~原型鏈:所謂原型鏈就是從一個實例對象向上找,經過查找實例對象的構造函數的原型對象向上找,而後找原型對象的構造函數的原型對象,一直找到構造函數爲Object時終止,由於 **Object.prototype.__proto__===null**; 這樣就造成了一個原型鏈~~
    • 原型鏈:從一個對象上獲取某一個屬性或者方法時,若是這個對象自己不具有這個屬性或者方法,那就會從這個對象的構造函數的原型對象上去找,若是還沒找到就會從構造函數的構造函數上去找,直到找到構造函數爲Object時終止,由於**Object.prototype.__proto__===null**,這樣造成的一個鏈條就叫原型鏈。
    原型鏈的頂端是Object.prototype這個原型對象的原型Object.prototype.__proto__爲空
  • instanceof原理
    • 判斷一個實例對象的instanceof究竟是不是一個構造函數時實際上判斷的是實例對象的__proto__屬性是否跟這個構造函數的prototype屬性相等,在上面的例子中,就是:o2 instanceof M爲true,由於o2.__proto__ === M.prototype
    • 而且,只要是在 這個原型鏈上的構造函數,都會等於這個實例對象的instanceof屬性,例如:o2 instanceof M毫無疑問是true的,同時o2 instanceof Object也是true的,由於M.prototype.__proto__ === Object.prototype,Object是在o2的原型鏈上的一個構造函數
    • 那怎麼嚴謹地判斷一個實例對象是否是一個構造函數的實例對象呢,須要用constructor,例如:o2.__proto__.constructor === M,就能夠肯定M是o2的構造函數了
  • new 運算符
var new2 = function(func){
    var o = Object.create(func.prototype);
    var k = func.call(o);
    if (typeof k === 'object') {
        return k
    }else{
        return o
    }
}
o6 = new2(M); 這個就等價於對構造函數M實例化了一個實例對象
2.6 面向對象類
  • 類與實例
    • 類的聲明
    /*類的聲明*/ 
      function Animal () {
          this.name = 'name';
      }
      /*ES6中的類的聲明*/ 
      class Animal2 {
          constructor (name) {
              this.name = name;
          }
      }
    • 生成實例
    /*實例化類的對象*/ 
      console.log(new Animal(), new Animal2())
  • 類與繼承
    • 如何實現繼承
      • 構造函數(call() 和apply(方法))
      • 原型鏈
    • 繼承的幾種方式
      • 藉助構造函數實現繼承
      /*藉助構造函數實現繼承*/ 
      function Parent1 () {
          this.name = 'parent1';
      }
      function Child1 () {
          Parent1.call(this);  //就是將Child1運行在Parent1的上下文環境裏
          // Parent1.apply(this, []);   //另外一中寫法
          this.type = 'child1';
      }
      console.log(new Child1)
      • 利用原型鏈實現繼承
      /*利用原型鏈實現繼承*/ 
      function Parent2 () {
          this.name = 'parent2';
          this.play = [1,2,3];
      }
      function Child2 () {
          this.type = 'child2';
      }
      Parent2.prototype.say = function () {console.log('hello')};
      Child2.prototype = new Parent2();  //實際上這個方法就是至關於把Parent2的原型鏈嫁接到了Child2上,因此子級能經過原型鏈訪問到父級的方法了
      console.log(new Child2());   //  (new Child2()).__proto__ === Child2.prototype = new Parent2(),因此子集實例的原型鏈指向的是父級的一個實例
      var s1 = new Child2();
      var s2 = new Child2();
      s1.play.push(7);
      console.log(s1.play, s2.play);  //他們永遠會是相等的,由於他們指向的地址是同樣的,他們的原型對象是同樣的,s1.__proto__===s2.__proto__
      • 組合方式
      /*組合方式*/
      function Parent3 () {
          this.name = 'parent3';
          this.play = [1,2,3];
      }
      function Child3 () {
          Parent3.call(this);
          this.type = 'child3';
      }
      Child3.prototype = new Parent3();   //構造函數Parent3執行了兩次,有一次是多餘的
      var s3 = new Child3();
      var s4 = new Child3();
      s3.play.push(6);
      console.log(s3, s4)
      • 組合方式優化1
      /*組合方式優化1*/
      function Parent4 () {
          this.name = 'parent4';
          this.play = [1,2,3];
      }
      function Child4 () {
          Parent4.call(this);
          this.type = 'child4';
      }
      Child4.prototype = Parent4.prototype;   //這樣構造函數Parent4就只執行了一次
      console.log(Parent4.prototype)
      var s5 = new Child4();
      var s6 = new Child4();
      var s6_ = new Parent4();
      console.log(s5 instanceof Child4, s5 instanceof Parent4);
      console.log(s5.constructor);
      console.log(s6_.constructor); //都指向了構造函數Parent4
      • 組合方式優化2 (比較完美的解決方案)
      /*組合方式優化2*/
      // 這種優化方式是爲了解決沒法分辨父級和子級的實例對象的問題,也就是說父級和子級的實例對象都指向了同一個原型對象
      function Parent5 () {
          this.name = 'parent5';
          this.play = [1,2,3];
      }
      function Child5 () {
          Parent5.call(this);
          this.type = 'child5';
      }
      Child5.prototype = Object.create(Parent5.prototype);   //至關於建立了一個空的中間對象,這樣的話子級構造函數的原型對象不是簡單地與父級構造函數的原型函數相等了,而是先等於一個空的中間對象,再對這個中間的對象進行賦值
      Child5.prototype.constructor = Child5;  //這一步實際上就是作的賦值,固然沒有上面那步讓子級的構造函數的原型對象先等於一個空對象的話仍是沒法將他們分開的
      var s7 = new Child5();
      var s8 = new Child5();
      var s9 = new Parent5();
      console.log(s7 instanceof Child5, s8 instanceof Parent5)
      console.log(s7.constructor)
      console.log(s9.constructor)
      2.7 通訊類
  • 什麼是同源策略及限制
    • 協議、域名、端口這三個構成了一個源,這三個之中有一個不同就是源不同了,就是跨域了。因此不是同一個源是不能操做同源的文件
    • Cookie、LocalStorage、和indexDB沒法讀取
    • DOM沒法得到
    • AJAX請求不能發送
  • 先後端如何通訊
    • Ajax (受同源策略限制)
    • WebSocket (不受同源策略限制)
    • CORS (支持跨域通訊,也支持同源通訊)
  • 如何建立Ajax
  • 跨域通訊的幾種方式
    • JSONP
      • 原理:利用js、css,img等標籤能夠加載跨域資源的原理,動態建立script標籤,再請求一個帶參網址實現跨域通訊。
      • 缺點:只能實現get請求
    • 跨域資源共享(CORS)
      • 原理:普通跨域請求:只服務端設置Access-Control-Allow-Origin便可,前端無須設置,若要帶cookie請求:先後端都須要設置。(withCredentials)
    • nginx代理跨域
      • 原理:同源策略是瀏覽器的安全策略,不是HTTP協議的一部分,服務器端調用HTTP接口只是使用HTTP協議,不會執行JS腳本,不存在同源策略,也就不存在跨域問題。
    • Nodejs 中間件代理
      • 原理大體與nginx相同,都是經過啓一個代理服務器,實現數據的轉發
    • WebSocket協議跨域
      • 原理:WebSocket protocol是HTML5一種新的協議。它實現了瀏覽器與服務器全雙工通訊,同時容許跨域通信
    • document.domain + iframe跨域
      • 原理:此方案僅限主域相同子域不一樣的的跨域場景。兩個頁面都經過js強制設置document.domain爲基礎主域,就實現了同域。
    • location.hash + iframe跨域
      • 原理:a域與b跨域相互通訊,經過中間頁c來實現。三個頁面,不一樣域之間利用iframe的location.hash傳值,相同域之間直接js訪問來通訊。
    • window.name + iframe跨域
      • 原理:window.name屬性的獨特之處:name值在不一樣的頁面(甚至不一樣域名)加載後依舊存在,而且能夠支持很是長的 name 值(2MB)
    • postMessage跨域 (H5中新增的)
      • 原理:postMessage是HTML5 XMLHttpRequest Level 2中的API,且是爲數很少能夠跨域操做的window屬性之一
2.8 安全類
  • CSRF
    • 基本概念:跨站請求僞造
    • 特色是用戶必定在註冊網址登陸過
    • 被攻擊網站自己存在漏洞
    • 防護措施:
      • Token驗證
      • Referer驗證
      • 隱藏令牌
  • XSS
    • 基本概念:跨域腳本攻擊
2.9 渲染機制類
  • 什麼是DOCTYPE及做用
    • 說白了就是告訴瀏覽器文檔類型
  • 瀏覽器的簡要渲染過程
    • 解析HTML-->構建DOM樹(DOM Tree)
    • 加載樣式-->解析樣式-->構建樣式規則樹(CSS Tree)
    • 加載js-->執行js代碼
    • 把DOM樹和樣式規則樹匹配構建渲染樹(Render Tree)
    • 計算元素進行佈局 (Layout)
    • 繪製 (Paiting)
  • 圖片記載和渲染的時機
    • 解析HTML【遇到標籤加載圖片】-->構建DOM樹
    • 加載樣式-->解析樣式 【遇到背景圖片連接不加載】-->構建樣式規則樹
    • 加載js-->執行js代碼
    • 把DOM樹和樣式規則樹匹配構建渲染樹【加載渲染樹上的背景圖片】
    • 計算元素位置進行佈局
    • 繪製【開始渲染圖片】
  • 設置了display:none屬性的元素,圖片會加載,但不會渲染出來,而這個設置了display:none的子元素不會渲染,也不會加載。 https://mp.weixin.qq.com/s?__biz=MzAwNjI5MTYyMw%3D%3D&mid=2651494431&idx=1&sn=ab0f92186e44c8e4575c9c0c831ad6cc&chksm=80f191d7b78618c11a4489b39af45e3279f5248843d2b05804aebecc13678a45432116260e03
  • 瀏覽器渲染過程
    • Create/Update DOM And request css/image/js:瀏覽器請求到HTML以後,生成DOM樹,並同時請求相應的CSS,js文件
    • Create/Update Render CSSOM:CSS文件下載完成,開始構建CSSOM
    • Create/Update Render Tree:CSSOM樹構建完以後和DOM一塊兒生成Render Tree
    • Layout: 瀏覽器根據render tree上各個節點的樣式信息計算各個點在屏幕中的位置
    • Painting:按照計算出來的規則,經過顯卡,把內容畫到屏幕上
  • 重排Reflow
    • 定義:瀏覽器根據各類樣式計算記過將各類DOM元素放到它該出現的位置,這個過程就是Reflow
    • 觸發條件:
      • 增長、刪除、修改DOM節點,繪致使Reflow或Repaint
      • 移動DOM位置或者動畫
      • 修改CSS樣式
      • Resize窗口或者滾動的時候
      • 修改網頁的默認字體時
  • 重繪Repaint
    • 定義:頁面要呈現的內容通通畫在屏幕上
    • 觸發:
      • DOM改動
      • CSS改動
  • 佈局Layout
2.10 運行機制類
  • JS是單線程的,從上到下執行,可是任務又分爲同步任務和異步任務,繪先執行同步任務,把異步任務先掛起,等同步任務完成了再執行異步任務
  • 同步人物和異步任務的優先關係
console.log(1);
setTimeout(function(){
  console.log(2)
}, 0)
console.log(3);
打印順序是:1,3,2,由於setTimeout是異步任務
console.log('A');
setTimeout(function(){
  console.log('C');
},0)
while(1){
  console.log(5)    
}
console.log('B');
會輸出:A; 由於while是一個同步任務,會優先執行這個任務,可是這個while循環是一個死循環,會一直陷在循環中,那後面的打印和定時器的異步任務都不會執行了
  • 異步對壘執行時間:瀏覽器有一個time模塊,專門識別setTimeou和setInterval,當遇到這兩種方法時會先將他們掛起,等到時間到了,纔會放到異步隊列中去執行
for (var i = 0; i < 4; i++) {
  setTimeout(function(){
    console.log(i);
  },1000)
}
輸出結果: 4個4
  • 如何理解JS的單線程
    • 一個時間以內JS只能幹一件事
  • 什麼是任務隊列
    • 分爲同步任務和異步任務,異步任務後於同步任務執行
  • 什麼是EventLoop
  • 異步任務
    • setTimeout和setInterval
    • DOM事件
    • ES6中的promise
2.11 頁面性能類
  • 資源壓縮合並,減小HTTP請求
  • 非核心代碼異步加載
    • 異步加載的方式
      • 動態腳本加載
      • defer
      • async
    • 異步加載的區別
      • defer是在HTML解析完以後纔會執行,若是是多個,按照加載的順序依次執行
      • async實在加載完以後當即執行,若是是多個,執行順序和加載順序無關
  • 利用瀏覽器緩存
    • 緩存的分類
      • 強緩存:相對時間、絕對時間
      • 協商緩存
    • 緩存的原理
  • 使用CDN
  • 預解析DNS
<meta http-equiv="x-dns-prefetch-control" content="on">
這句話是說在https協議下默認強制讓頁面上全部的a標籤也能夠DNS預解析
<link rel="dns-prefetch" href="..">
針對某一個域名DNS預解析
相關文章
相關標籤/搜索