(O)WEB:前端网站性能优化(原创)
*从理论、实战编码、实战调试3个方面学习前端性能优化(包括页面加载时间和页面流畅度):
-------------------------------理论-------------------------------
*浏览器的完整渲染过程
①输入url,发送请求
②加载(即下载)整个.html文件
③加载完后解析(即运行)html,并在解析的过程中构建DOM树
·JavaScript是单线程的。浏览器是多线程的:有的线程负责加载资源,有的线程负责执行脚本,有的线程负责渲染界面。
·浏览器按从上之下(深度遍历)的原则解析各个html标签
·解析标签的过程就是构建DOM树的过程
·解析遇到link、script、img标签时,浏览器会向服务器发送请求资源。
script加载时不影响其他资源加载,但由于不知道js中的执行内容,所以需要等JS加载并执行完后才会继续解析和渲染。
script的执行会阻塞html解析、其他下载线程以及渲染线程。
link加载完css后会解析为CSSOM(层叠样式表对象模型,一棵仅含有样式信息的树)。css的加载和解析不会阻塞html的解析,但会阻塞渲染。
img的加载不会阻塞html的解析,但img加载后并不渲染,它需要等待Render Tree生成完后才和Render Tree一起渲染出来。未下载完的图片需等下载完后才渲染。
④当css解析为CSSOM后,html解析为DOM后,两者将会结合在一起生成Render Tree(渲染树)。
⑤Layout(reflow): 计算出Render Tree每个节点的形状和位置。(很耗性能)
⑥Painting(repaint):浏览器绘制这些元素的样式,颜色,背景,大小及边框等。(很耗性能)
⑦Composite(层叠时):浏览器会将各渲染层的信息发送给GPU,GPU会按照合理的顺序合并图层然后显示到屏幕上。(GPU合成图像,单独线程,更流畅,但耗内存)
*渲染时长
大多数电脑显示器的刷新频率是60Hz,大概相当于每秒钟重绘60次,因为小于这个频率,页面的渲染就会出现卡顿现象,影响用户体验。大多数浏览器都会对重绘操作加以限制,不超过显示器的重绘频率,因为即使超过那个频率用户体验也不会有提升。因此,最平滑动画的最佳循环间隔是1000ms/60,约等于16.6ms。
-------------------------------编码实战-------------------------------
*前端加载优化:
·使用外联CSS和JS:让浏览器缓存,减少http请求。可利用webpack在引用的资源后面自动增加hash值,实现引用不变的基础上对浏览器缓存的资源进行更新。对于缓存容量小的问题,可以考虑缓存在localStorage。
·合并CSS、JS:减少http请求。
·按需加载:webpack的打包思路就是从程序逻辑入手:入口文件 => 分析代码 => 找出依赖 => 打包,这样代码里不引用的模块就不可能被打进包里,有效减少体积。
·按JS模块加载:例如echart中如果只用k线图就只加载k线模块。
·压缩HTML、CSS、JS:减少资源大小。
·图标采用base64:减少http请求。
·图标采用雪碧图(svg、font-icon):减少http请求,减少资源大小。
·图片压缩:picdiet(https://www.picdiet.com/zh-cn),是用JS编码,无大小、尺寸、数量限制,默认可平均减少50%体积,清晰度基本没损失,没有兼容性问题,也可以调节压缩比。
·避免图片和iFrame等的空src:减少http请求。
·图片:滚屏懒加载。
·CDN加速:常用资源使用CDN加速提高资源响应速度,如jquery、echarts。(http://www.bootcdn.cn/)
·BigRender首屏渲染优化:html, js, css和图片都放在textarea中懒加载(https://segmentfault.com/a/1190000006744741)。
·增加Loading进度条:将加载情况呈现给用户。
*服务端加载优化:
·缓存一切可缓存的资源:http缓存。
·使用长Cache,避免304重定向:在移动端网络不稳定的前提下,多一次请求,就多了一部分加载时间。
·使用DNS缓存:减少浏览器会在DNS解析中消耗的时间。
·启用GZip:GZip是http协议的一部分,用来压缩网页大小的。
·图片压缩:默认生成缩略图传前端。
·减少Cookie:Cookie会影响加载速度,所以静态资源域名不使用Cookie。
·域名解析:减少域名解析次数——减少跨站外部资源的引用。
·创建连接:减少连接创建次数——使用Keep-Alive避免重复连接。
·等待响应:提高服务器运行速度——提高数据运算及查询速度。
*HTML、CSS结构优化:
·页面的标签越少,页面的加载速度就越快,响应也更加迅速。
·css不能阻塞加载,所以将css放在头部,防止白屏和重排重绘造成的内容闪烁现象。
·尽量保持class的简短,如:.box:nth-last-child(-n+1) .title,改为:.final-box-title。
·用flex布局取代浮动布局。
·移除空的CSS规则:空的CSS规则增加了CSS文件的大小,且影响CSS树的执行。
·不声明过多的font-size:过多的font-size引发CSS树的效率。
·值为0时不需要任何单位:为了浏览器的兼容性和性能,值为0时不要带单位。
·display属性会影响页面的渲染,需合理使用:
①display:inline后不应该再使用width、height、margin、padding以及float
②display:inline-block后不应该再使用float
③display:block后不应该再使用vertical-align
④display:table-*后不应该再使用margin或者float
*DOM性能优化:主要是防止重排和重绘
·图片、音频和视频的宽高在加载完成之前为0,所以静态资源加载前需规定图片的大小。
·尽量避免重设图片大小:多次重设图片大小会引发图片的多次重绘
·多使用requestAnimationFrame(待学习)
·如果同时添加父元素和子元素,要在内存中先将所以子元素添加到父元素下,将父元素一次性加入DOM树。
·如果同时添加多个平级子元素,要先将平级子元素加入文档片段,再将文档片段整体加到页面。具体为:
①创建文档片段:var frag=document.createDocumentFragment();文档片段: 内存中临时存储多个平级子元素的虚拟父元素。
②将平级子元素,先追加到frag下: 用法同普通父元素
③将文档片段,整体添加到页面
·先把dom节点display:none;(会触发一次重排)。然后做大量的修改后,再把它显示出来。
·clone一个dom节点在内存里,修改之后;与在线的节点相替换。
·尽量使用ID选择器,ID选择器是最快的。
·每次Dom选择都要计算,缓存他,避免强制同步布局(force reflow)。
·对于修改元素多个样式,可以使用cssText属性,避免强制同步布局。例如如下,触发3次重排:
var el = document.getElementById('myDiv');
el.style.borderLeft = '1px';
el.style.borderRight = '2px';
el.style.padding = '5px';
改成这样,只需1次重排:
var el = document.getElementById('myDiv');
el.style.cssText = 'border-left: 1px; border-right: 2px; padding: 5px;';
将多个样式变化定义到一个class中,再通过className添加class也行。
·动画多使用transform和opacity,他们只会引起合成,不会引起布局和重绘。
·如果图层中某个元素需要重绘,那么整个图层都需要重绘。用translateZ(0)手动创建渲染层,减少需渲染的像素数,还可以用GPU加速。但是不要滥用这个属性,否则会大大增加内存消耗。(详情:https://developers.google.cn/web/fundamentals/performance/rendering/simplify-paint-complexity-and-reduce-paint-areas)
·不要使用table布局,一个小改动会造成整个table的重新布局。
·用css动画而不是js动画:css动画有一个重要的特性,它是完全工作在GPU上。因为你声明了一个动画如何开始和如何结束,浏览器会在动画开始前准备好所有需要的指令;并把它们发送给GPU。而如果使用js动画,浏览器必须计算每一帧的状态;为了保证平滑的动画,我们必须在浏览器主线程计算新状态;把它们发送给GPU至少60次每秒。除了计算和发送数据比css动画要慢,主线程的负载也会影响动画; 当主线程的计算任务过多时,会造成动画的延迟、卡顿。所以尽可能地使用基于css的动画,不仅仅更快;也不会被大量的js计算所阻塞。
·减小复合层的尺寸:可以将图片的尺寸减少5%——10%,然后使用scale将它们放大;用户不会看到什么区别,但是你可以减少大量的存储空间。
·采用虚拟DOM技术:例如Vue、React等框架就采用了虚拟DOM。
*script优化:
·我们知道脚本加载和运行会阻塞页面,所以应该把<script>标签放到最后。
·JS:throttle函数(节流):每XX秒内只执行一次;(https://github.com/jacksplwxy/gecko.js)
·JS:debounce函数(防抖):当连续触发函数调用时,在最后一次触发的XX秒以后才开始一次调用。(https://github.com/jacksplwxy/gecko.js)
·对于多条件判断,用钩子机制比if-else快。
·避免快速连续的布局:
改善前:function resizeWidth() {
// 会让浏览器陷入'读写读写'循环
for (var i = 0; i < paragraphs.length; i++) {
paragraphs[i].style.width = box.offsetWidth + 'px';
}
}
改善后:var width = box.offsetWidth;
function resizeWidth() {
for (var i = 0; i < paragraphs.length; i++) {
paragraphs[i].style.width = width + 'px';
}
}
·深入原形链越深,搜索的速度就会越慢。记住,搜索实例成员的过程比访问直接量或者局部变量负担更重,所以增加遍历原形链的开销正好放大了这种效果。
·函数作用域链的搜索也会消耗性能,全局变量总是在作用域链的最后,所以耗时最久。最好尽可能使用局部变量。一个好的经验法则是:用局部变量存储本地范围之外的变量值。
·成员嵌套越深,访问速度越慢。 location.href 总是快于window.location.href ,而后者也要比window.location.href.toString()更快。如果这些属性不是对象的实例属性,那么成员解析还要在每个点上搜索原形链,这将需要更长时间。
·计算简化,如:for(var i=2;i<=Math.sqrt(n);i++){if(n%i==0){return false}}
·前面提到每帧的渲染应该在16ms内完成,但在动画过程中,由于已经被占用了不少时间,所以JavaScript代码运行耗时应该控制在3-4毫秒。如果真的有特别耗时且不操作DOM元素的纯计算工作,可以考虑放到Web Workers中执行。
-------------------------------调试实战-------------------------------
①资源请求调试:chrome→F12→network→刷新→分析请求时间过长的资源
②渲染调试:chrome→F12→performance→录制→生成报告→对红色性能部分进行分析。中文资源:https://segmentfault.com/a/1190000011516068
(对于不理解的地方可以百度关键词,基本都有资源可以参考学习。本人后续还会继续补充细节,觉得不错就请点个赞吧!)
(O)WEB:前端网站性能优化(原创)的更多相关文章
- 现代WEB前端的性能优化
现代WEB前端的性能优化 前言:这只是一份学习笔记. 什么是WEB前端 潜在的优化点: DNS是否可以通过缓存减少DNS查询时间? 网络请求的过程走最近的网络环境? 相同的静态资源是否可以缓存? 能否 ...
- web前端页面性能优化
影响用户访问的最大部分是前端的页面.网站的划分一般为二:前端和后台.我们可以理解成后台是用来实现网站的功能的,比如:实现用户注册,用户能够为文章发表评论等等.而前端呢?其实应该是属于功能的表现. 而我 ...
- web前端之性能优化
作为一个前端工作人员,而且只会写点HTML5和CSS3的“假”前端工程师,为了能更好地理解一下前端的花花世界,最近拜读了<高性能网站建设指南>一书,对作者提出的前端性能优化的14个规则获益 ...
- web前端页面性能优化小结
影响用户访问的最大部分是前端的页面.网站的划分一般为二:前端和后台.我们可以理解成后台是用来实现网站的功能的,比如:实现用户注册,用户能够为文章发表评论等等.而前端呢?其实应该是属于功能的表现. 而我 ...
- WEB前端的性能优化
转自:http://www.2cto.com/kf/201604/498725.html 网站的划分一般为二:前端和后台.我们可以理解成后台是用来实现网站的功能的,比如:实现用户注册,用户能够为文章发 ...
- web前端如何性能优化提高加载速度
前端优化有以下几种途径: 一.减少HTTP请求数量和次数: 二.使用CDN: 三.添加Expires头: 四.压缩组件: 五.将样式表放在头部: 六.将脚本放在底部: 七.避免CSS表达式: 八.使用 ...
- input屏蔽历史记录 ;function($,undefined) 前面的分号是什么用处 JSON 和 JSONP 两兄弟 document.body.scrollTop与document.documentElement.scrollTop兼容 URL中的# 网站性能优化 前端必知的ajax 简单理解同步与异步 那些年,我们被耍过的bug——has
input屏蔽历史记录 设置input的扩展属性autocomplete 为off即可 ;function($,undefined) 前面的分号是什么用处 ;(function($){$.ex ...
- 网站性能优化(Yahoo 35条)
Yahoo 网站性能优化 35条 一.内容部分 尽量减少 HTTP请求 减少 DNS查找 避免跳转 缓存 Ajxa 推迟加载 提前加载 减少 DOM元素数量 用域名划分页面内容 使 frame数量最少 ...
- asp.net网站性能优化2则
摘要:Web服务器的性能优化有很多资料介绍了,多台主机负载均衡,查询结果的多级缓 存,数据库索引优化等都是常见的优化手段.随着后端优化空间越来越小,现在越来越多 的网站更注重前端性能的优化,就是浏览器 ...
随机推荐
- SQL特殊comment语法
SQL 注释的特殊用法: /*!版本号 语句*/ 表示大于等于某个版本是,才执行相应的语句. 在版本为5.7.23的MySQL上做测试如下: 测试1 mysql> select 1 /*!507 ...
- [转]vs2010用 boost.python 编译c++类库 供python调用
转自:http://blog.csdn.net/wyljz/article/details/6307952 VS2010建立一个空的DLL 项目属性中配置如下 链接器里的附加库目录加入,python/ ...
- Linux之文件(目录)默认权限、特殊权限与隐藏权限
文件默认权限 从Linux之用户组.文件权限详解了解到文件与目录的基本权限管理,文件在创建时如果不指定具体的权限,那么系统会给它分配一个默认的权限,这个默认权限就是umask. vbird@Ubunt ...
- AR外包,就找北京动点软件,长年承接AR外包(案例丰富可签合同,内附案例演示)
北京团队长年承接AR项目外包 咨询QQ:372900288 微信:liuxiang0884 以下是AR项目案例演示,索取更多案例请通过以上方式在线联系我们
- Excel技巧--巧用差异化插入空行
假设有上面这一列,要求在不同城市之间插入一空行相隔开.数据少的时候可以手动操作,但数据量大时,就需要以下技巧: 1.复制该列(除去标题),并粘贴到右侧一列,但上方要隔开一个单元格B2: 2.将这两列选 ...
- Delphi2009之TImage
TPngImage原来是SourceFroge上的一个开源项目,现在突然消失了,为什么呢?Nick 在他的博客上写到:TPNGImage被CodeGear/Embarcadero收购了,现在直接就是D ...
- Deployment Descriptor Web.xml
Deployment Descriptor部署描述符: - 部署描述符是要部署到Web容器或EJB容器的Web应用程序或EJB应用程序的配置文件. - 部署描述符应包含EJB应用程序中所有企业bean ...
- RabbitMQ--windows10环境下的RabbitMQ安装步骤(转)
https://blog.csdn.net/weixin_39735923/article/details/79288578
- Java 身份证号码验证
身份证号码验证 1.号码的结构 公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成.排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码 2.地址码(前 ...
- centos svn强制要求提交代码时写注释
1. 重命名svn主目录中hooks的pre-commit.tmpl文件为pre-commit,并添加可执行权限 mv pre-commit.tmpl pre-commit chmod u+x pre ...