辣些經(jīng)典的web前端面試題

前記

啊侥猩,快樂的時(shí)光總是很短暫。
2017年的第一場面試抵赢,比想的要更早些 :-D
好呢欺劳!總有辣么幾個(gè)問題,面試總要問铅鲤!
嘛划提!想起幾個(gè)總結(jié)幾個(gè),答案肯定不標(biāo)準(zhǔn)邢享,隨時(shí)改鹏往,基本就是這樣。

談一談對性能優(yōu)化的認(rèn)識(shí)骇塘?

前端優(yōu)化的途徑有很多,大致可以分為兩類伊履,第一類是頁面級別的優(yōu)化,例如 HTTP請求數(shù)款违、腳本的無阻塞加載唐瀑、內(nèi)聯(lián)腳本的位置優(yōu)化等 ;第二類則是代碼級別的優(yōu)化,例如 Javascript中的DOM 操作優(yōu)化奠货、CSS選擇符優(yōu)化介褥、圖片優(yōu)化以及 HTML結(jié)構(gòu)優(yōu)化等等座掘。

  • 頁面級優(yōu)化
    1. 減少http請求次數(shù)递惋。
      大部分響應(yīng)時(shí)間花在下載網(wǎng)頁內(nèi)容(images柔滔,stylesheets,javascript萍虽,script睛廊,flash等)。減少次數(shù)是縮短響應(yīng)時(shí)間的關(guān)鍵杉编!可以通過簡化頁面設(shè)計(jì)來減少請求次數(shù)超全,但頁面內(nèi)容比較多的時(shí)候可以采用以下技巧:
    2. 從設(shè)計(jì)實(shí)現(xiàn)層面簡化頁面
      保持頁面簡潔、減少資源的使用是最直接的邓馒。
    3. 合理設(shè)置 HTTP 緩存
      原則很簡單嘶朱,能緩存越多越好,能緩存越久越好光酣。
      HTTP 緩存的四種風(fēng)味與緩存策略
    4. 資源合并與壓縮
      如果可以的話疏遏,盡可能的將外部的腳本、樣式進(jìn)行合并救军,多個(gè)合為一個(gè)财异。另外, CSS唱遭、 Javascript戳寸、Image 都可以用相應(yīng)的工具進(jìn)行壓縮,壓縮后往往能省下不少空間拷泽。
    5. css sprites
      合并 CSS圖片疫鹊,減少請求數(shù)的又一個(gè)好辦法。
    6. inline images(不是很了解這個(gè))
    7. Lazy Load Images
    8. 將外部腳本置底
    9. 異步執(zhí)行 inline 腳本
    10. Lazy Load Javascript
    11. 將 css 放在 head 中
    12. 異步請求 callback
    13. 減少不必要的 HTTP 跳轉(zhuǎn)
    14. 避免重復(fù)的資源請求
  • 代碼級優(yōu)化
    1. Javascript
        1. DOM
        DOM操作應(yīng)該是腳本中最耗性能的一類操作跌穗,例如增加订晌、修改、刪除 DOM元素或者對 DOM集合進(jìn)行操作蚌吸。如果腳本中包含了大量的 DOM 操作則需要注意以下幾點(diǎn):
         1. HTML Collection(HTML收集器锈拨,返回的是一個(gè)數(shù)組內(nèi)容信息)
         在腳本中 document.images、document.forms 羹唠、getElementsByTagName()返回的都是 HTMLCollection類型的集合奕枢,在平時(shí)使用的時(shí)候大多將它作為數(shù)組來使用,因?yàn)樗?length屬性佩微,也可以使用索引訪問每一個(gè)元素缝彬。不過在訪問性能上則比數(shù)組要差很多,原因是這個(gè)集合并不是一個(gè)靜態(tài)的結(jié)果哺眯,它表示的僅僅是一個(gè)特定的查詢谷浅,每次訪問該集合時(shí)都會(huì)重新執(zhí)行這個(gè)查詢從而更新查詢結(jié)果。所謂的 “訪問集合” 包括讀取集合的 length屬性、訪問集合中的元素一疯。
         因此撼玄,當(dāng)你需要遍歷 HTML Collection的時(shí)候,盡量將它轉(zhuǎn)為數(shù)組后再訪問墩邀,以提高性能掌猛。即使不轉(zhuǎn)換為數(shù)組,也請盡可能少的訪問它眉睹,例如在遍歷的時(shí)候可以將 length屬性荔茬、成員保存到局部變量后再使用局部變量。
         2. Reflow & Repaint(不是很了解)
         除了上面一點(diǎn)之外竹海, DOM操作還需要考慮瀏覽器的 Reflow 和 Repaint 慕蔚,因?yàn)檫@些都是需要消耗資源的。
        2. 慎用 with(不了解)
      with(obj){ p = 1};
      代碼塊的行為實(shí)際上是修改了代碼塊中的執(zhí)行環(huán)境 斋配,將obj放在了其作用域鏈的最前端坊萝,在 with 代碼塊中訪問非局部變量是都是先從 obj 上開始查找,如果沒有再依次按作用域鏈向上查找许起,因此使用 with 相當(dāng)于增加了作用域鏈長度十偶。而每次查找作用域鏈都是要消耗時(shí)間的,過長的作用域鏈會(huì)導(dǎo)致查找性能下降园细。
         因此惦积,除非你能肯定在 with 代碼中只訪問 obj 中的屬性,否則慎用 with猛频,替代的可以使用局部變量緩存需要訪問的屬性狮崩。
        3. 避免使用 eval 和 Function
        每次 eval 或 Function 構(gòu)造函數(shù)作用于字符串表示的源代碼時(shí),腳本引擎都需要將源代碼轉(zhuǎn)換成可執(zhí)行代碼鹿寻。這是很消耗資源的操作 —— 通常比簡單的函數(shù)調(diào)用慢 100倍以上睦柴。
        eval 函數(shù)效率特別低,由于事先無法知曉傳給 eval 的字符串中的內(nèi)容毡熏,eval 在其上下文中解釋要處理的代碼坦敌,也就是說編譯器無法優(yōu)化上下文,因此只能有瀏覽器在運(yùn)行時(shí)解釋代碼痢法。這對性能影響很大狱窘。
        Function 構(gòu)造函數(shù)比 eval 略好,因?yàn)槭褂么舜a不會(huì)影響周圍代碼;但其速度仍很慢财搁。
        此外蘸炸,使用 eval和 Function也不利于Javascript 壓縮工具執(zhí)行壓縮。
        4. 減少作用域鏈查找
        這一點(diǎn)在循環(huán)中是尤其需要注意的問題尖奔。如果在循環(huán)中需要訪問非本作用域下的變量時(shí)請?jiān)诒闅v之前用局部變量緩存該變量搭儒,并在遍歷結(jié)束后再重寫那個(gè)變量穷当,這一點(diǎn)對全局變量尤其重要,因?yàn)槿肿兞刻幱谧饔糜蜴湹淖铐敹搜秃蹋L問時(shí)的查找次數(shù)是最多的膘滨。
        此外,要減少作用域鏈查找還應(yīng)該減少閉包的使用稀拐。
        5. 數(shù)據(jù)訪問
        Javascript中的數(shù)據(jù)訪問包括直接量 (字符串、正則表達(dá)式 )丹弱、變量德撬、對象屬性以及數(shù)組,其中對直接量和局部變量的訪問是最快的躲胳,對對象屬性以及數(shù)組的訪問需要更大的開銷蜓洪。當(dāng)出現(xiàn)以下情況時(shí),建議將數(shù)據(jù)放入局部變量:
         1. 對任何對象屬性的訪問超過 1次
         2. 對任何數(shù)組成員的訪問次數(shù)超過 1次
        另外坯苹,還應(yīng)當(dāng)盡可能的減少對對象以及數(shù)組深度查找隆檀。
        6. 字符串拼接
        在 Javascript中使用"+" 號來拼接字符串效率是比較低的,因?yàn)槊看芜\(yùn)行都會(huì)開辟新的內(nèi)存并生成新的字符串變量粹湃,然后將拼接結(jié)果賦值給新變量恐仑。與之相比更為高效的做法是使用數(shù)組的 join方法,即將需要拼接的字符串放在數(shù)組中最后調(diào)用其 join 方法得到結(jié)果为鳄。不過由于使用數(shù)組也有一定的開銷裳仆,因此當(dāng)需要拼接的字符串較多的時(shí)候可以考慮用此方法。
       2. CSS選擇符
       3. HTML
       4. Image壓縮

