欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

前端性能优化

程序员文章站 2024-03-17 17:37:16
...

作为一个前端工程师,每次完成一个项目后,我都会好奇要怎么评估自己的作品?

网站可以划分为前端和后台。前端的用户体验决定了用户是否愿意去使用网站的功能,网站功能最终影响用户是否会一票否决前端的体验。从而放弃使用该网站。应该从用户体验、网站功能(功能应该都能实现,对前端而言,代码效率会好些)、还有网站推广(略)方面来评估。

关系到用户体验的因素有很多,比如速度、交互式、浏览器支持等,但速度决定是一个重中之重的一块。站长之家提到网站的1秒钟延迟等同于转化率丢失7%,客户满意度降低16%。57%的消费者会因为超过3秒未能打开一个网站而选择离开。

1、速度

这个速度要怎么评估呢?四个时间节点:开始渲染时间(白屏时间)、DOM Ready、首屏时间、onload。
2012年11月29日,工信部正式发布了《宽带速率的测试方法用户上网体验》规范标准[3] ,把“首屏响应时间”做为用户上网体验的指标。首屏响应时间,即从用户在浏览器输入某个网页地址后(或者网站搜索页点击链接跳转)到 该网页渲染整个浏览器屏幕的时间而不是该页面的“总加载时间。
查看首屏的时间的方式:谷歌浏览器打开网页,按F12,选择Network,点击屏幕抓屏工具,(可以先清掉浏览器缓存)按F5刷新。

前端性能优化
上图显示,这个网站首屏响应时间(2.36s后页面不再发生变化)需要2.36s,总共144 个HTTP请求,全部请求处理完总共需要4s,其中load需要1.54s。
影响首屏响应时间的因素:请求数量和处理请求的时间+页面渲染的时间
要优化首屏响应时间,就应该从请求方面和页面渲染方面考虑。
浏览器发起请求到页面正常渲染所经历的每个阶段:

   预处理(Resource Scheduling)->DNS解析(Stalled/DNS Lookup)->建立连接(Inital connection)->发起HTTP请求(Request sent)->等待响应(Waiting)->接收数据(Content Download)->处理元素->布局渲染

谷歌有查看每个请求所需要的时间。步骤:谷歌浏览器按F12->点击Network ->按F5->把鼠标放到彩色条形图上。就能看到这个请求的每个阶段所花费的时间。
前端性能优化
从宏观方面来优化:

  • 首屏总共有144个HTTP请求,处理每个请求的都需要消耗一定的时间,减少HTTP请求无疑能减少整个首屏的响应时间。所以《高性能网站建设指南》提出的第一条规则就是建议减少HTTP请求,响应的技术有:采用CSS
    Sprites、图片地图、内联图片、js脚本合并、懒加载技术、浏览器缓存(ETag)、ajax缓存(get请求可缓存、post不支持缓存)等。
  • 渲染:在下载js时浏览器不会并行处理其他请求,这样会造成阻塞。而且当DOM元素出现隐藏/显示、尺寸变化、位置变化的时候,浏览器都会重新渲染页面。所以css样式表放在顶部,将js脚本放在底部,这样既能减少页面重绘,也剔除了下载js时的阻塞影响,同时也实现了网页的逐步渲染效果,防止白屏或者出现无样式的网页效果。

从每个请求的处理阶段来优化:

  • DNC解析优化:DNS缓存、减少DNS查找、keep-alive、适当的主机域名(2~4个)、使用内容分发网络。
  • 等待响应时间优化:优化后台数据处理速度、避免重定向
  • 接收数据阶段优化:压缩组件(采用gzip编码压缩HTTP响应包)、精简JavaScript、移除重复脚本、使用压缩后的文件(html、js、css)、采用响应式图片、精简cookie的内容。
  • 布局渲染:避免在CSS中使用Expressions(原因:计算频率过高,耗费cpu资源)

2.交互式

交互式涉及到成品设计及业务逻辑,这方面主要由产品经理把关。前端工程师除了完成产品需求指定的功能外,在实现功能的过程中还需要考虑到功能外的细节,考虑用户在使用这个功能的时侯,可能需要什么信息。而且这些在网页功能测试的时候,测试工程师一般都会指出来哪里需要微调,怎么才做才符合用户使用习惯或怎么样用户用起来比较顺手。

3、浏览器支持

浏览器的支持,主要涉及到浏览器的兼容性及移动端的适配。
兼容性产生的原因:不同浏览器的内核不同,导致各个浏览器对网页的解析产生差异。
解决浏览器兼容性问题,应该都是从html、css或者js。
比如:

  • IE9以下版本不支持HTML5标签,需要添加js支持
在html添加:
    <!--[if lt IE 9]>  
    <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>  
    <![endif]--> 
  • IE 兼容模式
IE 支持通过特定的 <meta> 标签来确定绘制当前页面所应该采用的 IE 版本。除非有强烈
的特殊需求,否则最好是设置为 edge mode,从而通知 IE 采用其所支持的最新的模
式。
<meta http-equiv="X-UA-Compatible" content="IE=Edge">

浏览兼容性问题太多,我先收集下,然后另起一篇写这个。

