1、簡述瀏覽器的渲染過程,DOM 樹和渲染樹的區(qū)別?
瀏覽器的渲染過程:
解析 HTML 構(gòu)建 DOM(DOM 樹),并行請求 css/image/js
CSS 文件下載完成,開始構(gòu)建 CSSOM(CSS 樹)
CSSOM 構(gòu)建結(jié)束后,和 DOM 一起生成 Render Tree(渲染樹)
布局(Layout):計算出每個節(jié)點在屏幕中的位置
顯示(Painting):通過顯卡把頁面畫到屏幕上
DOM 樹 和 渲染樹 的區(qū)別:
1、dom 樹,css 樹合并成成渲染樹(render 樹)
2、DOM 樹與 HTML 標簽一一對應(yīng),包括 head 和隱藏元素3、渲染樹不包括 head 和隱藏元素,大段文本的每一個行都是獨立節(jié)點,每一個節(jié)點都有對應(yīng)的css 屬性
2、簡單說一下頁面重繪和重排,如何最小化重繪和重排
瀏覽器渲染引擎工作時,會先解析HTML然后生成DOM樹,與此同時,渲染引擎也會用CSS解析器解析CSS文檔構(gòu)建CSSOM樹。接下來,DOM樹和CSSOM樹關(guān)聯(lián)起來構(gòu)成渲染樹(RenderTree)然后瀏覽器按照渲染樹進行布局(Layout),最后一步通過繪制顯示出整個頁面。
重繪和重排的區(qū)別:
重繪:一個元素外觀發(fā)生改變,但沒有改變布局,重新把元素繪制出來的過程。
重排:當dom的變化影響元素的幾何信息(元素的位置和尺寸大?。?,瀏覽器需要重新計算元素的幾何屬性,將其安放在界面的正確的位置。這個過程叫重排。
單單改變元素的外觀,肯定不會引起網(wǎng)頁重新生成布局,但當瀏覽器完成重排之后,將會重新繪制受到此次重排影響的部分。比如改變元素高度,這個元素乃至周邊dom都需要重新繪制。
即:重繪不一定導(dǎo)致重排,但重排一定會導(dǎo)致重繪。重排對性能的消耗要更多一些
觸發(fā)重排的方法:
改變元素的位置;改變元素的尺寸,比如邊距,填充,邊框,寬度,高度等;
頁面初始渲染,這是開銷最大的一次重排;改變元素的字體大?。?br>
改變?yōu)g覽器窗口大小,比如resize事件發(fā)生時;改變元素內(nèi)容,字體數(shù)量,圖片大?。?br>
激活css偽類;設(shè)置style屬性的值,因為設(shè)置style屬性會改變結(jié)點樣式,就會觸發(fā)重排。查詢某些屬性、或者調(diào)用某些計算方法:offsetwidth,offheight。
避免重排的方法是樣式集中改變;使用absolute或fixed脫離文檔流;使用gpu加速,transform。
引起重排的幾個原因
頁面初始渲染,這是開銷最大的一次重排
添加/刪除可見的DOM元素
改變元素位置
改變元素尺寸,比如邊距、填充、邊框、寬度和高度等
改變元素內(nèi)容,比如文字數(shù)量,圖片大小元素字體大小等
改變?yōu)g覽器窗口尺寸,比如resize事件發(fā)生時
激活CSS偽類(例如::hover)
設(shè)置 style 屬性的值,因為通過設(shè)置style屬性改變結(jié)點樣式的話,每一次設(shè)置都會觸發(fā)一次reflow
查詢某些屬性或調(diào)用某些計算方法:offsetWidth、offsetHeight等。原理是一樣的,都為求一個“即時性”和“準確性”。
重排影響的范圍
全局范圍:從根節(jié)點html開始對整個渲染樹進行重新布局。
局部范圍:對渲染樹的某部分或某一個渲染對象進行重新布局
把一個dom的寬高之類的幾何信息定死,然后在dom內(nèi)部觸發(fā)重排,就只會重新渲染該dom內(nèi)部的元素,而不會影響到外界。(例如position為absolut和fixed)
如何最小化重繪(repaint)和回流(reflow)?
(1)需要要對元素進行復(fù)雜的操作時,可以先隱藏(display:"none"),操作完成后再顯示
(2)需要創(chuàng)建多個 DOM 節(jié)點時,使用 DocumentFragment 創(chuàng)建完后一次性的加入 document
(3)緩存 Layout 屬性值,如:var left = elem.offsetLeft; 這樣,多次使用 left 只產(chǎn)生一次回流
(4)盡量避免用 table 布局(table 元素一旦觸發(fā)回流就會導(dǎo)致 table 里所有的其它元素回流)
(5)避免使用 css 表達式(expression),因為每次調(diào)用都會重新計算值(包括加載頁面)
(6)盡量使用 css 屬性簡寫,如:用 border 代替 border-width, border-style, border-color
(7)批量修改元素樣式:elem.className 和 elem.style.cssText 代替 elem.style.xxx
3、CSS 的盒模型?
盒子模型分為兩種:
第一種是 W3C 標準的盒子模型(標準盒模型)
第二種 IE 標準的盒子模型(怪異盒模型)
標準盒模型與怪異盒模型的表現(xiàn)效果的區(qū)別之處:
1、標準盒模型中
width 指的是內(nèi)容區(qū)域 content 的寬度
height 指的是內(nèi)容區(qū)域 content 的高度
標準盒模型下盒子的大小 = content + border + padding + margin
2、怪異盒模型中
width 指的是內(nèi)容、邊框、內(nèi)邊距總的寬度(content + border + padding);
height 指的是內(nèi)容、邊框、內(nèi)邊距總的高度
怪異盒模型下盒子的大小=width(content + border + padding) + margin;
除此之外,我們還可以通過屬性 box-sizing 來設(shè)置盒子模型的解析模式
可以為 box-sizing 賦兩個值:
content-box:默認值,border 和 padding 不算到 width 范圍內(nèi),可以理解為是 W3c 的
標準模型(default)??倢?width+padding+border+margin
border-box:border 和 padding 劃歸到 width 范圍內(nèi),可以理解為是 IE 的怪異盒 模
型,總寬=width+margin
4、CSS的引入方式有哪些?有什么區(qū)別?
方式一:內(nèi)聯(lián)樣式
內(nèi)聯(lián)樣式也叫行內(nèi)樣式,指的是直接在HTML標簽中的 style 屬性中添加 css。
方式二:嵌入樣式
嵌入樣式指的是在HTML頭部中的 style 標簽中寫入CSS代碼。
方式三:鏈接樣式
鏈接方式指的是使用HTML頭部的標簽引入外部的 CSS 文件。
方式四:導(dǎo)入樣式
導(dǎo)入樣式指的是使用 CSS 規(guī)則引入外部 CSS 文件。
使用link和@import區(qū)別:
1、從屬關(guān)系的區(qū)別:link屬于HTML標簽,而@import是CSS提供的語法規(guī)則,link除了加載CSS,還可以定義RSS,定義rel連接屬性等;@import就只能加載CSS。
2、加載順序的區(qū)別:link引入的樣式在頁面加載的同時加載;@import引入的樣式需等頁面加載完成后再加載。
3、兼容性區(qū)別:link是HTML標簽,所以沒有兼容性問題;@import不兼容IE5以下。
4、DOM可控性區(qū)別:link可以通過js操作DOM 動態(tài)引入樣式;由于DOM方法是基于文檔的,無法使用@import方式插入樣式。
5、用過哪些css動畫屬性?都是干啥用的?簡單實現(xiàn)一個無限旋轉(zhuǎn)動畫
animation 主要包含6個屬性,具體含義如下:
animation-name 規(guī)定需要綁定到選擇器的 keyframe 名稱。
animation-duration 規(guī)定完成動畫所花費的時間,以秒或毫秒計。
animation-timing-function 規(guī)定動畫的速度曲線。
animation-delay 規(guī)定在動畫開始之前的延遲,默認值為0。
animation-iteration-count 規(guī)定動畫應(yīng)該播放的次數(shù),默認值為1。
animation-direction 規(guī)定是否應(yīng)該輪流反向播放動畫,默認值是正向
animation-fill-mode : none | forwards | backwards | both;規(guī)定動畫在播放之前或之后,其動畫效果是否可見
animation-play-state: paused|running 規(guī)定動畫正在運行還是暫停。
transition 屬性是一個簡寫屬性,用于設(shè)置四個過渡屬性:
transition-property 規(guī)定設(shè)置過渡效果的 CSS 屬性的名稱。
transition-duration 規(guī)定完成過渡效果需要多少秒或毫秒。
transition-timing-function 規(guī)定速度效果的速度曲線。
transition-delay 定義過渡效果何時開始。
@keyframes donghua{
0%:{
transform:rorate(0deg);
}
100%:{
transform:rorate(360deg);
}
}
#app{
width:100px;
height:100px;
margin:100px auto;
background-color:pink;
anamation:donghua 2s linear 0.2s infinite;
}
6、BFC的布局規(guī)則?
1、內(nèi)部的Box會在垂直方向,一個接一個地放置。
2、Box垂直方向的距離由margin決定。屬于同一個BFC的兩個相鄰Box的margin會發(fā)生重疊(按照最大margin值設(shè)置)
3、每個元素的margin box的左邊, 與包含塊border box的左邊相接觸
4、BFC的區(qū)域不會與float box重疊。
5、BFC就是頁面上的一個隔離的獨立容器,容器里面的子元素不會影響到外面的元素。
6、計算BFC的高度時,浮動元素也參與計算
哪些元素或?qū)傩阅苡|發(fā)BFC
1、根元素(html)
2、float屬性不為none
3、position為absolute或fixed
4、display為inline-block, table-cell, table-caption, flex, inline-flex
5、overflow不為visible
BFC的應(yīng)用
1、自適應(yīng)兩欄布局
2、清除內(nèi)部浮動
3、防止margin上下重疊
7、什么是防抖和節(jié)流?有什么區(qū)別?
防抖和節(jié)流本質(zhì)是不一樣的。防抖是將多次執(zhí)行變?yōu)樽詈笠淮螆?zhí)行,節(jié)流是將多次執(zhí)行變成每隔一段時間執(zhí)行。
防抖(debounce):
防抖觸發(fā)高頻率事件時n秒后只會執(zhí)行一次,如果n秒內(nèi)再次觸發(fā),則會重新計算。
概述:每次觸發(fā)時都會取消之前的延時調(diào)用。
節(jié)流(thorttle):
高頻事件觸發(fā),每次觸發(fā)事件時設(shè)置一個延遲調(diào)用方法,并且取消之前的延時調(diào)用方法。
概述:每次觸發(fā)事件時都會判斷是否等待執(zhí)行的延時函數(shù)。
區(qū)別:降低回調(diào)執(zhí)行頻率,節(jié)省計算資源。
函數(shù)防抖一定時間連續(xù)觸發(fā)的事件,只在最后執(zhí)行一次,而函數(shù)節(jié)流一段時間內(nèi)只執(zhí)行一次。
function debounce_A(fn, delay) {
let timer = null;
// 真正執(zhí)行的函數(shù)
const _debounce = function () {
if (timer) {
// 取消上一次的定時器
clearTimeout(timer);
}
timer = setTimeout(function () {
fn();
}, delay);
};
return _debounce;
}
8、img iframe script 來發(fā)送跨域請求有什么優(yōu)缺點?
圖片
優(yōu)點:可以訪問任何url,一般用來進行點擊追蹤,做頁面分析常用的方法
缺點:不能訪問響應(yīng)文本,只能監(jiān)聽是否響應(yīng)
script(JsonP)
優(yōu)點:可以直接返回json格式的數(shù)據(jù)
缺點:只接受GET請求方式
frame
優(yōu)點:跨域完畢之后DOM操作和互相之間的JavaScript調(diào)用都是沒有問題的
缺點:1.若結(jié)果要以URL參數(shù)傳遞,這就意味著在結(jié)果數(shù)據(jù)量很大的時候需要分割傳遞,麻煩。2.還有一個是iframe本身帶來的,母頁面和iframe本身的交互本身就有安全性限制。
9、setTimeout、Promise、Async/Await 的區(qū)別?
1、JS是單線程語言,包括同步任務(wù)、異步任務(wù),異步任務(wù)又包括宏觀任務(wù)和微觀任務(wù)
2、執(zhí)行順序:同步任務(wù)——>微觀任務(wù)——>宏觀任務(wù)
3、宏觀任務(wù)的方法有:script(整體代碼)、setTimeout、setInterval、I/O、UI交互事件、postMessage、MessageChannel、setImmediate(Node.js 環(huán)境)
4、微觀任務(wù)的方法有:Promise.then、MutaionObserver、process.nextTick(Node.js 環(huán)境),async/await實際上是promise+generator的語法糖,也就是promise,也就是微觀任務(wù)
10、什么是事件流?
一、事件流的定義
頁面觸發(fā)一個事件時,會按照一定的順序來響應(yīng)事件,事件的響應(yīng)過程為事件流
事件流就是,事件傳播的過程。
DOM中完整的事件流包括了三個階段:事件捕獲階段、目標階段和事件冒泡階段