摘自:Web前端應(yīng)該從哪些方面來優(yōu)化網(wǎng)站?

另外:

  1. 減少http請求次數(shù)
    80%的響應(yīng)時(shí)間花在下載網(wǎng)頁內(nèi)容(images, stylesheets, javascripts, scripts, flash等)孤钦。減少請求次數(shù)是縮短響應(yīng)時(shí)間的關(guān)鍵歧斟!可以通過簡化頁面設(shè)計(jì)來減少請求次數(shù)。
  2. 減少DNS查詢次數(shù)
    DNS查詢也消耗響應(yīng)時(shí)間偏形,如果我們的網(wǎng)頁內(nèi)容來自各個(gè)不同的domain (比如嵌入了開放廣告静袖,引用了外部圖片或腳本),那么客戶端首次解析這些domain也需要消耗一定的時(shí)間俊扭。DNS查詢結(jié)果緩存在本地系統(tǒng)和瀏覽器中一段時(shí)間队橙,所以DNS查詢一般是對首次訪問響應(yīng)速度有所影響。下面是我清空本地dns后訪問博客園主頁dns的查詢請求萨惑。
  3. 緩存Ajax
    Ajax可以幫助我們異步的下載網(wǎng)頁內(nèi)容喘帚,但是有些網(wǎng)頁內(nèi)容即使是異步的,用戶還是在等待它的返回結(jié)果咒钟,例如ajax的返回是用戶聯(lián)系人的下拉列表吹由。所以我們還是要注意盡量應(yīng)用以下規(guī)則提高ajax的響應(yīng)速度。
  4. 延遲加載
    這里討論延遲加載需要我們知道我們的網(wǎng)頁最初加載需要的最小內(nèi)容集是什么朱嘴。剩下的內(nèi)容就可以推到延遲加載的集合中倾鲫。
    Javascript是典型的可以延遲加載內(nèi)容粗合。一個(gè)比較激進(jìn)的做法是開發(fā)網(wǎng)頁時(shí)先確保網(wǎng)頁在沒有Javascript的時(shí)候也可以基本工作,然后通過延遲加載腳本來完成一些高級的功能乌昔。