总结:从上面提及用户体验这块优化方案来分析,涉及到前端代码优化这一块的主要有
1.减少HTTP请求: CSS Sprite(PNG8格式)、图片地图、内联地图、js脚本合并、懒加载、ajax缓存(get请求)
2.处理阶段优化:精简JavaScript、移除重复脚本、使用压缩(html、js、css源码)后的文件、避免css使用表达式、使用外部css样式表(首页可以考虑内联)和js文件、样式表放在head里面link引用、js放在body底部闭合标签之前、精简cookie
3.浏览器支持:编写浏览器兼容性代码、考虑是否需要支持移动端

二、从代码效率来优化:
在谈及代码效率前,推荐下web性能分析工具YSLOW。这个插件是yahoo开发的,对应了yahoo推出的23条优化规则
前端性能优化

内存泄漏测试工具:chrome 自带的 Devtools 的network Performance Memory
相关的文章:https://www.cnblogs.com/snowwhite/p/6067571.html

2.1 html优化:
- 标签结构语言化。
- 避免空的src和href。当为空值时,浏览器默认设置为当前页面的URL。
- 合理构架,DOM结构尽量简单。减少不必要的嵌套。
- 减少iframe的使用
- id和class,在能看明白的基础上简化命名,在含有关键字的连接词中连接符号用‘-’,不用‘_’
- 利用LocalStorage合理缓存资源
- 尽量多滴缓存文件
- 使用HTML Web Workers 来允许多线程公正
- 为不同的Viewport 设置不同大小的Content
- 代码压缩

2.2.css
- 尽量将样式写在单独的css文件里面,在head元素中引用
- 不使用@import
- 避免使用复杂的额选择器,层级越少越好,层级最好不要超过三层
- 精简页面的样式文件,合并样式、去掉不用的样式
- 利用css继承减少代码量,可继承的属性:color,font-size,font-family等
- CSS解析是从右到左解析,尽量使用最具体的类别、避免后代选择器、属于标签类别的规则永远不要包含子选择器

2.3.js

DOM 优化 (在react vue anglarjs流行的现在,Dom操作应该会被慢慢边缘化了)

  • 多节点修改时,用cloneNode 然后用replace与原始节点互换
    var orig = document.getElementById('container');
  var clone = orig.cloneNode(true);
  var list = ['foo', 'bar', 'baz'];
  var content;
  for (var i = 0; i < list.length; i++) {
     content = document.createTextNode(list[i]);
     clone.appendChild(content);
  }
  orig.parentNode.replaceChild(clone, orig);
  • 添加多节点时,创建DoumentFragment,然后再添加到页面
  • 最小化DOM访问次数,尽可能在js端执行
  • 如果需要多次访问某个DOM节点,请先用局部变量存储
  • 如果可能的话,使用速度更快的API,比如querySelectorAll和firstElementChild
  • 要留意重绘和重排
    reflow:计算页面元素的几何信息
    repaint:绘制页面元素
  • 使用事件委托来减少事件处理器的数量
  • DOM操作和交互需要消耗大量事件来重新渲染整个(部分)页面,所以DOM更新越多,代码完成执行时间越长
  • 创建节点的方法:createElement 和appenChild()
  • 在DOM操作之前,把要操作的元素,先从当前DOM结构总删除,这样可以减少回流
  • 将获取DOM数据缓存起来

全局变量
当一个变量被定义在全局作用域中,默认情况下Javascript 引擎不会将其销毁,直到页面被关闭。

  • 手工解除变量引用

    在业务代码中,一个变量已经确定不再需要了,就可以手工解除变量引用,以使其被回收。

  • 变量查找优化

    慎用全局变量,全局变量需要搜索更长的作用域链,生命周期鼻局部变量长不利于内存释放,容易造成混淆。
    重复调用全局变量时,可以通过局部缓存来提速

回调函数:

回调函数是一种后续传递风格(Continuation Passing Style,
CPS)的技术,这种风格的程序编写将函数的业务重点从返回值转移到回调函数中去。而且其相比闭包的好处也有很多。
如果传入的参数是基础类型(如字符串、数值),回调函数中传入的形参就会是复制值,业务代码使用完毕以后,更容易被回收。
通过回调,我们除了可以完成同步的请求外,还可以用在异步编程中,这也就是现在非常流行的一种编写风格。
回调函数自身通常也是临时的匿名函数,一旦请求函数执行完毕,回调函数自身的引用就会被解除,自身也得到回收

三、代码可维护性的优化:
搜了很久都没找到怎么设计代码易于代码后期维护。这方面后期我找到了再补充。

参考:
http://blog.csdn.net/mahoking/article/details/51472697
http://blog.csdn.net/grandpang/article/details/51329289
http://www.chinaz.com/web/2015/0414/398424.shtml
https://www.cnblogs.com/Chen-XiaoJun/p/5757524.html
https://www.zhihu.com/question/19812118
http://blog.csdn.net/cherry_zhang18/article/details/77505831
http://blog.csdn.net/cengjingcanghai123/article/details/48581513
https://www.cnblogs.com/zzhui/p/5048130.html
https://www.cnblogs.com/mysun-shine/p/6434377.html
http://www.qdfuns.com/notes/21128/db10afdde2abe5f0b72d5945358987e3.html

相关标签: 性能优化