*从理论、实战编码、实战调试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:前端网站性能优化(原创)的更多相关文章

  1. 现代WEB前端的性能优化

    现代WEB前端的性能优化 前言:这只是一份学习笔记. 什么是WEB前端 潜在的优化点: DNS是否可以通过缓存减少DNS查询时间? 网络请求的过程走最近的网络环境? 相同的静态资源是否可以缓存? 能否 ...

  2. web前端页面性能优化

    影响用户访问的最大部分是前端的页面.网站的划分一般为二:前端和后台.我们可以理解成后台是用来实现网站的功能的,比如:实现用户注册,用户能够为文章发表评论等等.而前端呢?其实应该是属于功能的表现. 而我 ...

  3. web前端之性能优化

    作为一个前端工作人员,而且只会写点HTML5和CSS3的“假”前端工程师,为了能更好地理解一下前端的花花世界,最近拜读了<高性能网站建设指南>一书,对作者提出的前端性能优化的14个规则获益 ...

  4. web前端页面性能优化小结

    影响用户访问的最大部分是前端的页面.网站的划分一般为二:前端和后台.我们可以理解成后台是用来实现网站的功能的,比如:实现用户注册,用户能够为文章发表评论等等.而前端呢?其实应该是属于功能的表现. 而我 ...

  5. WEB前端的性能优化

    转自:http://www.2cto.com/kf/201604/498725.html 网站的划分一般为二:前端和后台.我们可以理解成后台是用来实现网站的功能的,比如:实现用户注册,用户能够为文章发 ...

  6. web前端如何性能优化提高加载速度

    前端优化有以下几种途径: 一.减少HTTP请求数量和次数: 二.使用CDN: 三.添加Expires头: 四.压缩组件: 五.将样式表放在头部: 六.将脚本放在底部: 七.避免CSS表达式: 八.使用 ...

  7. input屏蔽历史记录 ;function($,undefined) 前面的分号是什么用处 JSON 和 JSONP 两兄弟 document.body.scrollTop与document.documentElement.scrollTop兼容 URL中的# 网站性能优化 前端必知的ajax 简单理解同步与异步 那些年,我们被耍过的bug——has

    input屏蔽历史记录   设置input的扩展属性autocomplete 为off即可 ;function($,undefined) 前面的分号是什么用处   ;(function($){$.ex ...

  8. 网站性能优化(Yahoo 35条)

    Yahoo 网站性能优化 35条 一.内容部分 尽量减少 HTTP请求 减少 DNS查找 避免跳转 缓存 Ajxa 推迟加载 提前加载 减少 DOM元素数量 用域名划分页面内容 使 frame数量最少 ...

  9. asp.net网站性能优化2则

    摘要:Web服务器的性能优化有很多资料介绍了,多台主机负载均衡,查询结果的多级缓 存,数据库索引优化等都是常见的优化手段.随着后端优化空间越来越小,现在越来越多 的网站更注重前端性能的优化,就是浏览器 ...

随机推荐

  1. Batch Close process

    @echo offecho.rem Kill all chrome drivertaskkill /im chromedriver.exe /f pause

  2. 20175227张雪莹 2018-2019-2 《Java程序设计》第三周学习总结

    20175227张雪莹 2018-2019-2 <Java程序设计>第三周学习总结 教材学习内容总结 (仅在此列举个性化学习总结) 一.编程语言的几个发展阶段. 1.面向机器语言:汇编语言 ...

  3. 为运行Microsoft Dynamics CRM 异步处理服务指定账户没有性能计数器权限

    CRM 2016 安装 为运行Microsoft Dynamics CRM 应用程序指定账户没有性能计数器权限 为运行Microsoft Dynamics CRM 异步处理服务指定账户没有性能计数器权 ...

  4. (转)cenntos 安装mongodb

    转自 https://www.cnblogs.com/layezi/p/7290082.html 安装前注意: 此教程是通过yum安装的.仅限64位centos系统 安装步骤: 1.创建仓库文件: 1 ...

  5. @SuppressLint("HandlerLeak"),或Handler使用有警告;

    随手写个Handler,然后飘黄,看着挺难受(黄色警告的大概意思:Handler可能会内存泄漏,推荐你用静态内部类+实例化弱引用): This Handler class should be stat ...

  6. mongo官方企业版安装及数据库授权使用

    通过安装.deb包的方式,系统是Ubuntu 16.04 1. Import the public key used by the package management system.(导入包管理系统 ...

  7. python第三方库Requests的基本使用

    Requests 是用python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库.它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTT ...

  8. leetcode33

    class Solution { public: int search(vector<int>& nums, int target) { //这个题是给一个排序数组,但是数组里面内 ...

  9. IDEA jrebet插件安装

    破解.exe下载 https://github.com/ilanyu/ReverseProxy/releases/tag/v1.0 双击运行,exe 文件, 然后IDEA -> Help -&g ...

  10. Redux-persist使用

    redux-persist作用是将store中的数据缓存到浏览器中,减少数据请求,每当白名单中的数据发生变化,才会进行一次更新缓存的操作,并且这个数据缓存是存在localStorage中的,不是会话级 ...