網(wǎng)頁設(shè)計(jì)的基礎(chǔ)aso優(yōu)化平臺有哪些
進(jìn)程與線程
進(jìn)程
進(jìn)程的概念
進(jìn)程是操作系統(tǒng)中的一個程序或者一個程序的一次執(zhí)行過程,是一個動態(tài)的概念,是程序在執(zhí)行過程中分配和管理資源的基本單位,是操作系統(tǒng)結(jié)構(gòu)的基礎(chǔ)。
簡單的來說,就是一個程序運(yùn)行開辟的一塊內(nèi)存空間,值得注意的是,一個程序至少有一個進(jìn)程,進(jìn)程之間是相互獨(dú)立
的。
線程
線程的概念
線程是進(jìn)程中的一個實(shí)體,是被系統(tǒng)獨(dú)立調(diào)度和分派的基本單位,是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位。
簡單的來說,就是執(zhí)行程序的通道,一個進(jìn)程至少有一個線程,在進(jìn)程開啟后自動創(chuàng)建一個線程,這個線程稱為主線程
,線程之間是共享
進(jìn)程的內(nèi)存空間的。
瀏覽器進(jìn)程與線程
瀏覽器是一個多進(jìn)程``多線程
的應(yīng)用程序
這是因?yàn)闉g覽器防止連環(huán)崩壞,避免相互影響,其中重要的進(jìn)程有:瀏覽器進(jìn)程、渲染進(jìn)程、網(wǎng)絡(luò)進(jìn)程等。
每個標(biāo)簽頁都是一個渲染進(jìn)程,每個進(jìn)程都是獨(dú)立的,互不影響,所以當(dāng)一個標(biāo)簽頁崩潰時,不會影響其他標(biāo)簽頁。
注:現(xiàn)在瀏覽器的渲染進(jìn)程改變了,不再是一個標(biāo)簽一個進(jìn)程,轉(zhuǎn)換為相同站點(diǎn)為一個進(jìn)程 時間2023/10/25
瀏覽器進(jìn)程
主要負(fù)責(zé)界面顯示(標(biāo)簽、前進(jìn)、后退、導(dǎo)航欄等)、用戶交互、子進(jìn)程管理(網(wǎng)絡(luò)、渲染進(jìn)程等)、提供存儲等功能。內(nèi)部會啟動多個線程處理不同的任務(wù)。
網(wǎng)絡(luò)進(jìn)程
負(fù)責(zé)網(wǎng)絡(luò)加載資源,主要是通過網(wǎng)絡(luò)請求獲取數(shù)據(jù),然后傳遞給渲染進(jìn)程。內(nèi)部會啟動多個線程處理不同的任務(wù)。
渲染進(jìn)程
渲染進(jìn)程啟動后,會開啟一個渲染主線程,負(fù)責(zé)執(zhí)行 HTML、CSS、JavaScript。
渲染主線程
渲染主線程負(fù)責(zé):
- 解析 HTML,生成 DOM 樹
- 解析 CSS,生成 CSSOM 樹
- 計(jì)算樣式
- 布局
- 處理圖層
- 每秒把頁面渲染到屏幕上 60 次(不同的設(shè)備刷新率不同)
- 執(zhí)行全局JS代碼
- 執(zhí)行事件處理函數(shù)
- 執(zhí)行計(jì)時器的回調(diào)函數(shù)
- …
為什么渲染進(jìn)程不適合多個線程?
如果渲染進(jìn)程有多個線程,那么多個線程會共享渲染進(jìn)程的內(nèi)存空間,這樣會導(dǎo)致多個線程之間相互影響,造成頁面崩潰。
瀏覽器事件循環(huán)
在渲染主進(jìn)程中的多個任務(wù)執(zhí)行,如何做到任務(wù)調(diào)度 ===> 排隊(duì)執(zhí)行
任務(wù)隊(duì)列
任務(wù)隊(duì)列是一個先進(jìn)先出的隊(duì)列,用來存儲將要執(zhí)行的任務(wù),渲染主線程,從任務(wù)隊(duì)列拿任務(wù)執(zhí)行。
渲染主線程流程:
- 進(jìn)入無限循環(huán),不斷從任務(wù)隊(duì)列中取出任務(wù)執(zhí)行
- 每次檢查任務(wù)隊(duì)列是否有任務(wù),如果有,就取出任務(wù)執(zhí)行,沒有就等待任務(wù)加入任務(wù)隊(duì)列
- 其他線程的任務(wù)可隨時加入任務(wù)隊(duì)列末尾
異步任務(wù)
代碼在執(zhí)行過程中,會遇到一些無法立即處理的任務(wù),比如:
- 計(jì)時完成后需要執(zhí)行的任務(wù):setTimeout、setInterval
- 網(wǎng)絡(luò)通訊完成后需要執(zhí)行的任務(wù):XHR、Fetch
- 用戶操作后需要執(zhí)行的任務(wù):addEvaentListener
如果讓渲染主線程等待這些任務(wù)的執(zhí)行,將會導(dǎo)致主線程長期處于阻塞
狀態(tài),導(dǎo)致瀏覽器奔潰
這里使用異步的方式保證主線程不阻塞
如何理解 JS 的異步?
JS是一門單線程的語言,因?yàn)镴S執(zhí)行在渲染主線程中,為了防止渲染主線程的阻塞,采用異步的方式,碰到耗時任務(wù)時交給其他線程處理,自生立即結(jié)束當(dāng)前任務(wù),執(zhí)行后續(xù)任務(wù),而耗時任務(wù)的回調(diào)函數(shù)包裝成任務(wù),加到任務(wù)隊(duì)列中末尾,等待調(diào)度執(zhí)行
任務(wù)優(yōu)先級
任務(wù)沒有優(yōu)先級,但是任務(wù)隊(duì)列是有優(yōu)先級的
- 每個任務(wù)都有一個任務(wù)類型,同一個類型的任務(wù)必須在同一個隊(duì)列,不同類型的任務(wù)可分屬于不同的隊(duì)列(也可以將兩種或多種類型的任務(wù)放在同一個隊(duì)列)
在一次事件循環(huán)中,瀏覽器可以根據(jù)實(shí)際情況從不同的隊(duì)列中取出任務(wù)執(zhí)行 - 瀏覽器必須有一個微任務(wù)隊(duì)列,優(yōu)先執(zhí)行微任務(wù)隊(duì)列里的任務(wù)
在 chrome 中,至少包含以下隊(duì)列:
- 延時隊(duì)列:用于存放計(jì)時器的回調(diào)任務(wù),優(yōu)先級===》中
- 交互隊(duì)列:用于存放用戶操作后產(chǎn)生的事件處理任務(wù),優(yōu)先級===》高
- 微隊(duì)列:用于存放需要最快執(zhí)行的任務(wù),優(yōu)先級===》最高
添加微隊(duì)列的方式主要包括:Promise、MutationObserver