摘要:并減少對(duì)樣式的請(qǐng)求。缺點(diǎn)暴露了模塊成員,外部可以修改模塊內(nèi)部狀態(tài)。所有依賴(lài)這個(gè)模塊的語(yǔ)句,都定義在一個(gè)回調(diào)函數(shù)中,等到加載完成之后,這個(gè)回調(diào)函數(shù)才會(huì)運(yùn)行。
HTML&&CSS基礎(chǔ)知識(shí)點(diǎn)整理 一、WEB標(biāo)準(zhǔn):一系列標(biāo)準(zhǔn)的集合
1. 結(jié)構(gòu)(Structure):html 語(yǔ)言:XHTML[可擴(kuò)展超文本標(biāo)識(shí)語(yǔ)言]和XML[可擴(kuò)展標(biāo)記語(yǔ)言] 2. 表現(xiàn)(Preasentation):css 3. 行為(Behavior):JS[DOM+ES]
其中一些小的具體要求:
結(jié)構(gòu):標(biāo)簽小寫(xiě)、閉合、不能隨意嵌套
CSS+JS:精良使用外鏈,不用行內(nèi)
優(yōu)點(diǎn):1. 易于維護(hù) 2. 頁(yè)面響應(yīng)快 3. 可訪(fǎng)問(wèn)性高 4. 提高設(shè)備兼容性 5. 易被解析(搜索引擎)
Ps:
可維護(hù)性:出現(xiàn)問(wèn)題時(shí),修復(fù)Bug成本低且維護(hù)性好,還有一點(diǎn)是代碼能夠被其他開(kāi)發(fā)人員理解。
可訪(fǎng)問(wèn)性:所有人都能理解,解析
二、瀏覽器內(nèi)核> - IE:Trident內(nèi)核(多稱(chēng):IE內(nèi)核) > - Chrome:Webkit內(nèi)核 ==> Blink內(nèi)核 > - Firefox:Gecko內(nèi)核(多稱(chēng):IE內(nèi)核) > - Safari:Webkit內(nèi)核 > - Opear:Preato====>Webkit內(nèi)核 ====> Blink內(nèi)核三、渲染原理 1、涉及到的概念
Dom Tree:瀏覽器將Html解析成屬性的數(shù)據(jù)結(jié)構(gòu)
Parse(構(gòu)建Dom樹(shù)):生成Dom樹(shù)的行為
Css Rule Tree:瀏覽器將Css解析成屬性的數(shù)據(jù)結(jié)構(gòu)
Render Tree:DOM和CSSOM合并后生成Render Tree
Construct(構(gòu)建渲染樹(shù)):解析對(duì)應(yīng)的CSS樣式文件信息(包括js生成的樣式和外部css文件),而這些文件信息以及HTML中可見(jiàn)的指令(如),構(gòu)建渲染樹(shù)
Layout:根據(jù)Render Tree已知各個(gè)節(jié)點(diǎn)以及節(jié)點(diǎn)之間的從屬關(guān)系,計(jì)算節(jié)點(diǎn)在屏幕中的位置
Painting:根據(jù)Layout算出來(lái)的結(jié)果,通過(guò)顯卡,把內(nèi)容滑倒屏幕上
Reflow(回流):當(dāng)瀏覽器發(fā)現(xiàn)某個(gè)部分發(fā)生了點(diǎn)變化影響了布局,需要倒回去重新渲染,這個(gè)回退的過(guò)程
2、==步驟==解析HTML:瀏覽器會(huì)將HTML解析成一個(gè)DOM樹(shù),DOM 樹(shù)的構(gòu)建過(guò)程是一個(gè)深度遍歷過(guò)程:當(dāng)前節(jié)點(diǎn)的所有子節(jié)點(diǎn)都構(gòu)建好后才會(huì)去構(gòu)建當(dāng)前節(jié)點(diǎn)的下一個(gè)兄弟節(jié)點(diǎn)。
解析CSS:將CSS解析成 CSS Rule Tree 。
生成渲染樹(shù):根據(jù)DOM樹(shù)和CSSOM來(lái)構(gòu)造 Rendering Tree。注意:Rendering Tree 渲染樹(shù)并不等同于 DOM 樹(shù),因?yàn)橐恍┫馠eader或display:none的東西就沒(méi)必要放在渲染樹(shù)中了。
布局渲染樹(shù):已知道網(wǎng)頁(yè)中有哪些節(jié)點(diǎn)、各個(gè)節(jié)點(diǎn)的CSS定義以及他們的從屬關(guān)系。從根節(jié)點(diǎn)遞歸調(diào)用,計(jì)算每一個(gè)元素的大小、位置等,給出每個(gè)節(jié)點(diǎn)所應(yīng)該在屏幕上出現(xiàn)的精確坐標(biāo)
繪制渲染樹(shù):遍歷render樹(shù),并使用UI后端層繪制每個(gè)節(jié)點(diǎn)。
3、Reflow{重構(gòu)/回流/重排}(對(duì)應(yīng)Layout 改變了計(jì)算結(jié)果)當(dāng)渲染樹(shù)中的一部分(或全部)因?yàn)樵氐囊?guī)模尺寸,布局,隱藏等改變而需要重新構(gòu)建, 這就稱(chēng)為回流(reflow)。==每個(gè)頁(yè)面至少需要一次回流,就是在頁(yè)面第一次加載的時(shí)候(第一次布局也稱(chēng)作回流)==。4、Repaint/Redraw{重繪}(對(duì)應(yīng)Painting 改變了屏幕顯示樣式)reflow 幾乎是無(wú)法避免的?,F(xiàn)在界面上流行的一些效果,比如樹(shù)狀目錄的折疊、展開(kāi)(實(shí)質(zhì)上是元素的顯示與隱藏:display:none和visibility:hidden)等,都將引起瀏覽器的 reflow。鼠標(biāo)滑過(guò)、點(diǎn)擊……只要這些行為引起了頁(yè)面上某些元素的占位面積、定位方式、邊距等屬性的變化,都會(huì)引起它內(nèi)部、周?chē)踔琳麄€(gè)頁(yè)面的重新渲染。通常我們都無(wú)法預(yù)估瀏覽器到底會(huì) reflow 哪一部分的代碼,它們都彼此相互影響著。
改變某個(gè)元素的背景色、文字顏色、邊框顏色等等==(外觀屬性)==不影響它周?chē)騼?nèi)部布局的屬性時(shí),屏幕的一部分要重畫(huà),但是元素的幾何尺寸==(布局)==沒(méi)有變。5、觸發(fā)Reflow條件
頁(yè)面渲染初始化;(無(wú)法避免)
添加或刪除可見(jiàn)的DOM元素;
元素位置的改變,或者使用動(dòng)畫(huà);
元素尺寸的改變——大小,外邊距,邊框;
瀏覽器窗口尺寸的變化(resize事件發(fā)生時(shí));
填充內(nèi)容的改變,比如文本的改變或圖片大小改變而引起的計(jì)算值寬度和高度的改變;
讀取某些元素屬性:(offsetLeft/Top/Height/Width, clientTop/Left/Width/Height, scrollTop/Left/Width/Height, width/height, getComputedStyle(), currentStyle(IE)
6、觸發(fā)Repaint條件改變?cè)赝庥^屬性。如:color,background-color等。
7、Reflow和Repaint的關(guān)系在回流(重排)的時(shí)候,瀏覽器會(huì)使布局發(fā)生變化。完成回流將變化后的新頁(yè)面繪制到頁(yè)面上,則觸發(fā)重繪。8、display:none和visibility:hidden反之,重繪時(shí)不會(huì)不一定會(huì)使布局發(fā)生變化,這不一定觸發(fā)重排(回流)
有些情況下,比如修改了元素的樣式,瀏覽器并不會(huì)立刻reflow 或 repaint 一次,而是會(huì)把這樣的操作積攢一批,然后做一次 reflow,這又叫==異步 reflow 或增量異步 reflow==。但是在有些情況下,比如==resize== 窗口,改變了頁(yè)面默認(rèn)的字體等。對(duì)于這些操作,==瀏覽器會(huì)馬上進(jìn)行 reflow==。
==重排(回流)必定會(huì)引發(fā)重繪,但重繪不一定會(huì)引發(fā)重排(回流)==
display:none 的節(jié)點(diǎn)不會(huì)被加入Render Tree,如果某個(gè)節(jié)點(diǎn)最開(kāi)始是不顯示的,設(shè)為display:none是更優(yōu)的
visibility: hidden 的節(jié)點(diǎn)會(huì)被加入Render Tree
display:none 會(huì)觸發(fā) reflow,而 visibility:hidden 只會(huì)觸發(fā) repaint,因?yàn)闆](méi)有發(fā)現(xiàn)位置變化。
9、優(yōu)化重排重繪==重繪重排的代價(jià):耗時(shí),導(dǎo)致瀏覽器卡慢==
需要大量重繪重排的場(chǎng)景,例如:動(dòng)畫(huà)
優(yōu)化:
==瀏覽器==自己的優(yōu)化:==(多次攢一次)==瀏覽器會(huì)維護(hù)1個(gè)隊(duì)列,把所有會(huì)引起回流、重繪的操作放入這個(gè)隊(duì)列,等隊(duì)列中的操作到了一定的數(shù)量或者到了一定的時(shí)間間隔,瀏覽器就會(huì)flush隊(duì)列,進(jìn)行一個(gè)批處理。這樣就會(huì)讓多次的回流、重繪變成一次回流重繪。
==程序員==注意的優(yōu)化:減少重繪和重排就是要==減少對(duì)渲染樹(shù)的操作==,可以合并多次的DOM和樣式的修改。并減少對(duì)style樣式的請(qǐng)求。以下:
直接改變?cè)氐腸lassName(==一次改變多個(gè)需要同樣的樣式變化的元素==)
display:none;先設(shè)置元素為display:none;然后進(jìn)行頁(yè)面布局等操作;設(shè)置完成后將元素設(shè)置為display:block;這樣的話(huà)就只引發(fā)兩次重繪和重排;(將重繪重排隱藏起來(lái)操作)
不要經(jīng)常訪(fǎng)問(wèn)瀏覽器的flush隊(duì)列屬性;如果一定要訪(fǎng)問(wèn),可以利用緩存。將訪(fǎng)問(wèn)的值存儲(chǔ)起來(lái),接下來(lái)使用就不會(huì)再引發(fā)回流
使用cloneNode(true or false) 和 replaceChild 技術(shù),引發(fā)一次回流和重繪;(==操作復(fù)制節(jié)點(diǎn),將改變后的節(jié)點(diǎn)一次重新繪制==)
將需要多次重排的元素,position屬性設(shè)為absolute或fixed,元素脫離了文檔流,它的變化不會(huì)影響到其他元素;(==脫離文檔會(huì)不會(huì)再影響頁(yè)面布局==)
如果需要?jiǎng)?chuàng)建多個(gè)DOM節(jié)點(diǎn),可以使用DocumentFragment創(chuàng)建完后一次性的加入document;(==一次改變多個(gè)==)
==盡量不要使用table布局==
四、依賴(lài)管理 五、AMD、CMD和CommonJs 1. 前端模塊規(guī)范有三種:CommonJs,AMD和CMD。* CommonJs用在服務(wù)器端,AMD和CMD用在瀏覽器環(huán)境 * AMD 是 RequireJS 在推廣過(guò)程中對(duì)模塊定義的規(guī)范化產(chǎn)出。 * MD 是 SeaJS 在推廣過(guò)程中對(duì)模塊定義的規(guī)范化產(chǎn)出。 * AMD:提前執(zhí)行(異步加載:依賴(lài)先執(zhí)行)+延遲執(zhí)行 * CMD:延遲執(zhí)行(運(yùn)行到需加載,根據(jù)順序執(zhí)行)2. 模塊
模塊就是實(shí)現(xiàn)特定功能的文件,把幾個(gè)函數(shù)放在一個(gè)文件里就構(gòu)成了一個(gè)模塊。 需要的時(shí)候加載這個(gè)文件,調(diào)用其中的函數(shù)即可。
(1)函數(shù)寫(xiě)法
function f1(){ //... } function f2(){ //... }
==缺點(diǎn)==:
這樣做會(huì)==污染全局變量==,無(wú)法保證不與其他模塊發(fā)生==變量名沖突==,而且==模塊成員之間沒(méi)什么關(guān)系==。
(2)對(duì)象寫(xiě)法
var module = { star : 0, f1 : function (){ //... }, f2 : function (){ //... } }; module.f1(); module.star = 1;
==優(yōu)點(diǎn)==:模塊寫(xiě)成一個(gè)對(duì)象,模塊成員都封裝在對(duì)象里,通過(guò)調(diào)用對(duì)象屬性,訪(fǎng)問(wèn)使用模塊成員。
==缺點(diǎn)==:==暴露了模塊成員==,==外部可以修改模塊內(nèi)部狀態(tài)==。
(3)立即執(zhí)行函數(shù)
var module = (function(){ var star = 0; var f1 = function (){ console.log("ok"); }; var f2 = function (){ //... }; return { f1:f1, f2:f2 }; })(); module.f1(); //ok console.log(module.star) //undefined
==優(yōu)點(diǎn)==:外部無(wú)法訪(fǎng)問(wèn)內(nèi)部私有變量
3.CommonJsCommonJS是服務(wù)器端模塊的規(guī)范,由Node推廣使用。
由于服務(wù)端編程的復(fù)雜性,如果==沒(méi)有模塊很難與操作系統(tǒng)及其他應(yīng)用程序互動(dòng)==。
CommonJS規(guī)范:
一個(gè)多帶帶的文件就是一個(gè)模塊。每一個(gè)模塊都是一個(gè)多帶帶的作用域,也就是說(shuō),在該==模塊內(nèi)部定義的變量,無(wú)法被其他模塊讀取==,除非定義為==global==對(duì)象的屬性。
==輸出模塊變量==的最好方法是使用==module.exports==對(duì)象。
==加載模塊使用require==方法,該方法==讀取一個(gè)文件并執(zhí)行==,==返回文件內(nèi)部module.exports對(duì)象==
使用方法如下:
//math.js exports.add = function() { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) { sum += args[i++]; } return sum; }; //increment.js var add = require("math").add; exports.increment = function(val) { return add(val, 1); }; //index.js var increment = require("increment").increment; var a = increment(1); //2
問(wèn)題:
require 是同步的。模塊系統(tǒng)需要同步讀取模塊文件內(nèi)容,并編譯執(zhí)行以得到模塊接口。 但在瀏覽器端問(wèn)題多多。
原因:
瀏覽器端,加載 JavaScript 最佳、最容易的方式是在 document 中插入script標(biāo)簽。 但腳本標(biāo)簽天生異步,傳統(tǒng) CommonJS 模塊在瀏覽器環(huán)境中無(wú)法正常加載。
解決思路
開(kāi)發(fā)一個(gè)服務(wù)器端組件,對(duì)模塊代碼作靜態(tài)分析,將模塊與它的依賴(lài)列表一起返回給瀏覽器端。 這很好使,但需要服務(wù)器安裝額外的組件,并因此要調(diào)整一系列底層架構(gòu)。
另一種解決思路是,用一套標(biāo)準(zhǔn)模板來(lái)封裝模塊定義:
define(function(require, exports, module) { // The module code goes here });
這套模板代碼為模塊加載器提供了機(jī)會(huì),使其能在模塊代碼執(zhí)行之前,對(duì)模塊代碼進(jìn)行靜態(tài)分析,并動(dòng)態(tài)生成==依賴(lài)列表==。
//math.js define(function(require, exports, module) { exports.add = function() { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) { sum += args[i++]; } return sum; }; }); //increment.js define(function(require, exports, module) { var add = require("math").add; exports.increment = function(val) { return add(val, 1); }; }); //index.js define(function(require, exports, module) { var inc = require("increment").increment; inc(1); // 2 });4.AMD(異步模塊定義)
* AMD是"Asynchronous Module Definition"的縮寫(xiě)。 * 由于不是JavaScript原生支持,使用AMD規(guī)范進(jìn)行頁(yè)面開(kāi)發(fā)需要用到對(duì)應(yīng)的庫(kù)函數(shù)RequireJS * AMD 是 RequireJS 在推廣過(guò)程中對(duì)模塊定義的規(guī)范化的產(chǎn)出 * 采用異步方式加載模塊,模塊的加載不影響它后面語(yǔ)句的運(yùn)行。所有依賴(lài)這個(gè)模塊的語(yǔ)句,都定義在一個(gè)回調(diào)函數(shù)中,等到加載完成之后,這個(gè)回調(diào)函數(shù)才會(huì)運(yùn)行。
==RequireJS主要解決兩個(gè)問(wèn)題:==
多個(gè)js文件可能有依賴(lài)關(guān)系,被依賴(lài)的文件需要早于依賴(lài)它的文件加載到瀏覽器
js加載的時(shí)候?yàn)g覽器會(huì)停止頁(yè)面渲染,加載文件越多,頁(yè)面失去響應(yīng)時(shí)間越長(zhǎng)
==RequireJs采用require()語(yǔ)句加載模塊,不同于CommonJS,它要求兩個(gè)參數(shù):==
第一個(gè)參數(shù)[module],是一個(gè)數(shù)組,里面的成員就是要加載的模塊;
第二個(gè)參數(shù)callback,則是加載成功之后的回調(diào)函數(shù)。math.add()與math模塊加載不是同步的,瀏覽器不會(huì)發(fā)生假死。
require([module], callback); require([increment"], function (increment) { increment.add(1); });
==define()函數(shù)==
RequireJS定義了一個(gè)函數(shù) define,它是全局變量,用來(lái)定義模塊:
define(id?, dependencies?, factory);
==參數(shù)說(shuō)明:==
id:指定義中模塊的名字,可選;如果沒(méi)有提供該參數(shù),模塊的名字應(yīng)該默認(rèn)為模塊加載器請(qǐng)求的指定腳本的名字。如果提供了該參數(shù),模塊名必須是“頂級(jí)”的和絕對(duì)的(不允許相對(duì)名字)。
依賴(lài)dependencies:是一個(gè)當(dāng)前模塊依賴(lài)的,已被模塊定義的模塊標(biāo)識(shí)的數(shù)組字面量。
依賴(lài)參數(shù)是可選的,如果忽略此參數(shù),它應(yīng)該默認(rèn)為["require", "exports", "module"]。然而,如果工廠方法的長(zhǎng)度屬性小于3,加載器會(huì)選擇以函數(shù)的長(zhǎng)度屬性指定的參數(shù)個(gè)數(shù)調(diào)用工廠方法。
工廠方法factory,模塊初始化要執(zhí)行的函數(shù)或?qū)ο蟆H绻麨楹瘮?shù),它應(yīng)該只被執(zhí)行一次。如果是對(duì)象,此對(duì)象應(yīng)該為模塊的輸出值。
define("alpha", ["require", "exports", "beta"], function (require, exports, beta) { exports.verb = function() { return beta.verb(); //Or: return require("beta").verb(); } });
==RequireJs使用例子==
require.config是用來(lái)定義別名的,在paths屬性下配置別名。然后通過(guò)requirejs(參數(shù)一,參數(shù)二);
第一個(gè)參數(shù)是數(shù)組,傳入我們需要引用的模塊名
第二個(gè)參數(shù)是個(gè)回調(diào)函數(shù),回調(diào)函數(shù)傳入一個(gè)變量,代替剛才所引入的模塊。
main.js //別名配置 requirejs.config({ paths: { jquery: "jquery.min" //可以省略.js } }); //引入模塊,用變量$表示jquery模塊 requirejs(["jquery"], function ($) { $("body").css("background-color","red"); });
引入模塊也可以只寫(xiě)require()。requirejs通過(guò)define()定義模塊,定義的參數(shù)上同。在==此模塊內(nèi)的方法和變量外部是無(wú)法訪(fǎng)問(wèn)的==,只有通過(guò)return返回才行.
//將該模塊命名為math.js保存。 //math.js define("math",["jquery"], function ($) {//引入jQuery模塊 return { add: function(x,y){ return x + y; } }; });
//main.js引入模塊方法 require(["jquery","math"], function ($,math) { console.log(math.add(10,100));//110 });5.CMD
* CMD 即Common Module Definition通用模塊定義 * CMD規(guī)范是國(guó)內(nèi)發(fā)展出來(lái)的 * CMD有個(gè)瀏覽器的實(shí)現(xiàn)SeaJS * SeaJS要解決的問(wèn)題和requireJS一樣,只在
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/116996.html
摘要:并減少對(duì)樣式的請(qǐng)求。缺點(diǎn)暴露了模塊成員,外部可以修改模塊內(nèi)部狀態(tài)。所有依賴(lài)這個(gè)模塊的語(yǔ)句,都定義在一個(gè)回調(diào)函數(shù)中,等到加載完成之后,這個(gè)回調(diào)函數(shù)才會(huì)運(yùn)行。 HTML&&CSS基礎(chǔ)知識(shí)點(diǎn)整理 一、WEB標(biāo)準(zhǔn):一系列標(biāo)準(zhǔn)的集合 1. 結(jié)構(gòu)(Structure):html 語(yǔ)言:XHTML[可擴(kuò)展超文本標(biāo)識(shí)語(yǔ)言]和XML[可擴(kuò)展標(biāo)記語(yǔ)言] 2. 表現(xiàn)(Preasentation):css...
摘要:高度模型淺識(shí)為的簡(jiǎn)寫(xiě),簡(jiǎn)稱(chēng)為塊級(jí)格式化上下文,為瀏覽器渲染某一區(qū)域的機(jī)制,中只有和中還增加了和。并非所有的布局都會(huì)在開(kāi)發(fā)中使用,但是其中也會(huì)涉及一些知識(shí)點(diǎn)。然而在不同的純制作各種圖形純制作各種圖形多圖預(yù)警 一勞永逸的搞定 flex 布局 尋根溯源話(huà)布局 一切都始于這樣一個(gè)問(wèn)題:怎樣通過(guò) CSS 簡(jiǎn)單而優(yōu)雅的實(shí)現(xiàn)水平、垂直同時(shí)居中。記得剛開(kāi)始學(xué)習(xí) CSS 的時(shí)候,看到 float 屬性不...
摘要:特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 本以為自己收藏的站點(diǎn)多,可以很快搞定,沒(méi)想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補(bǔ)充。有錯(cuò)誤的地方,還請(qǐng)斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會(huì)及時(shí)更新,平時(shí)業(yè)務(wù)工作時(shí)也會(huì)不定期更...
摘要:一些有用的一些有用的,包括轉(zhuǎn)換小箭頭三角形媒體查詢(xún)等中文指南是當(dāng)下最熱門(mén)的前端資源模塊化管理和打包工具。 nodejs 入門(mén) nodejs 入門(mén)教程,大家可以在 github 上提交錯(cuò)誤 2016 年最好用的表單驗(yàn)證庫(kù) SMValidator.js 前端表單驗(yàn)證工具分享 淺談前端線(xiàn)上部署與運(yùn)維 說(shuō)到前端部署,可能大多數(shù)前端工程師在工作中都是使用的公司現(xiàn)成的部署系統(tǒng),與SRE對(duì)接、一起完...
閱讀 1395·2023-04-25 18:34
閱讀 3456·2021-11-19 09:40
閱讀 2835·2021-11-17 09:33
閱讀 2949·2021-11-12 10:36
閱讀 2837·2021-09-26 09:55
閱讀 2663·2021-08-05 10:03
閱讀 2527·2019-08-30 15:54
閱讀 2873·2019-08-30 15:54