资源

性能优化 @google
https://developers.google.com/web/fundamentals/performance/why-performance-matters/
资源加载和页面渲染各方面详细的指南


渲染优化
https://classroom.udacity.com/courses/ud860

网站性能测试工具
https://developers.google.com/speed/pagespeed/insights/

渲染优化

前端渲染过程

http://www.cnblogs.com/coco1s/p/5439619.html

浏览器渲染展示网页的过程,老生常谈,面试必问,大致分为:
1. 解析HTML(HTML Parser)
2. 构建DOM树(DOM Tree)
3. 渲染树构建(Render Tree)
4. 绘制渲染树(Painting)
简单解释一下,通过请求得到的 HTML 经过解析(HTML parser)生成 DOM Tree。
而在 CSS 解析完毕后,需要将解析的结果与 DOM Tree 的内容一起进行分析建立一棵 Render Tree,最终用来进行绘图(Painting)。
一张很经典的图:
性能优化 - 图1



style -> layout -> paint -> composit
https://csstriggers.com/
改变不同的CSS属性会引起上面4个动作中的一个或多个

提升性能的关键点

RAIL
response 100ms
animation 16ms / frame , 浏览器还有其自身任务, 实际10ms至12ms可用, 其中js脚本可用3至4毫秒
idle 50ms 可以用来加载一些后续会用到的东西
load 1s , 加载关键资源, 呈现页面


或者叫LIAR
load / idle / animation / response


requestAnimationFrame

需要动画时, 使用requestAnimationFrame 而不是setTimeout

IE9不支持, 需使用polyfill https://gist.github.com/paulirish/1579671


Web Worker

辣鸡收集

垃圾收集时可能会丢帧

内存管理
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Memory_Management

How To Write Fast, Memory-Efficient JavaScript
https://www.smashingmagazine.com/2012/11/writing-fast-memory-efficient-javascript/

High-Performance, Garbage-Collector-Friendly Code
http://buildnewgames.com/garbage-collector-friendly-code/



样式更改

防止强制同步布局FSL
成因: 循环中每次获取布局相关的属性, 比如offsetHeight等, 会引发layout操作, 然后又修改了CSS属性, 引发reCalculaStyle和layout
layout -> style -> layout
修正: 循环外获取一次layout properties, 循环里修改style属性


How (not) to trigger a layout in WebKit
http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html
一些layout properties:
Element
clientHeight, clientLeft, clientTop, clientWidth, focus(), getBoundingClientRect(), getClientRects(), innerText, offsetHeight, offsetLeft, offsetParent, offsetTop, offsetWidth, outerText, scrollByLines(), scrollByPages(), scrollHeight, scrollIntoView(), scrollIntoViewIfNeeded(), scrollLeft, scrollTop, scrollWidth
Frame, Image
height, width
Range
getBoundingClientRect(), getClientRects()
SVGLocatable
computeCTM(), getBBox()
SVGTextContent
getCharNumAtPosition(), getComputedTextLength(), getEndPositionOfChar(), getExtentOfChar(), getNumberOfChars(), getRotationOfChar(), getStartPositionOfChar(), getSubStringLength(), selectSubString()
SVGUse
instanceRoot
window
getComputedStyle(), scrollBy(), scrollTo(), scrollX, scrollY, webkitConvertPointFromNodeToPage(), webkitConvertPointFromPageToNode()

合成和绘制

创建layer :
transform: translateZ(0) // 因为有的浏览器不支持will-change, 所以需要同时添加这一条null transform hack
will-change: transform // 给浏览器一个提示, 让其决定是否分层
https://developer.mozilla.org/zh-CN/docs/Web/CSS/will-change

tips


使用 transform3d api 代替 transform api,强制开启 GPU 加速

如何使用 Timeline 工具
https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool?utm_source=dcc&utm_medium=redirect&utm_campaign=2016q3

动画

High Performance Animations
https://www.html5rocks.com/en/tutorials/speed/high-performance-animations/

其他小点

chrome性能分析工具的初步使用
https://zhuanlan.zhihu.com/p/41017888
性能优化 - 图2

从输入url开始能做哪些优化
https://segmentfault.com/a/1190000014348854

滚动优化
https://xiangsongtao.github.io/blog/ru-he-chu-li-gun/

querySelector和getElementById性能分析与使用选择

https://blog.csdn.net/hualimeme/article/details/44410895

· 得到的元素不是需要很麻烦的多次getElementBy..的话,尽量使用getElementBy..,因为他快些。
· 得到的元素需要很麻烦的多次getElementBy..组合才能得到的话使用querySelector,方便。
· 看实际情况,你决定方便优先还是性能优先,


性能优化栗子

面向体验的重构优化
https://mp.weixin.qq.com/s/GyBsKNYrUkNc5IAw4UJ6Sw

图标加载方式
数据空闲时预加载
图片高清图加载替换低清图

