Web前端优化初探,小弟抛砖引玉,期待高手共破难关!
前言
其实没想过写前端优化这篇文章来的,因为我自知现在水平达不到这个高度!
但是,你知道面试官很烦的,他每次面试非要问你浏览器兼容与前端优化......,所以我又不得不在这两个上面做一定研究。
上面几个问题,没一定功力的前端不可能答得好的。对于优化这块东西,我也很多正在摸索,实在觉得现在拿不出手啊!但是时间不等人。
比如这段时间参加的一个面试,面试官就非要将我做的页面想象得很卡,而且指定就是前端卡,让我优化,还问我平时会不会注意一些优化的东西。
说实话,平时写代码时候,我惊奇的发现一个事实:
1 我会不自主的将css写成一排:
#tabs { border-bottom: 1px solid #1C87D5; padding: 5px 5px 0; }
2 我写js时,两个等号一定要空格:
var con = document.getElementById('content'); //不用编辑器我写出来的代码排版也不会差
3 在写页面时候我会花10分钟纠结我这里是不是多了一个div
......
通过以上事实,我觉得我已经养成一种规范的“强迫症了”,这里不是要说自己编码多好,而是想说明:
很多优化在平时在意或者不在意之间就已经做了,到后面你就不自主认为他不是优化而是必须了,比如:
for(var i = 0, len = args.length; i < len; i++) {}
但是,我能做的也就是以上的水准罢了,要在往下深入便真的需要具体的项目历练了,所以一旦真正要说到优化,我强烈感觉自己不够格!
不够格不是不研究的理由,不够格我们可以看够格的文章,所以小弟今日就来学习一番,此篇文章参考了以下资料:
于是让我们开始吧!!!在这里我提出一个优化总纲:零流量,无请求!
基本的优化
1 css放在顶部 有时候我们还会将他直接放到页面里面,原因是防止页面裸奔 2 js文件外部引用,放到尾部 script标签没出现一次便会让页面等待期解释执行(这样是有道理的),js逻辑结束后才能继续渲染页面
3 语义化标签
该优化我都差点忽略了,做这个时候还需要注意seo
4 减少请求文件体积:图片合并/外部文件压缩
5 缓存ajax请求
6 注意控制cookie大小和污染
因为cookie是本地文件,每次浏览器都会去读取响应的cookie
7 万万不要使用css表达式
......
现在我们来补充点重要知识:浏览器的重绘与重排
浏览器的重绘与重排
在前端交互中,很多特效会引起浏览器的重绘(redraw)和重排(reflow),需要付出高昂的性能代价(对于不熟悉的我,会有怎样的弊端小的还不得而知呢)。
浏览器从下载文档到显示页面的过程便包含了重绘和重排,通常在文档初步加载时,浏览器引擎将会解析html文档来构建DOM树,之后根据DOM元素的几何属性构建一棵用于渲染的树。
渲染树的每个节点都有大小和边距等属性,类似于盒模型(由于隐藏元素不需要显示,渲染树中并不包含DOM树中的隐藏元素)。
当渲染树构建完毕后,浏览器就可以将元素放置到正确的位置了,再根据渲染树节点的样式属性绘制出页面。
由于浏览器的流式布局,对渲染树的计算通常只需要遍历一次,但table元素需要花上三倍的时间来确定其在渲染树中节点的属性,这也是为什么我们要避免使用table布局的一个原因。
重绘是一个元素外观的改变所触发的浏览器行为,例如改变visibility、outline、背景色等属性,
浏览器会根据元素新属性重新绘制,使元素呈现新的外观,重绘不会带来重新布局,不一定引发重排
重排是比较明显的一种改变,可以理解为渲染树需要重新计算,以下常见操作会触发重排: 1 dom元素的集合属性变化;当dom元素的几何属性变化时,渲染树中的相关节点就会失效,浏览器会根据dom元素的变化重新构建渲染树中失效的节点。
之后会根据新的渲染树重新绘制这部分页面,而且一个元素的重排可能引起连锁反应,如:
容器节点渲染树发送变化时,会导致子节点重新计算,也会触发后续兄弟节点重排,最后每个元素都要重排,性能代价很高。
2 dom树的结构变化;当dom树结构发送变化时(节点增加移动),会触发重排,
浏览器引擎布局过程类似于树结构的前序遍历,当前元素不会影响前面已经遍历过的元素。
所以在在body最后插入元素对页面影响很小,以后少往前面插入元素了。
3 js获取某些属性时也会引起重排;每获取一次便会重排一次,所以获取以下属性后最好缓存:
offset相关属性;scroll相关属性、client相关属性。
另外浏览器大小改变、元素样式改变也会引起重排
1 对元素样式的多次改变可以变为一次:比如几次操作style属性的话,就可以给他赋予一个css
2 将需要多次重排的元素设为绝对定位(position或者fixed),元素脱离文档流便不会影响其他元素
3 由于display: none的元素不在渲染树中,对隐藏元素的操作不会引发其他元素的重排,若是要对一个元素进行复杂操作可以先隐藏之,操作结束后在显示。
4 在在内存中多次操作节点,完成后再添加到文档,例如获取后台数据后,可以先在内存构造完整的html片段,再一次加到文档中去,切记一行行添加
5 使用会引起缓存的属性时,缓存之!
6 为包含图片的元素设定固定高度,以免图片加载结束引起页面下沉而整个重排!任何可能导致页面抖动、位移的因素都应该扼杀,比如页面比较长的话,一开始就让滚动条出现吧,你会发现页面抖动过多你笔记本的风扇会很兴奋的!
7 对于首屏不加载的内容可以使用异步加载方式存储html字符串,按需加载,降低首页渲染时间。
写到这里,我突然发现我曾经十分的戳。。。。很多没注意
静态资源
1 我们的页面会出现许多小图标,但很多小图标完全可以用css实现,比如三角形,在css3规模化使用后,更加应该利用他减少外部图片的引用。
2 资源复用,比如我们一个图片按钮就应该用于各种尺寸。
3 避免404错误
js/html相关
1 ajax数据缓存,情况允许使用本地存储
2 图片/广告位使用滚动显示加载(原因不明)
3 下拉菜单/弹出层中的隐藏内容可以使用<textarea>隐藏,需要才真正显示(这招高)
4 无关紧要数据延迟加载(iframe)
5 事件延迟加载,比如鼠标移到某个文字上需要加载数据并且显示,但是鼠标可能无意义移上去,这种情况下便应该取消事件(又如鼠标按下1秒才可拖动层)
6 避免dom操作,减少事件绑定,减少请求数,遍历数据而非遍历dom
7 若是一个层可拖动的话,不要鼠标每移动1px就改变元素位置,而是其累计5px以上才移动
8 js模块化,若是引起闭包的话,要有意识的清理没用的变量
总结
优化这个命题对我来说还是太大了,我们应该在工作过程中有意识的注意身边的每一个有意思有创意的功能点,看看自己会如何实现的,
我相信长此以往,我有一天也可以对前端优化侃侃而谈,变成真正的高手。
针对前端若是您有好的建议,请一定提出来哦!