另:
唯快不破:Web 應(yīng)用的 13 個(gè)優(yōu)化步驟

從輸入U(xiǎn)RL到瀏覽器顯示頁面發(fā)生了什么?

這個(gè)過程可以大致分為兩個(gè)部分:網(wǎng)絡(luò)通信和頁面渲染隙疚。

  1. 網(wǎng)絡(luò)通信
  • 在瀏覽器中輸入 url
    用戶輸入 url ,例如 http://www.baidu.com磕道。其中 http 為協(xié)議供屉, www.baidu.com 為網(wǎng)絡(luò)地址。一般網(wǎng)絡(luò)地址可以為域名或IP地址溺蕉。
  • 應(yīng)用層 DNS 解析域名伶丐。
    客戶端先檢查本地是否有對應(yīng)的 IP 地址,若找到則返回響應(yīng)的 IP 地址疯特。若沒找到則請求上級 DNS 服務(wù)器哗魂,直至找到或到根節(jié)點(diǎn)。
  • 應(yīng)用層客戶端發(fā)送 HTTP 請求
    HTTP 請求包括請求報(bào)頭和請求主體兩個(gè)部分.
  • 傳輸層 TCP 傳輸報(bào)文
    TCP協(xié)議通過“三次握手”等方法保證傳輸?shù)陌踩煽俊?/li>
  • 網(wǎng)絡(luò)層IP協(xié)議查詢 MAC 地址
  • 數(shù)據(jù)到達(dá)數(shù)據(jù)鏈路層
  • 服務(wù)器接收數(shù)據(jù)
  • 服務(wù)器響應(yīng)請求
    服務(wù)接收到客戶端發(fā)送的HTTP請求后漓雅,查找客戶端請求的資源录别,并返回響應(yīng)報(bào)文,響應(yīng)報(bào)文中包括一個(gè)重要的信息——狀態(tài)碼邻吞。其中比較常見的是200 OK表示請求成功组题。301表示永久重定向,即請求的資源已經(jīng)永久轉(zhuǎn)移到新的位置抱冷。在返回301狀態(tài)碼的同時(shí)往踢,響應(yīng)報(bào)文也會(huì)附帶重定向的url,客戶端接收到后將http請求的url做相應(yīng)的改變再重新發(fā)送徘层。404 not found 表示客戶端請求的資源找不到峻呕。
    狀態(tài)碼由三位數(shù)字組成:
    • 1xx:指示信息–表示請求已接收,繼續(xù)處理趣效。
    • 2xx:成功–表示請求已被成功接收瘦癌、理解、接受跷敬。
    • 3xx:重定向–要完成請求必須進(jìn)行更進(jìn)一步的操作讯私。
    • 4xx:客戶端錯(cuò)誤–請求有語法錯(cuò)誤或請求無法實(shí)現(xiàn)。
    • 5xx:服務(wù)器端錯(cuò)誤–服務(wù)器未能實(shí)現(xiàn)合法的請求西傀。
  • 服務(wù)器返回相應(yīng)文件
  1. 頁面渲染
    瀏覽器是一個(gè)邊解析邊渲染的過程斤寇。首先瀏覽器解析HTML文件構(gòu)建DOM樹,然后解析CSS文件構(gòu)建渲染樹拥褂,等到渲染樹構(gòu)建完成后娘锁,瀏覽器開始布局渲染樹并將其繪制到屏幕上。