AB测试验证优化效果
性能优化 - 图3
利用 performance API,就可以获取到上图所示的浏览器各个阶段的时间。
Chrome浏览器 可以用 window.chrome.loadTimes().firstPaintTime;IE8+ 浏览器可以用 window.performance.timing.msFirstPaint;


内存分析

https://blog.csdn.net/bug_zero/article/details/54883083
https://developers.google.com/web/tools/chrome-devtools/memory-problems/?utm_source=dcc&utm_medium=redirect&utm_campaign=2016q3


定位内存泄漏的流程
https://blog.gmem.cc/detect-memleaks-with-devtools

定位内存泄漏需要一些技巧,但是一般都是从快照的Summary视图开始分析。一个常用的工作流程是所谓三快照(three snapshot)技术:
1. 执行必要的预热操作,确保那些需要长期驻留的对象初始化完毕
2. 获取一个快照
3. 执行可能导致内存泄漏的操作
4. 获取一个快照
5. 再次执行你觉得可能导致内存泄漏的操作
6. 再次获取一个快照
7. 选择最后一个快照,在列表顶部选择:性能优化 - 图4
8. 这样,你就可以看到那些在快照1-快照2这个时间段内分配的,到目前为止仍然驻留在内存中的那些对象。这些对象可能是导致内存泄漏的对象
9. 展开对象类型节点,选中一个对象,这时下面的Retainers面板会显示该对象的驻留树——即该对象是如何被其它对象引用的
三快照技术有效的依据是:在应用经过预热(warm-up)阶段之后,分配的新对象一般都是由(定时器/用户)操作触发的、朝生暮死的对象。这些本该朝生暮死的对象如果一直驻留,意味着存在内存泄漏。


内容加载优化

图像加载优化



· Prefer vector formats: vector images are resolution and scale independent, which makes them a perfect fit for the multi-device and high-resolution world.
· Minify and compress SVG assets: XML markup produced by most drawing applications often contains unnecessary metadata which can be removed; ensure that your servers are configured to apply GZIP compression for SVG assets.
· Pick best raster image format: determine your functional requirements and select the one that suits each particular asset.
· Experiment with optimal quality settings for raster formats: don’t be afraid to dial down the “quality” settings, the results are often very good and byte savings are significant.
· Remove unnecessary image metadata: many raster images contain unnecessary metadata about the asset: geo information, camera information, and so on. Use appropriate tools to strip this data.
· Serve scaled images: resize images on the server and ensure that the “display” size is as close as possible to the “natural” size of the image. Pay close attention to large images in particular, as they account for largest overhead when resized!
· Automate, automate, automate: invest into automated tools and infrastructure that will ensure that all of your image assets are always optimized.
https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/image-optimization



知乎文章 https://zhuanlan.zhihu.com/p/30362177

开启gzip压缩静态文件

express

compress中间件

  1. app.use(express.logger());
  2. app.use(express.compress());
  3. app.use(express.static(__dirname + '/html'));
  4. app.use(express.methodOverride());
  5. app.use(express.bodyParser());

Nginx

Nginx默认只能对text/html类型的文件进行压缩。下面的指令为开启Gzip的指令:

  1. gzip on;
  2. gzip_http_version 1.0;
  3. gzip_disable "MSIE [1-6].";
  4. gzip_types text/plain application/x-javascript text/css text/javascript;


如果要能够是Nginx开启图片压缩功能,在配置文件中添加如下代码:

  1. gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-php image/jpeg image/gif image/png;

这里需要注意一下:
1.在gzip_http_version的默认值是1.1,就是说对HTTP/1.1协议的请求才会进行gzip压缩。
如果使用了proxy_pass进行反向代理,那么nginx和后端的upstream server之间是用HTTP/1.0协议通信的
如果使用nginx通过反向代理做Cache Server,前端的nginx没有开启gzip,且后端的nginx上未设置gzip_http_version为1.0,那么Cache的url将不会被gzip压缩。
2.gzip_disable的设置是禁用IE6的gzip压缩IE6的某些版本对gzip的压缩支持不是很好,会造成页面的假死。
对img进行gzip后会造成IE6的假死,把对img的gzip压缩去掉后就正常了。
为了确保其它的IE6版本不出问题,所以加上了gzip_disable配置项。

设置允许压缩的页面最小字节数,页面字节数从header头中的Content-Length中进行获取。

  1. gzip_min_length 1000;

默认值是0,不管页面多大都压缩。
建议设置成大于1k的字节数,小于1k可能会越压越大。 即: gzip_min_length 1024

  1. gzip_proxied expired no-cache no-store private auth;

Nginx作为反向代理的时候启用,开启或者关闭后端服务器返回的结果,匹配的前提是后端服务器必须要返回包含”Via”的 header头。
原文链接:http://caibaojian.com/gzip.html