随着网页的加载,每一个HTTP请求都会是瀑布流中的一条。第一条都是文件document的加载,当文件被解析,随后一般是CSS文件的加载。和写在HTML文件中的标签中的顺序是同样的。但浏览器会作一些优化,好比会下降图片的优先度,提高CSS文件的优先度等。web
在瀑布流下方的表格中,咱们能够看到请求的Name,Status,Type等信息。Initiator列的意思是,什么文件需求加载了这一行的文件。按住Shift点击表格的一行,调用该行文件的相应文件会变绿(who called it?),该行文件调用的相应行会变红(who does it called?)。chrome
若是咱们点击Capture Screenshot按钮,从新加载页面, 就能够看到网页的每次repaint,也就是网页是如何加载的。浏览器
使用这个功能,咱们能够知道在慢速网络下,网页是如何呈现出来的。服务器
Network面板中,咱们能够点击文件类型来查看特定类型的文件。左侧有个输入框也能够输入特定条件。好比larger-than:200px,就能够观察大于200px的图片请求。网络
Disable Cache,Offline,Preserve Log三个按钮的功能是显而易见的。chrome-devtools
开发者性能测试是在开发环境中作性能测试,可是用户端是在真实用户使用的状况下记录测试数据。之前是这么作的:函数
const start = new Date().getTime(); const end = new Date().getTime(); const time = end - start;
这样咱们就能够记录下用户做出一个操做的时间,而后将数据post回来。工具
后来有了Performance API:oop
performance.mark('start') performance.mark('end); performance.measure('Our Measurement,'start','end'); performance.getEntriesByType('measure')
通常图片过大的解决方法:布局
还有一个HTML API要知道,srcset
能够在不一样窗口大小的时候加载指定的图片。
<img srcset="small.jpg 300w, medium.jpg 800w, large.jpg 1200w">
可是为了浏览器兼容性,咱们老是应该给默认的src attribute留一个URL。
现代大多数屏幕刷新率都是60帧每秒。1秒/60 = 16.66毫秒。因此咱们的一个画面更新的处理时间若是超过了16毫秒,就感受卡。
有一种卡的缘由是由于,解析Javascript的时间过长。V8引擎渲染页面的时候,须要编译Javascript,生成AST(Abstract Syntax Tree)。当客户端的处理性能不好的时候,就要等好久。
还有一种卡的缘由是由于,Layout thrashing,反复布局,又称布局抖动。
//Read const h1 = element.clientHeight; //Write element1.style.height = (h1 * 2) + 'px'; //Read const h2 = element2.clientHeight; //Write element2.sytle.height = (h2 * 2) + 'px';
当咱们反复进行这种DOM读写操做的时候,就会形成布局抖动。
若是咱们能够将读和写彻底分开,一次性操做全部读,一次性操做全部写,就不会有这种状况,可是这是不现实的。这就是使用window.requestAnimationFrame()的缘由。
简单说requestAnimationFrame将读写操做和屏幕刷新率匹配起来,当浏览器准备好更新下一帧时,作想作的操做,减小性能浪费,避免跳帧。关于这个话题有不少写Event Loop的文章里也有写,这里很少写。
在开发者工具中,咱们在更多工具中能够找到Rendering的选项。
打开这个选项,页面每次repaint的地方都会变成绿色,帮助开发者观察是否一些不必重绘的地方在不停的被重绘,浪费性能。
咱们点击录制按钮,在页面上作一些操做,好比Scroll。Performance面板中就会有一些数据。
最下方有一个饼状图是一个归纳总结。
展开Main行,X轴表明处理时间,Y轴是Call Stack。Y轴高不要紧,只是函数之间不断的调用,可是若是有色块很宽的话就说明处理时间很长。
咱们可使用WASD来操做。按W Zoom In能够看到具体信息。
找到一个很宽的色块,看以前是哪一个色块调用了这个色块,而后咱们就能够在下方Summary面板中找到具体文件名,点击去Sources面板看代码。
当一些内存没有按开发者的意愿被释放的时候,就出现了内存泄漏。
function foo() { bar = "Hi" }
当foo被调用的时候,由于bar没有变量声明关键词const, var, let。JS就会一直向上找这个变量到全局做用域,而后会为你建立一个全局变量bar。当这个函数结束的时候,你觉得这个bar会被回收,但其实它一直留在全局。设想若是这个bar不是“Hi”而是一个拥有不少元素的array,它留在了全局做用域,这并非咱们想要的状况。
顾名思义,计时器没有被取消或移除。
const button = document.getElementById('button); document.body.removeChild( document.getElementById('button) ); }
这里咱们在DOM中移除了这个button,可是以前指向这个元素的reference还在,就是变量button。因此这个reference就留在了内存中。
打开Chrome的任务管理器,确保Javascript Memory列有显示。咱们能够看到每一个标签页的内存使用状况。若是有一个标签页的内存使用不稳定,一直在上升,说明出现了内存泄漏。
在Performance面板记录下的数据中,若是咱们打勾Memory选项,咱们就能够看到Memory行。若是线图不停的上升,就说明出现了内存泄漏。
在开发者工具的Memory面板中,咱们能够选择Heap Snapshot,记录一个当前页面具体内存使用状况的快照。注意Shallow Size列和Retained Size列。
Shallow Size是对象自身占用内存的大小,而Retained Size是指咱们移除Object后能得到多少空间,也就是将对象自己和连同的相关对象一块儿删除后释放的内存大小。好比一个变量指向一个很大的Object,这个变量自己是个reference很小(Shallow Size很小),可是移除这个变量之后,咱们就能够得到很大的空间(Retained Size很大)。
咱们能够根据Shallow Size给Heap Snapshot排序,找到占用内存最多的对象,若是不确认是不是内存泄漏,能够再记录一个Heap Snapshot作对比。若是该对象的Shallow Size增加了,说明确实出现了内存泄漏。咱们能够根据工具给的提示信息,找到开发代码片断作修改。
如今的Audit面板整合了谷歌的Lighthouse服务。网上还有一些其余不错的第三方服务如webpagetest, sonarwhal。