(注:本人現已不在石豆任職,且石豆官網又進行了一次新的改版,故本文章內容已再也不匹配石豆現有官網)css
這倆星期主要致力於公司官網的改版,今天也算是比較完整地上線(暫時仍是全靜態的),能夠在 http://www.shidou.com 查看效果(舊版是http://www.shidou.com/sdcm/ )。html
效果還不錯,主要提高了交互以及首屏速率。就加載速度來講,從下圖(上方爲舊版,下方爲新版)能夠看出白屏時間和首屏時間均較大幅度下滑,鑑於requireJS無阻塞加載模塊以及部分圖片懶加載的處理,也很好地把首屏加載時間跟整頁加載時間分開:前端
再次訪問的速度也算是翻了幾倍:css3
先說說一些遺憾的地方吧,畢竟不是大企業那樣資源充足,因此沒額外的服務器來作靜態資源CDN處理,並且gulp給靜態資源加md5後綴的方式跟requireJS實在難配合,故也暫不考慮給頁面加expire頭。git
另一些gzip、Etag之類的後端優化,也不屬於我這邊能管理的範疇了,因此有些想優化的東西仍是蠻有心無力。github
下面仍是稍微嘮嗑點有趣的東西。web
兼容處理gulp
新版項目要求是兼容到IE7,但頁面上的確使用了不少的CSS3特性,對於不支持的瀏覽器只能作優雅降級的處理。bootstrap
以產品介紹頁的第一個動畫來講,以常規形式使用了瀏覽器判斷標籤來顯示不一樣內容(IE9-僅顯示一張圖片):後端
<!--[if lte IE 9 ]><div class="low"></div><![endif]--> <!--[if (gt IE 9)|!(IE) ]><!--> <div class="anm-wrap monitored"> <div class="bottom-wrap"> <span class="l1-1"></span> <span class="l1-2"></span> <span class="l2-1"></span> <span class="l2-2"></span> <span class="l3"></span> <span class="l4"></span> <span class="l5-1"></span> <span class="l5-2"></span> <span class="l6-1"></span> <span class="l6-2"></span> <div class="c1-1"></div> <div class="c1-2"></div> <div class="c2-1"></div> <div class="c2-2"></div> <div class="c3"></div> <div class="c4"></div> <div class="c5-1"></div> <div class="c5-2"></div> <div class="c6-1"></div> <div class="c6-2"></div> </div><div class="top"></div> </div><!--<![endif]--> </div>
而在其它css3動畫模塊上,則是儘可能使用 translate3d 來取代 translateX/Y,緣由是IE9不支持這個特性,那麼能夠在它忽略動畫(transition/animation)的狀況下也忽略爲了動畫而設置的方位偏移:
不過有些動畫畢竟須要用上透明度opacity,如動畫起始點設置opacity:0,會致使IE9在不支持動畫的狀況下也顯示爲透明度0,那麼就得常規使用css hack作額外處理。
但在使用gulp-sass編譯sass過程當中,會發現它常常會把一些css hack的特定符號給忽略掉(見issue),故在一位朋友的建議下采用他們公司的hack方法——類區分處理。主要是在html標籤加入對應瀏覽器的css類名:
<!--[if IE 7 ]> <html class="ie7" lang="zh-cn"><![endif]--> <!--[if IE 8 ]> <html class="ie8" lang="zh-cn"><![endif]--> <!--[if IE 9 ]> <html class="ie9" lang="zh-cn"><![endif]--> <!--[if (gt IE 9)|!(IE) ]><!--> <html lang="zh-cn"><!--<![endif]-->
後續咱天然能夠很方便地在樣式中hack任意IE瀏覽器,好比
.ie9 .pd-wrap3 .intro2{ .p-wrap>span,div.info{opacity: 1;} }
另外不得不說,在作CSS3動畫處理過程當中最惱人的無異於要寫一堆兼容代碼,如光是一個 transition 就會有 -webkit/moz/ms/o- 幾種前綴。
因而乎果斷拿sass封裝一個樣式庫來提升工做效率,例如上述的 transition 咱們能夠在一個 _base.scss 中這麼定義:
@mixin transition($content){ transition: $content;-webkit-transition: $content; -moz-transition: $content;-ms-transition: $content; }
而後在其它sass文件中import進來,以@include的形式使用:
@include transition(all .8s cubic-bezier(.15, .73, .37, 1.2));
YEP!就這麼一句話搞定,媽媽不再用操心我花時間複製粘貼改兼容代碼了。
不過有時候transition裏的特性也得加前綴啊,好比 -webkit-transition:-webkit-transform(XXX) 。傻孩紙,再封裝一個方法就能夠咯:
@mixin transition($content){ transition: $content;-webkit-transition: $content; -moz-transition: $content;-ms-transition: $content; } @mixin pTransition($content){ //內部特性也要加前綴的方法 -webkit-transition:-webkit-#{$content};-moz-transition:-moz-#{$content}; -ms-transition:-ms-#{$content};transition: $content; }
實際上咱們要考慮的狀況可能略複雜,但都不在sass話下,好比我在頁面中常常複用一個translate3d和scale特性的樣式定義,那麼能夠用sass這麼包裝:
@mixin scaleNt3d($x:1,$y:1,$a:0,$b:0,$c:0){ transform: scale($x,$y) translate3d($a,$b,$c); -webkit-transform: scale($x,$y) translate3d($a,$b,$c); -moz-transform: scale($x,$y) translate3d($a,$b,$c); -ms-transform: scale($x,$y) translate3d($a,$b,$c); }
綜上能夠知道,在css3動畫模塊的設計過程當中,使用sass/less能極大提升你的工做效率、帶來便捷。
動畫處理
大部分的動畫原理基本在我上篇文章優秀網站看前端 —— 小米Note介紹頁面裏說的七七八八了,主要思想無非仍是 —— 先佈局好動畫最終效果,再添加translate3d等特性將其顯示爲動畫起始的形態,而後經過窗口scroll到當前動畫模塊位置的時候給該模塊加一個置空樣式,把translate3d什麼的效果通通清除掉,這樣便也在transition的做用下動態展現了「清除樣式」的過程。固然animation的形式也是一樣原理。
比較棘手一些的仍是window.onscroll事件卸載的處理吧,拿上述的產品介紹頁來講,我是但願用戶在看完三個選項卡的共8個動畫以後,就直接off掉窗口的滾動事件。
因而拿下述代碼來作處理:
function checkModule(){ var st = $win.scrollTop() + $win.height() - 300, pn = 'p' + flag; func[pn](); for(var i=0;i<arrs[pn].length;i++){ if(!arrs[pn][i] || st<arrs[pn][i]) continue; arrs['e'+flag][i].addClass('act'); arrs[pn][i] = null; if(i>=arrs[pn].length-1) arrs['f'+flag]=1 } if(arrs['f3'] && arrs['f2'] && arrs['f1']) $win.off('scroll',checkModule); }
其中 arrs 的初始模式以下:
arrs = {
p1:[], p2:[], p3:[],
e1:[], e2:[], e3:[]
}
pn用來push各動畫模塊的offset().top,en用來push各動畫模塊容器元素的JQ對象,窗體每滾動一次都會遍歷對應的pn(經過flag識別用戶在瀏覽哪一個選項卡,從而遍歷對應的pn和en)來判斷窗體是否滾到了某個動畫模塊要被觸發的位置,若是是,則給en加上觸發動畫的class。
每處理完en最後一個元素,就會給arrs加上對應的一個屬性fn,而後在 if(arrs['f3'] && arrs['f2'] && arrs['f1']) 爲真的時候卸下窗體的滾動監聽。
另外在合做加盟頁面作了個滾動視覺差效果(錢幣會根據窗體滾動也上下滾動,沒作太大幅度,可能得稍仔細看):
看着玄乎玄乎的,其實實現很是簡單,跟h5和css3也沒啥關係,無非在瀏覽器滾動的時候作判斷和計算,給錢幣一個對應的margin-top值:
//錢幣視覺差滾動 var $win = $(window), purse_h = $("#purse").offset().top, step4_h = $("#step4").offset().top, $moneys = $('span','#intro3'), $m1 = $moneys.slice(0,3), $m2 = $moneys.slice(3,6), $m3 = $moneys.slice(6); $win.on("scroll",function(){ var h = $win.scrollTop() + $win.height(); if( (h <= purse_h) || ($win.scrollTop() > step4_h) ) return; $m1.css("marginTop",(purse_h-h)/5); $m2.css("marginTop",(purse_h-h)/15); $m3.css("marginTop",(purse_h-h)/20); });
其中的 purse_h 和 step4_h 分別是那個紅色大錢袋以及下面那個「04加盟流程」容器距離文檔頂部位置,窗體滾動的時候先判斷是否在它們兩者之間的區域內滾動,是的話纔給錢幣們(這裏把11個錢幣分爲3個部分)作動畫處理。
lazyload
這塊主要針對首屏加載的優化,主要用於首頁的幻燈片處,還有合做加盟頁面。
拿合做加盟頁面來講,有很是多的圖片,篇幅也較長,等待這些圖片的加載會消磨訪問者的耐心。
因而咱們不妨先加載首屏展現的圖片,等DOMReady後再加載非首屏的圖片:
咱們把首屏的圖片和其它部分圖片區分爲兩部分的雪碧圖(圖1,圖2),首屏的雪碧圖作正常加載,其它部分要用到雪碧圖的元素均加上一個class="lazyload"的類,用於腳本檢索。
接着在DOMReady以後給這些元素添加設置了背景圖片的class:
$(".lazyload").addClass('sprite-bg');
因而乎咱們能夠看到其它部分的雪碧圖成功地延遲到最後下載:
總而言之懶加載的實現很簡單,主要是須要有這樣的優化思路,從小處着手。
資源壓縮
新項目除了使用gulp常規化壓縮腳本和樣式外,也使用了gulp-imagemin 來優化圖片大小(建議配合imagemin-pngquant使用):
從項目起始到如今,預計壓縮掉超過1/3的圖片體積。並且擺脫了手動去TinyPNG壓縮圖片的過程,也算是蠻大便利(也謝謝我這邊的UI小歐妹子在PS中就先作了優化處理,特別是首頁幻燈片和banner處基本都轉爲gif格式)。
其它
新版的站點再也不使用舊版的bootstrap佈局,提升渲染效率也減小冗餘資源請求。也將把PC和移動端的版本分開爲獨立文件處理,否則像舊版那樣混雜一塊兒實在不便處理(也是舊版用bootstrap的緣由),交互上也會被侷限。
移動端版的仍處於UI設計過程當中,後續會針對移動頁面進行專版的優化,也打算把阿里的自適配技巧應用過來(前端只需按320的寬度作佈局便可),之後有機會再跟你們分享。
另外在新版的站點上一共使用了倆款第三方字體,用的輔助工具是字蛛:
後續可能還會考慮走相似 r.js 打包項目的形式,之前會以爲這種形式略粗暴,不利於資源複用,但如今會以爲http鏈接創建的開銷優化可能比資源複用更來的重要,有時間想玩玩jspm,聽說包含了打包功能。
就嘮嗑下這些有的沒得,共勉~