1.Web標(biāo)準(zhǔn)
Web標(biāo)準(zhǔn)是由一系列標(biāo)準(zhǔn)組合而成婉弹。一個網(wǎng)頁主要由三部分組成:結(jié)構(gòu)層片挂、表現(xiàn)層和行為層幻林。對應(yīng)的標(biāo)準(zhǔn)也分三方面:
- 結(jié)構(gòu)化標(biāo)準(zhǔn)語言主要包括XHTML和HTML以及XML,
- 表現(xiàn)層標(biāo)準(zhǔn)語言主要包括CSS音念,
- 行為標(biāo)準(zhǔn)主要包括對象模型沪饺,DOM、ECMAScript等闷愤。
結(jié)構(gòu)化標(biāo)準(zhǔn)語言整葡,就是W3C規(guī)定的那樣,
㈠標(biāo)簽的書寫讥脐,需要開始和結(jié)束遭居。單便簽除外;
㈡塊級元素不能放在<p></p>標(biāo)簽里面旬渠。li內(nèi)可以包含div標(biāo)簽俱萍。
㈢塊元素里面可以放在塊和內(nèi)聯(lián),特殊的 p和 h1—h6里面不要放塊元素告丢,li和div可以放很多枪蘑。因為這兩個標(biāo)簽,本身就有容器的屬性
㈣內(nèi)聯(lián)里面要放內(nèi)聯(lián)岖免,不要放塊腥寇。
㈤結(jié)構(gòu)與表現(xiàn)分離
㈥命名一定要規(guī)范
表現(xiàn)層標(biāo)準(zhǔn):
css的書寫,首先要盡可能使用外部引入的方式觅捆,因為結(jié)構(gòu)層盡可能的減少表現(xiàn)層的代碼過多出現(xiàn)。達(dá)到分離的目的麻敌。css的選擇器有哪些栅炒,那些屬性可以繼承,那些不可以繼承术羔。他們之間的優(yōu)先級是怎么樣的赢赊。怎么用最簡潔的css代碼表達(dá)設(shè)計者的想法,而不只是實現(xiàn)設(shè)計者的想法就沒事了级历。我們要的是代碼簡潔释移,代碼過多,反而讓瀏覽器解析很多寥殖,浪費(fèi)時間玩讳。
行為層標(biāo)準(zhǔn):
主要是JavaScript中的知識涩蜘。比如DOM、ECMAScript熏纯。使用javascript中的標(biāo)準(zhǔn)同诫,即可。一般對于用戶的行為樟澜,或者說頁面上的動態(tài)效果的一些特殊實現(xiàn)误窖,我們可以會考慮到使用javascript來進(jìn)行書寫,但是代碼的可復(fù)用性秩贰,模塊化霹俺。變量,作用域毒费”螅可能更多的就是javascript的規(guī)定了。自己把自己的理解程度說出來就可以了蝗罗。
2.標(biāo)簽語義化
什么是語義化艇棕?其實簡單說來就是讓機(jī)器可以讀懂內(nèi)容。web頁面的解析是由搜索引擎來進(jìn)行搜索串塑,機(jī)器來解析沼琉。所以語義化的標(biāo)準(zhǔn)是,盡可能的讓機(jī)器讀懂桩匪。
最初的HTML中如h1~h6打瘪、thead、ul傻昙、ol等標(biāo)簽闺骚,通過標(biāo)簽的語義,最初設(shè)計的想法妆档,來達(dá)到語義化的要求僻爽。如標(biāo)題、表頭贾惦、無序胸梆、有序列表,搜索引擎很好的利用了這些語義化標(biāo)簽抓取內(nèi)容
后來须板,最初定義的HTML語義化標(biāo)簽碰镜,不足以實現(xiàn)對Web頁面各個部分的功能或位置描述,所以Web前端人員利用HTML標(biāo)簽的id和class屬性习瑰,進(jìn)一步對HTML標(biāo)簽進(jìn)行描述绪颖,如對頁腳HTML標(biāo)簽添加如id="footer"或者class="footer"的屬性(值),以“無聲”的方式在不同的前端程序員或者前后端程序員間實現(xiàn)交流甜奄。
制定HTML5的W3C組織采用了諸如header柠横、footer窃款、section等語義化標(biāo)簽,來進(jìn)行頁面布局的設(shè)計想法滓鸠,彌補(bǔ)了采用id="header"或者class="section"等雁乡。
更深層次的語義化,是自己在團(tuán)隊合作的過程中糜俗,對于需要聲明的變量和class踱稍,id。盡可能使用彼此能理解的英文悠抹。這樣減少合作的成本珠月,加快合作的效率。
3.布局和頁面架構(gòu)
布局方面楔敌,分為兩種:代碼上的啤挎,視覺上的。
代碼就是最典型的DIV+CSS布局卵凑,表格布局(table)庆聘,iframe框架(特殊地方使用)布局,具體的使用勺卢』锱校可以對應(yīng)的看一下。目前最流行的是黑忱,div+css布局的方式宴抚。當(dāng)然布局的概念比較廣泛,因為在css中也存在很多布局的方法甫煞,比如float和position菇曲。具體理解的程度,需要自己去詳細(xì)的闡述抚吠。
視覺的布局:比如單頁面的常潮,九宮格的,瀑布流布局楷力,tab切換布局喊式,手風(fēng)琴布局等。
頁面架構(gòu):
在談前端架構(gòu)之前弥雹,需要先探討一下不同人群對前端產(chǎn)生的困惑。前端這個職業(yè)最近幾年才逐漸被認(rèn)可延届,之前一直是低端的代名詞剪勿,所以多數(shù)高手很不屑搞這個。之前的很多項目方庭,人們對前端這塊的要求也只是能用就行厕吉,所以很少會在上面去細(xì)致酱固、深入地建立一套完善體系。而多數(shù)產(chǎn)品的技術(shù)經(jīng)理也會是后端出身的头朱,往往對前端的認(rèn)識還停留在Java Struts那個原始的MVC模型上运悲,或者首先想到的就是GWT和JSF,這是從后端角度出發(fā)的一種視角项钮。用這類思維方式做出來的產(chǎn)品班眯,一般用戶體驗都不會很好。
另一方面烁巫,從界面層上手的人群署隘,他對用戶體驗這方面會把控得比較好,但通常缺架構(gòu)意識亚隙,或者說是軟件工程的意識磁餐。在界面層比較復(fù)雜的情況下,很可能會有失控的趨勢阿弃。對整個系統(tǒng)結(jié)構(gòu)的認(rèn)知程度通常不夠深入诊霹,也缺乏設(shè)計模式等方面的知識。
開發(fā)人員會有一些困惑:
創(chuàng)建項目的時候渣淳,一般沒有人作前端的技術(shù)選型
拿到項目之后脾还,沒有直接可復(fù)制的基礎(chǔ)版本
習(xí)慣于引用第三方組件
趕功能,需要某個組件或者特效
上網(wǎng)搜到一個合適的水由,加進(jìn)來
它還依賴一些別的庫
文件大還是次要的
可能會產(chǎn)生沖突荠呐,樣式也不一致
開發(fā)經(jīng)理也會有一些困惑:
協(xié)作過程感覺有問題
前端人員寫原始界面,包含靜態(tài)界面和特效
開發(fā)人員接著改砂客,加邏輯
發(fā)現(xiàn)有問題要返工了
在誰的代碼基礎(chǔ)上繼續(xù)改泥张?如何合并?
2014年了鞠值,為什么還有這么多人工環(huán)節(jié)媚创?
能自動單元測試嗎?
能自動發(fā)布打包嗎彤恶?
用戶會對這些事情感到煩惱:
長得丑
界面老土
風(fēng)格不一致
速度慢
加載慢
渲染慢
執(zhí)行慢
出錯
架構(gòu)的本質(zhì)是什么钞钙?其實也是一種管理。通常我們所說的管理声离,都是指對于任務(wù)和人員的管理芒炼,而架構(gòu)管的是機(jī)器和代碼。比如說术徊,機(jī)器的部署屬于運(yùn)維的物理架構(gòu)本刽,SOA屬于服務(wù)架構(gòu),那么,前端的架構(gòu)指什么呢子寓?
長期以來暗挑,前端所處的位置是比較偏應(yīng)用層,而且是很薄的一層斜友,而架構(gòu)又要求深度和廣度炸裆,所以之前在前端里面做架構(gòu),好比在小水塘里游泳鲜屏,稍微撲騰兩下就到處碰壁烹看。但最近這幾年來,前端的范圍被大大拓展了墙歪,所以這一層逐漸變得大有可為听系。
怎樣去理解架構(gòu)呢?在早期的文字MUD游戲里虹菲,有這么一句話:“你感覺哪里不對靠胜,但是又說不上來”显矗”在我們開發(fā)和使用軟件系統(tǒng)的過程中浪漠,或多或少會遇到這樣的感覺,有這種感覺就說明架構(gòu)方面可能有些問題霎褐。
在狹義的前端領(lǐng)域址愿,架構(gòu)要處理的很重要的事情是組件的集成。由于JavaScript本身缺乏命名空間這樣的機(jī)制冻璃,多數(shù)框架都傾向于自己搞一套响谓,所以這方面的碎片化是很嚴(yán)重的。如果一個公司的實力不足以自研所有用到的組件省艳,就會一直面臨這方面的問題娘纷。
比如說,在做某個功能的過程中跋炕,發(fā)現(xiàn)需要一個組件赖晶,時間來不及做,就到網(wǎng)上搜了個辐烂,加到代碼里面遏插,先運(yùn)行起來再說。一不小心纠修,等功能做完的時候胳嘲,已經(jīng)引入了無數(shù)種組件了,有很多代碼是重疊的扣草,可能有的還有沖突了牛,外觀也不一致吁系。
環(huán)顧四周的大型互聯(lián)網(wǎng)公司,基本上都有自己的前端框架白魂,比如阿里的Kissy和Arale,騰訊的JX上岗,百度的Tangram福荸,360的QWrap等,為什么肴掷?因為要整合別的框架敬锐,并且在此基礎(chǔ)上發(fā)展適合自己的組件庫,代價非常大呆瞻,初期沒辦法的時候只能湊合台夺,長期來說,所有代碼都可控的意義非常重要痴脾。
那么颤介,是不是一套框架可以包打天下呢,這個真的很難赞赖。對于不同的產(chǎn)品形態(tài)滚朵,如果想要用一套框架去適應(yīng),有的會偏輕前域,有的又偏重辕近,有的要兼容低端瀏覽器,有的又不要匿垄,很難取舍移宅。
常見的前端產(chǎn)品形態(tài)包括:
內(nèi)容型Web站點(diǎn) 側(cè)重渲染方面的優(yōu)化,前端邏輯比重小
操作型B/S系統(tǒng) 以數(shù)據(jù)和邏輯為中心椿疗,界面較規(guī)整
內(nèi)嵌Web的本地應(yīng)用 要處理緩存和一些本地接口漏峰,包括PC客戶端和移動端
另外有Web游戲,因為跟我們的企業(yè)形態(tài)關(guān)系不大变丧,而且也比較獨(dú)特芽狗,所以不包含在內(nèi)。這三種產(chǎn)品的前端框架要處理的事情顯然是不太一樣的痒蓬,所以可以細(xì)分成2-3種項目模板童擎,整理出對應(yīng)的種子項目,供同類產(chǎn)品初始化用攻晒。
最近我們經(jīng)常在前端領(lǐng)域聽說兩個詞:全端顾复、全棧。
全端的意思是鲁捏,原來的只做在瀏覽器中運(yùn)行的Web程序不夠芯砸,還要做各種終端,包括iOS,Android等本地應(yīng)用假丧,甚至PC桌面應(yīng)用双揪。
為什么廣義的前端應(yīng)當(dāng)包含本地應(yīng)用呢?因為現(xiàn)在的本地應(yīng)用包帚,基于很多考慮渔期,都變成了混合應(yīng)用,也就是說渴邦,開發(fā)這個應(yīng)用的技術(shù)疯趟,既包含原生的代碼,也包含了嵌入的HTML5代碼谋梭。這么一來信峻,就造成了開發(fā)本地應(yīng)用的人技能要求較廣,能夠根據(jù)產(chǎn)品的場景瓮床,合理選擇每個功能應(yīng)當(dāng)使用的技術(shù)盹舞。
現(xiàn)在有一些PC端的混合應(yīng)用開發(fā)技術(shù),比如node-webkit和hex隘庄,前者的典型應(yīng)用是Intel? XDK矾策,后者的典型應(yīng)用是有道詞典,此外峭沦,豌豆莢的PC客戶端也是采用類似技術(shù)的贾虽,也有一些產(chǎn)品是用的qt-webkit。這類技術(shù)可以方便做跨平臺吼鱼,極大減少開發(fā)工作量蓬豁。
所以,我們可以看到菇肃,在很多公司地粪,開發(fā)安卓、iOS應(yīng)用的人員跟Web前端的處于同一個團(tuán)隊中琐谤,這很大程度上就是考慮到這種情況蟆技。
全棧的意思是,除了只做在瀏覽器中運(yùn)行的代碼斗忌,還寫一些服務(wù)端的代碼质礼,這個需求又是從哪里來的呢?
這個需求其實來自優(yōu)化织阳。我們要優(yōu)化一個系統(tǒng)的前端部分眶蕉,有這么一些事情可以做:
- HTML結(jié)構(gòu)的優(yōu)化,減少DOM樹的層次等等
- CSS渲染性能的優(yōu)化唧躲,批量寫入DOM變更之類
- 資源文件的優(yōu)化造挽,比如小圖片的合并碱璃,圖像格式的處理,圖標(biāo)字體的使用等
- JavaScript邏輯的優(yōu)化饭入,模塊化嵌器,異步加載,性能優(yōu)化
- 加載字節(jié)量的優(yōu)化谐丢,主要是分?jǐn)偟牟呗?/li>
- HTTP請求的優(yōu)化
這里面嘴秸,除了前三條,其他都可能跟后端有些關(guān)系庇谆,尤其是最后一條。但是前端的人沒法去優(yōu)化后端的東西凭疮,這是不同的協(xié)作環(huán)節(jié)饭耳,所以就很麻煩。
那么执解,如果有了全棧寞肖,這個問題可以怎么解決呢?
比如說衰腌,我們要做最原始的小文件合并新蟆,可以在服務(wù)器做一些配置,把多個合并成一個請求右蕊,比如天貓的某個url:
http://g.tbcdn.cn/kissy/k/1.4.1/??dom/base-min.js,event-min.js,event/dom/base-min.js,event/base-min.js,event/dom/touch-min.js,event/dom/shake-min.js,event/dom/focusin-min.js,event/custom-min.js,cookie-min.js?t=1.js
這個就很明顯是多個文件合并而成的琼稻,9個小文件的請求,合并成了一個64k的文件請求饶囚。
這種簡單的事情可以在靜態(tài)代理服務(wù)器上配置出來帕翻,更復(fù)雜的就比較難了,需要一定的服務(wù)端邏輯萝风。比如說嘀掸,我們有多個ajax請求,請求不同的服務(wù)规惰,每個請求的數(shù)據(jù)量都非常少睬塌,但因為請求數(shù)很多,可能會影響加載性能歇万,如果能把它們在服務(wù)端就合并成一個就好了揩晴。但這個優(yōu)化是前端發(fā)起的,傳統(tǒng)模式下贪磺,他的職責(zé)范圍有限文狱,優(yōu)化不到服務(wù)端去,而這多個服務(wù)很可能是跨產(chǎn)品模塊的缘挽,想要合并瞄崇,放在哪個后端團(tuán)隊都很怪異呻粹。
這可真難辦,就像老虎追猴子苏研,猴子上了樹等浊,老虎只能在下面干瞪眼。但是如果我們能讓老虎上樹摹蘑,這就不是個問題了筹燕。如果有這么一層NodeJS,這一層完全由前端程序員控制衅鹿,他就可以在這個地方做這種合并撒踪,非常的合理。
除此之外大渤,我們常常會用到HTML模板制妄,但使用它的最佳位置是隨著產(chǎn)品的場景而不同的,可能某個地方在前端更好泵三,可能某個地方在后端好些耕捞。到底放在哪合適,只有前端開發(fā)人員才會知道烫幕,如果前端開發(fā)人員不能參與一部分后端代碼的開發(fā)俺抽,優(yōu)化工作也還是做不徹底。有NodeJS之后會怎樣呢较曼,因為不管前端模板還是后端模板磷斧,都是JavaScript的,可以使用同一套庫捷犹,這樣在做調(diào)整的時候不會有代碼遷移的煩惱瞳抓,直接把模板換地方即可。
現(xiàn)在伏恐,也有很多業(yè)務(wù)場景有實時通信的需求孩哑,目前來說最合適的方案是Socket.io,它默認(rèn)使用NodeJS來當(dāng)服務(wù)端翠桦,這也是NodeJS的一個重要使用場景横蜒。
這樣,前端開發(fā)人員也部分參與了運(yùn)行在服務(wù)端的代碼销凑,他的工作范圍從原先客戶端瀏覽器丛晌,向后拓展了一個薄層,所以就有了全棧的稱呼斗幼。至于說這個稱呼還繼續(xù)擴(kuò)展澎蛛,一個前端開發(fā)人員從視覺到交互到靜態(tài)HTML到JavaScript包辦的情況,這個就有些過頭了蜕窿。
以上這些谋逻,主要解決的都是代碼層面的事情呆馁。另外有一個方面,也是需要關(guān)注毁兆,但卻常常不能引起重視的浙滤,那就是前端的工程化問題。
早期為什么沒有這些問題气堕?因為那時候前端很簡單纺腊,復(fù)雜度不高,現(xiàn)在整個很復(fù)雜了茎芭,就帶來了很多管理問題揖膜。比如說整個系統(tǒng)的前端都組件化了之后,HTML會拆分成各種模板梅桩,JavaScript會拆分成各種模塊壹粟,而CSS也通過LESS或者SASS這種方式,變成了一種編譯式的語言摘投。
這時候,我們考慮一個所謂的組件虹蓄,它就比較麻煩了犀呼。它可能是一個或者多個HTML模板,加上一個或者多個JavaScript模塊薇组,再包含CSS中的一部分構(gòu)成的外臂,而前兩者都可能有依賴項,三個部分也都要避免與其他組件的沖突律胀。
這些東西都需要管理宋光,并且提供一種比較好的方案去維護(hù)。在JavaScript被模塊化之后炭菌,也可以通過單元測試來控制它們的質(zhì)量罪佳,并且把這個過程自動化,每次版本有變更之前黑低,保證它們最基本的正確性赘艳。最終,需要有一種自動化的發(fā)布機(jī)制克握,把這幾類代碼提取蕾管,打包合并,壓縮菩暗,發(fā)布掰曾。
這個主題展開可以講很多,所以我們不在本次分享中涉及停团。在我之前的幾篇文章中旷坦,也闡述過觀點(diǎn)掏熬。
目前這方面研究最深入的是之前百度FIS團(tuán)隊的張云龍,他的幾篇文章在這里塞蹭,強(qiáng)烈推薦閱讀孽江。
后記:
這篇文章是我入職蘇寧之后第一次公開分享,目標(biāo)受眾主要是后端出身的技術(shù)經(jīng)理番电,目的是讓這個群體能有更多的前端意識「谄粒現(xiàn)在公司的項目基本都有前端模塊,但人員專職程度較低漱办,水平也參差不齊这刷。蘇寧的戰(zhàn)略口號之一是提升用戶體驗,從產(chǎn)品角度看娩井,用戶體驗的提升并非是UI做幾個圖暇屋,搞一些花哨效果就可以了,它是一個系統(tǒng)工程洞辣,涉及從用戶習(xí)慣調(diào)研咐刨、產(chǎn)品設(shè)計、前端開發(fā)扬霜、甚至后端服務(wù)等一系列環(huán)節(jié)定鸟,需要從易用度、觀感著瓶、加載性能联予、流暢度等各方面共同提升。
這些東西都需要從全局角度作規(guī)劃,從源頭控制起,否則只能是頭疼醫(yī)頭坛缕,腳痛醫(yī)腳。為此卷胯,基礎(chǔ)技術(shù)中心會逐步整合幾套適合不同場景的基礎(chǔ)前端框架,作為種子項目供今后的技術(shù)選型使用威酒。此外诵竭,還會從前端開發(fā)的各種主題組織一些技術(shù)分享,并且逐步形成一套制度化兼搏,流程化的培訓(xùn)體系卵慰。