支付寶新首頁(yè)的幾點(diǎn)前端實(shí)踐小結(jié)

一、HTML5 標(biāo)簽的應(yīng)用
HTML5 的應(yīng)用不僅僅是標(biāo)簽的應(yīng)用,但她可以從標(biāo)簽的應(yīng)用開始。打開你的瀏覽器,查看源代碼,你會(huì)發(fā)現(xiàn) <header> <footer> 這些標(biāo)準(zhǔn)已經(jīng)都用上了。還會(huì)發(fā)現(xiàn)一段 HTML5 Shiv 的 JS 代碼:
<!--[if lt IE 9]>
<script type="text/javascript">
// html5shiv MIT @rem remysharp.com/html5-enabling-script
// iepp v1.6.2 MIT @jon_neal iecss.com/print-protector
/*@cc_on(function(a,b){function r(a){var b=-1;while(++b<f)a.createElement(e[b])}if(!(!window.attachEvent||!b.createStyleSheet||!function(){var a=document.createElement("div");a.innerHTML="<elem></elem>";return a.childNodes.length!==1}())){a.iepp=a.iepp||{};var c=a.iepp,d=c.html5elements||"abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",e=d.split("|"),f=e.length,g=new RegExp("(^|\\s)("+d+")","gi"),h=new RegExp("<(/*)("+d+")","gi"),i=/^\s*[\{\}]\s*$/,j=new RegExp("(^|[^\\n]*?\\s)("+d+")([^\\n]*)({[\\n\\w\\W]*?})","gi"),k=b.createDocumentFragment(),l=b.documentElement,m=l.firstChild,n=b.createElement("body"),o=b.createElement("style"),p=/print|all/,q;c.getCSS=function(a,b){if(a+""===undefined)return"";var d=-1,e=a.length,f,g=[];while(++d<e){f=a[d];if(f.disabled)continue;b=f.media||b,p.test(b)&&g.push(c.getCSS(f.imports,b),f.cssText),b="all"}return g.join("")},c.parseCSS=function(a){var b=[],c;while((c=j.exec(a))!=null)b.push(((i.exec(c[1])?"\n":c[1])+c[2]+c[3]).replace(g,"$1.iepp_$2")+c[4]);return b.join("\n")},c.writeHTML=function(){var a=-1;q=q||b.body;while(++a<f){var c=b.getElementsByTagName(e[a]),d=c.length,g=-1;while(++g<d)c[g].className.indexOf("iepp_")<0&&(c[g].className+=" iepp_"+e[a])}k.appendChild(q),l.appendChild(n),n.className=q.className,n.id=q.id,n.innerHTML=q.innerHTML.replace(h,"<$1font")},c._beforePrint=function(){o.styleSheet.cssText=c.parseCSS(c.getCSS(b.styleSheets,"all")),c.writeHTML()},c.restoreHTML=function(){n.innerHTML="",l.removeChild(n),l.appendChild(q)},c._afterPrint=function(){c.restoreHTML(),o.styleSheet.cssText=""},r(b),r(k);if(c.disablePP)return;m.insertBefore(o,m.firstChild),o.media="print",o.className="iepp-printshim",a.attachEvent("onbeforeprint",c._beforePrint),a.attachEvent("onafterprint",c._afterPrint)}})(this,document)@*/
</script>
<![endif]-->
其實(shí)就是這段代碼使這些 HTML5 專屬的標(biāo)準(zhǔn)可以在 IE6 ~ IE8 上運(yùn)行。COPYRIGHT 信息還保留在頁(yè)面代碼上,大家可以自己去研究一下。原理很簡(jiǎn)單,就是用 JS 創(chuàng)建標(biāo)簽讓 IE 低下 9 的版本可以認(rèn)識(shí),然后就直接用了。
標(biāo)簽應(yīng)用需要著重關(guān)注的是其語(yǔ)義的傳達(dá)。像 <header> <footer> 這種很好理解,但像 <section> 和 <aside>,還有類似于用新語(yǔ)義的 <small> 標(biāo)簽等,都是值得大家去深入研究的。這方面這次新首頁(yè)的改版我也有著重強(qiáng)調(diào)過,不過執(zhí)行起來并不是很理想。接下來我會(huì)做一下這方面相應(yīng)的研究,如果你有興趣,可以加入到我的團(tuán)隊(duì)中來。
值得一提的是,HTML5 有一個(gè)特點(diǎn)是“有容乃大”,標(biāo)簽可以非常靈活地去使用。比如可以用 "block-level" links,寫慣了 XHTML 的同學(xué),一定不會(huì)習(xí)慣下面的代碼,甚至?xí)X得不可理喻,但這就是 HTML5 所允許的。
<article>
<a href="story1.html">
<h3>Bruce Lawson voted sexiest man on Earth</h3>
<p><img src="bruce.jpg" alt="gorgeous lovebundle. ">A congress representing all the planet's women unanimously voted Bruce Lawson as sexiest man alive.</p>
<p>Read more</p>
</a>
</article>
所以,上次分享的時(shí)候就說:“團(tuán)隊(duì)協(xié)作,需要我們?nèi)M定一套規(guī)范,來幫助我們?cè)趹?yīng)用 HTML5 的標(biāo)準(zhǔn)時(shí)候,代碼能夠更統(tǒng)一。普遍來說,XHTML 是相對(duì)更符合我們標(biāo)準(zhǔn)的,支付寶也是采用這種方式,有一套約定規(guī)范,我們可以根據(jù) XHTML,將 HTML5 轉(zhuǎn)化成 XHTML5,以更適合我們團(tuán)隊(duì)開發(fā)”。你覺得呢?
二、可訪問性增強(qiáng)與速度提升
這次首頁(yè)改版幾乎整個(gè)頁(yè)面都是 CMS,有個(gè)很變態(tài)的需求是,所有圖標(biāo)都需要運(yùn)營(yíng)可改。換個(gè)說法就是,用內(nèi)存換速度的拼圖片(CSS sprites) 來減少 HTTP 請(qǐng)求數(shù)成了不可能。姐姐啊,HTTP 是換取速度最昂貴的東西,這樣搞,我的頁(yè)面性能該如何是好呢?
其實(shí)像大家可以體驗(yàn)到的。普遍的感受就是,首頁(yè)放的東西比上一版多了,但速度竟然快了不少。另外一個(gè)很明顯的感受是,圖片都是最后出來的。是的,這就是為什么這么多請(qǐng)求,還能快起來的原因。
所謂的延遲加載,把所有圖片都用相應(yīng)的標(biāo)記記錄圖片地址,然后用 JS 去創(chuàng)建一個(gè) img 再把 src 的值變成已經(jīng)標(biāo)記在頁(yè)面中的那個(gè)地址。這樣做有兩個(gè)好處,一是先把文本內(nèi)容顯示出來,再加載圖片,這樣一個(gè)先后的過程會(huì)給用戶心理給用戶安慰,讓其感覺頁(yè)面是正在加載的;一是平行加載圖片,從實(shí)際上加快頁(yè)面的速度。
但這樣做也有一個(gè)風(fēng)險(xiǎn),當(dāng) JS 沒有開啟的時(shí)候,用戶就看不到圖片。所以,我們需要進(jìn)一步增強(qiáng)頁(yè)面的可用性,讓其沒有 JS 的時(shí)候也可以顯示出來。當(dāng)時(shí)想到的就是 <noscript> 標(biāo)簽,專為無 JS 而生的標(biāo)簽?,F(xiàn)在,禁用你瀏覽器的 JS 再訪問支付寶首頁(yè)吧。是吧,還是都有顯示出來吧,目換達(dá)到了。做法是這樣的,按 noscript > img 這樣的結(jié)構(gòu),給每一個(gè) <img> 標(biāo)簽外面都包一個(gè) <noscript> 標(biāo)簽,當(dāng)有 JS 的時(shí)候,用 JS 把 <img> 提到 <noscript> 外面。
在技術(shù)實(shí)現(xiàn)上,有一個(gè)比較麻煩的是:從 noscript 中獲取的 innerHTML,在 firefox 等高級(jí)瀏覽器中是被轉(zhuǎn)義過的 text 文本,而在 ie 中是未轉(zhuǎn)義過的,最重要的是在 ie7 中用 innerHTML 根本就獲取不到。轉(zhuǎn)義是小事,可以寫一個(gè) Hack 來實(shí)現(xiàn),但獲取不到才是最大的問題。所以,我們要用這樣的方式來寫一個(gè) img:
<noscript data-noscript="https://img.alipay.com/sys/homeindex/style/pb.png">
<img src="https://img.alipay.com/sys/homeindex/style/pb.png" alt="新手課堂:快速輕松學(xué)會(huì)支付寶" />
</noscript>
在 <noscript> 標(biāo)簽中添加一個(gè) HTML5 格式的屬性,讓獲取不到 innerHTML 時(shí),獲取其 data-noscript 這個(gè)屬性。然后創(chuàng)建一個(gè) img,并把其 src 的值設(shè)置成 data-noscript 的值。下面給出這次首頁(yè)上我使用的代碼:
// 轉(zhuǎn)義 noscript 中獲取的 innerHTML
HI.text2HTML = function (text) {
if(text.indexOf('<') === -1) return text;
var tmp = document.createElement("DIV");
tmp.innerHTML = text;
return tmp.textContent || tmp.innerText;
}
// 將 img 提取出來,append 到 noscript 標(biāo)準(zhǔn)的前面。
// 使用 insertBefore + fragment 的方式
// hack 兼容各個(gè)瀏覽器
HI.ns2Live = function (ns) {
var img,f = document.createDocumentFragment();
if(ns.innerHTML){
img = D.toDom(HI.text2HTML(ns.innerHTML));
} else {
img = document.createElement('IMG');
img.src = ns.getAttribute('data-noscript');
}
f.appendChild(img);
ns.parentNode.insertBefore(f, ns);
}
不過話說回來,支付寶的登陸控件現(xiàn)在還做得很爛,沒有 JS 的時(shí)候根本就出不來。所以,這個(gè)優(yōu)化也只是蛋痛先做做,還需要控件那邊的升級(jí)。對(duì)于這個(gè),我表示很心痛。
三、優(yōu)化優(yōu)化優(yōu)化
其實(shí)這次改版,想優(yōu)化的東西并沒有全部?jī)?yōu)化上去。比如說,靜態(tài)文件的緩存,其實(shí)可以調(diào)成 1 年(為什么不是像 yahoo 那樣緩存 10 年,其實(shí)這是一個(gè)規(guī)定,只是我已經(jīng)忘記了那個(gè)組織叫什么了。汗);比如 js 和 css 的性能優(yōu)化,圖片的壓縮,無障礙訪問的增強(qiáng),字體增強(qiáng)等等。東西挺多的,首頁(yè)可優(yōu)化的點(diǎn)還是挺可以。但這一次因?yàn)槟承┰?,?xiàng)目被提前一周發(fā)布,沒有做全部?jī)?yōu)化。發(fā)布上去后的有升級(jí)包,但相應(yīng)產(chǎn)品線的人對(duì)于這些性能優(yōu)化也不是很 Care。作為架構(gòu)組的同學(xué),其實(shí)也做不了主,畢竟是別人線的產(chǎn)品,畢竟人家也不愿意。
這里強(qiáng)烈推薦大家看一下 Google 的建議,我的優(yōu)化幾乎都是從這里取經(jīng)得來的:http://code.google.com/speed/page-speed/docs/overview.html
結(jié)語(yǔ)
好吧,就寫到這里。就兩大點(diǎn),其他都摻著說,沒有全部細(xì)化出來。其實(shí)還有更多的東西正在研究中。只是最近一直很懶,也有確實(shí)發(fā)生了很多事情。所以都疲于寫博。人還是應(yīng)該偶爾寫寫博客做做總結(jié),不然腦子很容易轉(zhuǎn)不起來,字也串不成完整的一句話。對(duì)于這次改版的代碼,HTML/CSS 代碼大多是實(shí)習(xí)生同學(xué)寫的,上次在微博上也有提起過。我主要負(fù)責(zé) JS ,大方面的把握和優(yōu)化方面的東西。發(fā)現(xiàn)現(xiàn)在的實(shí)習(xí)生都挺不錯(cuò)的,大三的時(shí)候我還不會(huì)寫代碼呢。哈哈…
相關(guān)文章
15 個(gè)為編程初學(xué)者準(zhǔn)備的網(wǎng)站(都是國(guó)外的一些網(wǎng)站)
今天的文章,我們將分享15個(gè)可以學(xué)習(xí)編程的網(wǎng)站,這些網(wǎng)站上提供了很多編程教程,圖書以及編程練習(xí),希望對(duì)你有用2024-11-02- 這篇文章主要介紹了web開發(fā)中的長(zhǎng)度單位主要包括px,pt,em等,需要的朋友可以參考下2023-08-06
網(wǎng)頁(yè)前端開發(fā)的一些尺寸單位(px,rem單位)
px單位是絕對(duì)單位,一般用于pc端網(wǎng)頁(yè)開發(fā),因?yàn)槭墙^對(duì)單位所以在移動(dòng)端上的使用體驗(yàn)并不是很好,rem它是描述相對(duì)于當(dāng)前根元素字體尺寸,是相對(duì)單位,它可以根據(jù)根元素的變換而2023-08-06WEB前端優(yōu)化必備js/css壓縮工具YUI-compressor詳解與集成用法
壓縮工具層次不窮,各有優(yōu)點(diǎn),選擇適合的壓縮工具為將來做項(xiàng)目開發(fā)使用是一件很重要的事情!!在這介紹YUI-compressor,需要的朋友可以參考下2023-06-21html,css,javascript是怎樣變成頁(yè)面的
瀏覽器是多進(jìn)程的,有瀏覽器主進(jìn)程,網(wǎng)絡(luò)進(jìn)程,渲染進(jìn)程,插件進(jìn)程等,在將html,css,javascript解析成一個(gè)頁(yè)面的時(shí)候,就需要多個(gè)進(jìn)程的分工合作2023-05-01- 本文為大家整理了常用的文件對(duì)應(yīng)的MIME類型,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-25
postman中form-data、x-www-form-urlencoded、raw、binary的區(qū)別介紹
這篇文章介紹了postman中form-data、x-www-form-urlencoded、raw、binary的區(qū)別,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-12-28網(wǎng)頁(yè)中使用Unicode字符的介紹(&#,\u等)
國(guó)際組織制定了可以容納世界上所有文字和符號(hào)的字符編碼方案,稱為Unicode,是通用字符集Universal Character Set的縮寫,用以滿足跨語(yǔ)言、跨平臺(tái)進(jìn)行文本轉(zhuǎn)換、處理的要求2021-11-27前端實(shí)現(xiàn)字符串GBK與GB2312的編解碼(小結(jié))
這篇文章主要介紹了前端實(shí)現(xiàn)字符串GBK與GB2312的編解碼(小結(jié)),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2020-12-02告別硬編碼讓你的前端表格自動(dòng)計(jì)算的實(shí)例代碼
這篇文章主要介紹了告別硬編碼讓你的前端表格自動(dòng)計(jì)算,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-27