摘自:從輸入U(xiǎn)RL到瀏覽器顯示頁面發(fā)生了什么
另:
一個(gè)頁面從輸入U(xiǎn)RL到頁面加載顯示完成饺鹃,這個(gè)過程都發(fā)生什么莫秆?
從輸入U(xiǎn)RL到頁面加載發(fā)生了什么?

如何垂直居中一個(gè)浮動(dòng)元素间雀?

/* 已知寬高 */
#div1{
  background-color:#6699FF;
  width:200px;
  height:200px;
  position: absolute; /*父元素需要相對定位*/
  top: 50%;
  left: 50%;
  margin-top:-100px ;  
  margin-left: -100px;
}

/* 未知寬高 */
#div1{
  width: 200px;
  height: 200px;
  background-color: #6699FF;
  margin:auto;
  position: absolute;/*父元素需要相對定位*/
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  }

那么問題來了,如何垂直居中一個(gè)<img>?(用更簡便的方法镊屎。)

/*<img>的容器設(shè)置如下*/
#container 
{
    display:table-cell;
    text-align:center;
    vertical-align:middle;
}

jquery 常用的選擇器

  1. 基本選擇器
  2. ID選擇器 $(“#id”) 獲取指定ID的元素
  3. 類選擇器 $(“.class”) 獲取同一類class的元素
  4. 標(biāo)簽選擇器 $(“div”) 獲取同一類標(biāo)簽的所有元素
  5. 并集選擇器 $(“div,p,li”) 使用逗號分隔惹挟,只要符合條件之一就可。獲取所有的div缝驳、p连锯、li元素
  6. 交集選擇器(標(biāo)簽指定式選擇器) $(“div.redClass”) 注意選擇器1和選擇器2之間沒有空格,class為redClass的div元素用狱,注意區(qū)分后代選擇器运怖。
  7. 層級選擇器
  8. 子代選擇器 $(“ul>li”) 使用>號,獲取兒子層級的元素齿拂,注意,并不會(huì)獲取孫子層級的元素
  9. 后代選擇器 $(“ul li”) 使用空格肴敛,代表后代選擇器署海,獲取ul下的所有l(wèi)i元素,包括孫子等
  10. 過濾選擇器
  11. :eq(index) $(“l(fā)i:eq(2)”).css(“color”, ”red”) 獲取到的li元素中医男,選擇索引號為2的元素砸狞,索引號index從0開始。
  12. :odd $(“l(fā)i:odd”).css(“color”, ”red”) 獲取到的li元素中镀梭,選擇索引號為奇數(shù)的元素
  13. :even $(“l(fā)i:even”).css(“color”, ”red”) 獲取到的li元素中刀森,選擇索引號為偶數(shù)的元素
  14. 篩選選擇器(方法)
  15. children(selector) $(“ul”).children(“l(fā)i”) 相當(dāng)于$(“ul>li”),子類選擇器
  16. find(selector) $(“ul”).find(“l(fā)i”) 相當(dāng)于$(“ul li”),后代選擇器
  17. siblings(selector) $(“#first”).siblings(“l(fā)i”) 查找兄弟節(jié)點(diǎn)报账,不包括自己本身研底。
  18. parent() $(“#first”).parent() 查找父親
  19. eq(index) $(“l(fā)i”).eq(2) 相當(dāng)于$(“l(fā)i:eq(2)”),index從0開始

bind 算法

只要掌握核心幾點(diǎn)就沒問題:

  1. Function.bind返回的也是一個(gè)函數(shù),所以注定發(fā)生了閉包透罢,
  2. 在返回的這個(gè)函數(shù)中去調(diào)用一個(gè)其他的函數(shù)榜晦,這其實(shí)本質(zhì)上就是函數(shù)鉤子(HOOK)

關(guān)于在JS里的函數(shù)鉤子,我認(rèn)為只需要維護(hù)以下三點(diǎn)即可:

  1. 保持函數(shù)的this指向
  2. 保持函數(shù)的所有參數(shù)都傳遞到目標(biāo)函數(shù)
  3. 保持函數(shù)的返回值

有了以上這幾點(diǎn)羽圃,這個(gè)函數(shù)就非常好寫了乾胶,下面是MSDN上的標(biāo)準(zhǔn)Polyfill:

if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }
    var aArgs = Array.prototype.slice.call(arguments, 1), 
      fToBind = this, 
      fNOP = function () {},
      fBound = function () {
        return fToBind.apply(this instanceof fNOP 
          ? this 
          : oThis || this,
          aArgs.concat(Array.prototype.slice.call(arguments)));
      };
    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();
    return fBound;
  };
}

