運行環境
--瀏覽器可以通過訪問鏈接來得到頁面的內容;(上線的代碼產生的內容)
--瀏覽器通過繪制和渲染,顯示出頁面的最終的樣子;
--整個過程中,我們需要考慮什么問題?(瀏覽器內核情況)
1.頁面加載過程
1.1.從輸入url到得到html的詳細過程
1.瀏覽器根據DNS服務器(解析出)得到域名的IP地址
2.向這個IP的機器發送http請求
3.服務器收到、處理并返回http請求
4.瀏覽器得到返回內容
1.2.window.onload 和 DOMContentLoaded 的區別
都是頁面加載之后要觸發什么事件;
window.addEventListener('load',function(){
//頁面的全部資源加載完才會執行,包括圖片、視頻等
});
document.addEventListener('DOMContentLoaded',function(){
//DOM 渲染完即可執行,此時圖片、視頻還可能沒有加載完
});
2.1.加載資源的形式
1.-輸入url(或跳轉頁面)加載html
http://coding.m.imooc.com
2.-加載html中的靜態資源
<script src="/static/js/jquery.js"></script>
2.2.加載一個資源的過程
都符合1.瀏覽器根據DNS服務器(解析出)得到域名的IP地址
2.向這個IP的機器發送http請求
3.服務器收到、處理并返回http請求
4.瀏覽器得到返回內容
2.3.瀏覽器渲染頁面的過程
1.根據HTML結構生成DOM Tree(只有結構)
2.根據css生成CSSOM(樣式)
3.將DOM 和 CSSOM 整合形成RenderTree(渲染樹)
4.根據RenderTree 開始渲染和展示
5.遇到<script>時,會執行并阻塞渲染
(瀏覽器渲染一個DOM樹,script中js有權利改變DOM結構和內容,我們不得不讓瀏覽器
去做出一個妥協性的讓步,js在加載執行中,渲染先結束先阻塞先不要管它)
*頁面加載--幾種示例
1.<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<p>test</p>
</body>
</html>
2.div{
width:100%;
height:100px;
font-size:50px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="styleSheet" type="text/css" href="test.css">
</head>
<body>
<div>test</div>
</body>
</html>
3. document.getElementById('container').innerHTML == 'update by js';
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="container">default</div>
<script src="index.js"></script>
<p>test</p>
</body>
</html>
*首先你輸入url(或跳轉頁面)把html代碼加載出來,瀏覽器要解析,到body里面
開始渲染了,body里第一行渲染出一個div內容是default,到body里第二行發現一
個script,停下來加載script,(第三行代碼就一直等著)加載完并執行完之后,最后
一行才正式渲染出來。
4.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<p>test</p>
<p></p>
<p>test</p>
</body>
</html>
加載完html結構之后就開始渲染,body中第一行圖片是異步請求的,比如這個test.png
很大,請求的很慢,這個時候并不會阻礙整個dom樹的一個渲染,渲染body第一行ok結束
,渲染第二行結束,img標簽已經有了,只不過圖片還沒有加載出來而已,這個img標簽
已經可以用了,這個時候圖片是異步加載,我們在渲染第三行。
1.為什么要把css放在head中?
加載css之后,瀏覽器直接知道規則,在渲染下面的DOM結構的時候就會把這些結構考慮
進去去渲染;(css一定要在body里面的東西出來之前就加載完,而且這個規則要告訴
瀏覽器,加載完之后瀏覽器就自己知道了,然后再body渲染的時候,一次就把這個事干好)
2.為什么要把js放在body最下面?
1.不會阻塞之前的body內容,因為內容(沒有script執行,先把html結構基本的一些
標簽渲染出來,最后在執行script,這個時候就不會阻塞了,能讓頁面更快的出來,
這是性能的問題)已經渲染;
2.把script放在最后能拿到所有的標簽
2.性能優化(本身是一個綜合性的問題)
原則:
1.多實用內存(內存的存儲)、緩存或者其他方法
2.減少CPU計算、減少網絡請求
從哪里入手:
1.加載頁面和靜態資源
--靜態資源的壓縮合并;
--靜態資源緩存;(本地有緩存就沒有必要在請求一次)
--使用CDN讓資源加載更快(CDN是一個不同區域的網絡優化,如果我在北京訪問一個
地址的時候,同樣的一個地址CDN會給我轉到北京就近的一個機房中加載下來;如果
沒有CDN,你的服務器就在杭州,我從任何一個地方的請求都需要走杭州的一個機房,
距離比較遠,經過的路由器就比較多,也就比較慢一些)
--使用SSR(server side rander 服務端渲染)后端渲染,數據直接輸出到HTML中
2.頁面渲染(渲染優化)
--css放前面,js放后面
--懶加載(圖片懶加載、下拉加載更多);
圖片先不加載,什么時候用什么加載;
--減少DOM查詢,對DOM查詢做緩存;
--減少DOM操作,多個操作盡量合并在一起執行;
--事件節流(很頻繁的操作合到一個操作);
--盡早執行操作(如 DOMContentLoaded)
DOM渲染完就立即執行,不管前端資源像圖片有沒有加載完
性能優化--幾個示例:
1.--資源合并
<scirpt src="a.js"></script>
<scirpt src="b.js"></script>
<scirpt src="c.js"></script>
代碼合并成(構建工具來合并):
<script src="abc.js"></script>
2.--緩存
1.通過連接名稱控制緩存
<script src="abc_1.js"></script>
2.只有內容改變的時候,鏈接名稱才會改變
<script src="abc_2.js"></script>
3.--使用CDN (比在服務器上做zepto連接要快很多)
<link rel="styleSheet">
<script src="https://cdn.bootcss.com/zepto/10rc1/zepto.min.js"></script>
4.--使用SSR后端渲染
(好處:把數據直接輸出到html中,瀏覽器能直接拿到,直接渲染,沒必要ajax把數據在獲取一遍)
1.現在Vue React(這兩個默認沒有后端渲染的) 提出了這樣的概念:
先把模板拿下來之后通過ajax獲取數據
2.jsp php asp都屬于后端渲染(動態頁面--我們的數據可以直接輸出到瀏覽器,不用再通過ajax獲取)
**5.--懶加載 **

<script type="text/javascript">
var img1 = document.getElementById('img1');
img1.src = img1.getAttribute('date-realsrc');
</script>
一開始的圖片是顯示很小的圖,很快就加載出來,但這個圖片真正用的時候在把這個真正的圖片賦值過來讓它顯示就行;
加快頁面渲染速度;
6.--緩存DOM查詢
//未緩存DOM查詢(每次循環都需要執行DOm查詢)
//執行每一次循環,document.getElementsByTagName('p')都要做一次查詢
var i;
for(i=0;i<document.getElementsByTagName('p').length;i++){
//todo
};
//緩存了DOM查詢(一次DOM查詢把東西存到一個變量中,下次循環就沒有必要在挨個做DOM查詢了,
只是獲取這個變量的屬性就可以了)
//直接把東西查詢出來緩存到pList中,就查詢一次,下面在執行10遍循環的時候
,就不會在去執行查詢了,只需從緩存的pList去取就行了,這就快了。
var pList = document.getElementsByTagName('p');
var i ;
for(i=0;i<pList.length;i++){
//todo
}
7.--合并DOM插入(本來有10次dom查詢,現在只剩一次了)
var listNode = document.getElementById('list');
//要插入10個li標簽
(定義一個臨時片段,10次循環只用對片段中去加,不會觸發DOM操作)
var frag = document.createDocumentFragment();
var x,li;
for(x=0;x<10;x++){
//定義一個片段,10個li依次插入片段中
li = document.createElement("li");
li.innerHTML = "List item"+x;
frag.appendChild(li);
}
//把片段插入listNode
listNode.appendChild(frag);
8.--事件節流(性能優化的原則,減少cpu的計算
var textarea = document.getElementById('text');
var timeoutId;
textarea.addEventListener('keyup',function(){
//每次看看timeoutId有沒有,有了就先清掉
if(timeoutId){
clearTimeout(timeoutId);
}
//當輸入完停下來這個時候觸發change事件;
//重新賦值timeoutId,設個100毫秒的延遲;如果一旦停大于100毫秒以上就觸發change事件;
timeoutId = setTimeout(function(){
//觸發change事件
},100);
});
9.--盡早執行操作
window.addEventListener('load',function(){
//頁面的全部資源加載完才會執行,包括圖片、視頻等
});
document.addEventListener('DOMContentLoaded',function(){
//DOM 渲染完即可執行,此時圖片、視頻還可能沒有加載完
});
3.安全性
1.--場景的前端安全問題有哪些?
1.1.XSS跨站請求攻擊
eg:1.新浪博客寫一篇文章,同時偷偷插入一段<script>
(一旦看這篇文章,代碼就會執行;獲取cookie,發送自己的服務器,多少人看了這篇文章,就能獲取多少用戶信息)
----攻擊代碼中,獲取cookie,發送自己的服務器;
----發布博客,有人查看博客內容;
----會把查看著的cookie發送到攻擊者的服務器;
*怎么預防:
--前端替換關鍵字,例如替換 < 為 < > w為 >(會影響性能,js執行效率比較低,前端只有瀏覽器)
--后端替換(依賴于服務器的能力)
1.2.XSRF跨站請求偽造
eg:你已登錄一個購物網站,正在瀏覽商品
----該網站付費接口是 xxx.com/pay?id=100 但是沒有任何驗證;
----然后你收到一封郵件,隱藏這<img src=xxx.com/pay?id=100>;
----你查看郵件的時候,就已經悄悄的付費購買了。
*解決方案:
--1.增加驗證流程,如輸入指紋、密碼、短信驗證碼(后端來做驗證,前端配合)
****************面試技巧****************
1.簡歷
1.1簡潔明了,重點突出項目經歷和解決方案;
(項目經歷:做過什么東西要寫明白,可以通過你做的東西了解到你,這個項目真實的技術等級、技術復雜度)
(解決方案:在項目中做了什么貢獻,遇到什么樣的問題,用什么解決的(用的什么框架來做,技術棧、解決方案))
1.2.把個人博客放在簡歷中,并且定期維護更新博客
1.3.把個人的開源項目放在簡歷中,并維護開源項目
1.4.簡歷千萬不要造假,要保持能力和經歷上的真實性
2.面試過程中。。。
2.1.如何看待加班?加班就像借錢,救急不救窮
(加班作為常態那就不行了,加班會很累,壓力會比較大,睡不好;
根本沒有業余時間去提高自己的能力)
2.2.千萬不要挑戰面試官,不要反考面試官
2.3.學會給面試官驚喜,但不要太多
2.4.遇到不會回答的問題,說出你知道的也可以
比如:性能優化 知道多少說出來多少
2.5.談談你的缺點——————說一下你最近正在學什么就可以了
比如:最近在學react
可能對react還不是很了解,現在正在學,大約一個月之后就能做出來一個react網站;