(注:本人现已不在石豆任职,且石豆官网又进行了一次新的改版,故本文章内容已再也不匹配石豆现有官网)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,听说包含了打包功能。
就唠嗑下这些有的没得,共勉~