摘自: Web前端面試小記

最后

嘛!來啊朽寞,互相傷害笆读!面試什么的脑融,傷的多惹喻频,并不算什么【傲嬌臉】!

:-P

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肘迎,一起剝皮案震驚了整個(gè)濱河市半抱,隨后出現(xiàn)的幾起案子脓恕,更是在濱河造成了極大的恐慌,老刑警劉巖窿侈,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件炼幔,死亡現(xiàn)場離奇詭異,居然都是意外死亡史简,警方通過查閱死者的電腦和手機(jī)乃秀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來圆兵,“玉大人跺讯,你說我怎么就攤上這事。” “怎么了橱赠?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵蚪腐,是天一觀的道長。 經(jīng)常有香客問我愈污,道長,這世上最難降的妖魔是什么轮傍? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任暂雹,我火速辦了婚禮,結(jié)果婚禮上创夜,老公的妹妹穿的比我還像新娘杭跪。我一直安慰自己,他們只是感情好驰吓,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布涧尿。 她就那樣靜靜地躺著,像睡著了一般檬贰。 火紅的嫁衣襯著肌膚如雪现斋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天偎蘸,我揣著相機(jī)與錄音庄蹋,去河邊找鬼。 笑死迷雪,一個(gè)胖子當(dāng)著我的面吹牛限书,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播章咧,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼倦西,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了赁严?” 一聲冷哼從身側(cè)響起扰柠,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤粉铐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后卤档,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蝙泼,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年劝枣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了汤踏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡舔腾,死狀恐怖溪胶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情稳诚,我是刑警寧澤哗脖,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站扳还,受9級特大地震影響才避,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜普办,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一工扎、第九天 我趴在偏房一處隱蔽的房頂上張望徘钥。 院中可真熱鬧衔蹲,春花似錦、人聲如沸呈础。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽而钞。三九已至沙廉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間臼节,已是汗流浹背撬陵。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留网缝,地道東北人巨税。 一個(gè)月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像粉臊,于是被迫代替她去往敵國和親草添。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

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