什么是表现? (What is performance?)
Creating a high performance web site is a delicate dance. Many people think it’s just about how fast your JavaScript performs. The reality is that it’s far more than that. There are also multiple ways to measure performance.
创建一个高性能的网站是一种微妙的舞蹈。 许多人认为这只是JavaScript的执行速度。 现实是,它远不止于此。 还有多种衡量绩效的方法。
The first is load time. From the time that a user clicks a link or enters a URL into the address bar, how long does it take to load that page? Even this has multiple definitions as there’s one hand where it’s how long it takes to completely load the page and on the other hand it’s the user’s perception of how long before the page does something useful or is responsive.
首先是加载时间。 从用户单击链接或在地址栏中输入URL开始,加载该页面需要多长时间? 即使这样也有多种定义,一方面是完全加载页面需要多长时间,另一方面是用户对页面执行有用或响应之前需要多长时间的感知。
For example, you could load the main content and make the page available for interaction while you programmatically go back to the server and grab the rest of the content.
例如,当您以编程方式返回服务器并获取其余内容时,可以加载主要内容并使页面可用于交互。
The second performance metric is more complicated. This one is about how fast animations and interactions on your site perform in the browser.
第二个性能指标更为复杂。 这是关于您的网站上的动画和交互在浏览器中执行得如何快速的信息。
Web运行时架构 (Web Runtime Architecture)
In both cases, it takes a great understanding of the web runtime architecture to tune either of these cases. I’m deliberately saying web runtime architecture rather than the IE runtime architecture because all of the browsers have roughly the same architecture when talking about it at this level because they are all implementing the same standards. They may have different names for their subsystems or have optimized one over the other but in general this is the flow of every browser.
在这两种情况下,都需要对Web运行时体系结构有很好的了解,才能对这两种情况进行调优。 我故意说的是Web运行时体系结构而不是IE运行时体系结构,因为在此级别上讨论时,所有浏览器都具有大致相同的体系结构,因为它们都实现相同的标准。 他们可能为子系统使用不同的名称,或者对它们的名称进行了优化,但总的来说,这是每个浏览器的流程。
Roughly, there are three categories of things to think about, those that affect network, those that affect the CPU and those that affect the GPU.
大致而言,需要考虑三类问题:影响网络的因素,影响CPU的因素和影响GPU的因素。
网络 (Network)
The first thing that happens is networking. Networking starts when the URL is first entered. For now, I’ll be talking about starting with an HTML page but the reality is that networking handles whatever type of resource that’s referenced by the page including XML, JSON, IMG, PDF, etc. and different subsystems come into play for various resources.
发生的第一件事是网络。 首次输入URL时开始联网。 现在,我将讨论从HTML页面开始,但现实是,网络可以处理页面所引用的任何类型的资源,包括XML,JSON,IMG,PDF等,并且各种资源可以使用不同的子系统。 。
But let’s start with an HTML file. Firstly, the browser begins downloading the HTML file and as it’s downloaded, pre-processing begins. Pre-processing looks into the file for anything else that the HTML references that the browser could start downloading. This includes CSS files, JavaScript files, images or whatever is referenced by the file.
但是,让我们从HTML文件开始。 首先,浏览器开始下载HTML文件,并在下载后开始预处理。 预处理会在文件中查找HTML引用的浏览器可以开始下载的其他任何内容。 这包括CSS文件,JavaScript文件,图像或文件引用的任何内容。
This is important because the browser needs to have all of the referenced content at hand as quickly as possible because it’s all interdependent; the HTML relies on the CSS and the JavaScript, the JavaScript can only talk to the DOM which is built from the HTML and the CSS doesn’t have anything to style without the HTML DOM which the JavaScript can manipulate. Yes, that’s a bit confusing but hopefully it will make more sense here shortly.
这很重要,因为浏览器需要相互之间相互依赖,因此需要尽快处理所有引用的内容。 HTML依赖于CSS和JavaScript,JavaScript只能与通过HTML构建的DOM对话,而没有JavaScript可以操纵HTML DOM,CSS则无法样式化。 是的,这有点令人困惑,但希望不久后在这里会更有意义。
An important issue to consider is that, per the spec, browsers are only allowed to open six simultaneous connections to any given server and a connection is needed for each resource specified in the HTML. That doesn’t sound like a lot of connections when you look at pages that have a lot of image content, JavaScript files, CSS files such as Facebook, Pinterest or the like. In fact, it sounds quite crippling.
要考虑的一个重要问题是,根据规范,浏览器仅允许打开到任何给定服务器的六个同时连接,并且HTML中指定的每个资源都需要一个连接。 当您查看包含大量图像内容,JavaScript文件,CSS文件(例如Facebook,Pinterest等)的页面时,听起来并没有很多联系。 实际上,这听起来很残酷。
It’s actually up from where the spec started which was two simultaneous connections! The reason for this limitation is to help a server detect a Denial of Service Attack (DOS or DDOS), where the client opens up as many connections as possible and takes as much of the bandwidth from the server as they possibly can. The good news about the six limit is that it allows the browser to go get more content at the same time.
实际上是从规范开始的地方开始的,它是两个同时连接的! 出现此限制的原因是为了帮助服务器检测拒绝服务攻击(DOS或DDOS),在此情况下,客户端将打开尽可能多的连接,并从服务器获取尽可能多的带宽。 关于这六个限制的好消息是,它允许浏览器同时获取更多内容。
The vast majority of web sites that I see have all of the content coming from the same site. Best practice where there’s a number of images, CSS, JavaScript or other assets is to split those resources across different domains. This is one of the quick wins for using a CDN (Content Delivery Network). This also why it makes sense to use a hosted version of common JavaScript frameworks rather than putting it on your own server.
我看到的绝大多数网站的所有内容都来自同一网站。 有大量图像,CSS,JavaScript或其他资产的最佳实践是将这些资源分配到不同的域中。 这是使用CDN(内容交付网络)的捷径之一。 这也是为什么使用通用JavaScript框架的托管版本而不是将其放在您自己的服务器上才有意义的原因。
解析器 (Parsers)
Once an item is downloaded, it goes to the parsers. There are dozens of parses that parse everything including — but not limited to — HTML, CSS, XML, XHTML, SVG, JavaScript and variations on all of these. The job of the parsers is to create the internal data structures that the browser will be using for the rest of the processing.
项目下载后,将转到解析器。 有数十种语法可以解析所有内容,包括但不限于HTML,CSS,XML,XHTML,SVG,JavaScript以及所有这些语言的变体。 解析器的工作是创建浏览器将在其余处理中使用的内部数据结构。
I’m over-simplifying the job of the parsers, and just covering those could be an entire separate article. The important part about the conversation at the moment is that writing well-formed documents — HTML, XML, XSLT, JSON… — can improve your load time.
我过分简化了解析器的工作,仅涵盖这些内容可能是一整篇单独的文章。 目前关于对话的重要部分是编写格式正确的文档(HTML,XML,XSLT,JSON等)可以缩短加载时间。
内部数据结构 (Internal Data Structures)
There are a number of different internal data structures that the browser needs to accomplish its tasks. The best known of these is the DOM (Document Object Model). If you’ve done any JavaScript programming on a web site before, you’ve probably interacted with the DOM at some level. The general thought is that the DOM is slow and painful. The reality is something more complicated.
浏览器需要完成许多不同的内部数据结构才能完成其任务。 其中最著名的就是DOM(文档对象模型)。 如果您以前在网站上进行过任何JavaScript编程,则可能已在某种程度上与DOM进行了交互。 人们普遍认为DOM缓慢而痛苦。 现实更复杂了。
Every time something touches the DOM, it affects everything downstream from there. Why that’s a problem will become clearer in just a bit.
每当事物接触DOM时,它都会影响DOM下游的所有内容。 为什么会出现问题,这一点很快就会变得更加清楚。
Another very important structure to understand is the CSS Cascade. This is an amalgamation of all of the CSS rules that are referenced in the HTML and all of the CSS files as well as the rules that are set programmatically by JavaScript. It incorporates all of the orders of precedence as to what overrides what and so on.
要理解的另一个非常重要的结构是CSS级联。 这是HTML和所有CSS文件中引用的所有CSS规则以及JavaScript编程设置的规则的合并。 它合并了关于什么优先于什么的所有优先顺序,依此类推。
JavaScript (JavaScript)
The JavaScript sandbox is where JavaScript parsing, byte code generation, native code generation and all of the execution of JavaScript happens. This is why JavaScript is safe to run inside of browsers. It’s not that it’s a safe language. Quite the contrary, it’s an incredibly powerful language that if unchecked could run rampant over everything on your machine.
JavaScript沙箱是JavaScript解析,字节代码生成,本机代码生成以及所有JavaScript执行的地方。 这就是JavaScript在浏览器内部安全运行的原因。 不是说这是一种安全的语言。 恰恰相反,这是一种非常强大的语言,如果不对其进行检查,它可能会席卷您计算机上的所有内容。
Rather, it’s safe because JavaScript only has two ways out of the sandbox – to call the DOM API or to call the network via XHR requests. There are a ton of frameworks that help with both of these tasks – jQuery is one of the most popular. The $(“path statement”) syntax is incredibly powerful as a selector for the DOM. The $.getJSON() method is an incredibly simple to use and fast method of making AJAX requests.
相反,它是安全的,因为JavaScript仅有两种出入沙箱的方式–调用DOM API或通过XHR请求调用网络。 有大量的框架可以帮助完成这两项任务-jQuery是最受欢迎的框架之一。 $(“path statement”)语法作为DOM的选择器非常强大。 $.getJSON()方法是一种非常简单易用的快速AJAX请求方法。
样式–格式和布局 (Styling – Formatting and Layout)
The next step, styling, actually covers two subsystems.
下一步,样式化实际上涵盖了两个子系统。
The first styling subsystem is formatting. Formatting is important because the DOM tree is completely ignorant to anything visual. All it knows is the parent child relationships between the elements and the attributes. It’s the CSS cascade that knows all of that information. During formatting this information is joined up giving the DOM elements size, color, backgrounds, font sizes and so on.
第一个样式子系统是格式化。 格式化很重要,因为DOM树对于任何视觉效果都是完全无知的。 它所知道的只是元素和属性之间的父子关系。 CSS级联知道所有这些信息。 在格式化期间,此信息会合并在一起,从而提供DOM元素的大小,颜色,背景,字体大小等。
At the end of this subsystem, the individual elements each know what they look like.
在该子系统的末尾,各个元素都知道它们的外观。
The next step, now that all of the DOM elements know what they look like, is to figure out how they look together on the page – this is the layout process.
既然所有DOM元素都知道它们的外观,那么下一步就是弄清楚它们在页面上的外观-这是布局过程。
CSS is inherently a block based layout. This means that everything; images, paragraphs, divs, spans, event shapes such as circles, are actually blocks to CSS. The big question is how big of a block. And HTML/CSS is inherently a flow based layout unless something overrides that. This means that the content, by default, will go to the next available top right-hand corner in which it fits.
CSS本质上是基于块的布局。 这意味着一切; 图像,段落,div,范围,事件形状(例如圆圈)实际上是CSS的块。 最大的问题是一个块有多大。 HTML / CSS本质上是一种基于流的布局,除非有某些东西可以覆盖它。 这意味着默认情况下,内容将转到适合该内容的下一个可用右上角。
So if your screen is 800px wide, and you have four elements that are 300px wide each, you’ll fit two across the top and the third one will go on the next row of items. The CSS Cascade can override this however and position items either in a relational or absolute manner. If it’s relational, its position is dictated to be a certain distance from the previous item that was laid out on the screen.
因此,如果您的屏幕是800像素宽,并且您有四个每个300像素宽的元素,那么您将在顶部放两个元素,而第三个元素将放在下一行项目中。 CSS级联可以覆盖此内容,但是可以以关系或绝对方式放置项目。 如果是关系型的,则其位置应与上一个在屏幕上布置的项目相距一定距离。
If it’s absolute, it ignores all of the rules and is laid out a certain distance from the uppermost right hand corner of the page. In this case, it’s likely that it will even be positioned over another item on the screen.
如果是绝对值,它将忽略所有规则,并与页面的右上角相距一定距离。 在这种情况下,它甚至可能会放在屏幕上的另一个项目上。
As such, the primary job of the layout engine is to put all of the blocks on the screen. This includes positioning objects based on their relative or absolute positioning, wrapping or scaling things that are too wide and all of the other things that go into that lightning round of Tetris that is required.
这样,布局引擎的主要工作就是将所有块都放在屏幕上。 这包括根据对象的相对或绝对位置对对象进行定位,包装或缩放太宽的对象以及进入“俄罗斯方块”闪电周期所需的所有其他对象。
At the end of the layout phase, the browser has an internal structure called the display tree. This is an interesting data structure. Some folks ask why browsers don’t just use the DOM tree but it’s not a 1-1 relationship between the items in the DOM tree and the items in the display tree. While this may take a moment to get your head around, it makes sense.
在布局阶段结束时,浏览器具有称为显示树的内部结构。 这是一个有趣的数据结构。 一些人问为什么浏览器不仅使用DOM树,还不是DOM树中的项目与显示树中的项目之间的1-1关系。 尽管这可能需要一点时间才能引起注意,但这是有道理的。
There are things that are in the DOM tree that are not in the display tree such as elements that are display:none or input fields that are type=hidden. There are also things that are in the display tree that are not in the DOM tree such as the numbers on an ordered list ( <ol><li>asdf</li></ol> ).
DOM树中的某些内容不在显示树中,例如display:none或type = hidden的输入字段。 显示树中还有一些东西不在DOM树中,例如有序列表( <ol><li>asdf</li></ol> )上的数字。
涂料和合成 (Paint and Compositing)
At this point, the styling is done and the display tree is ready to paint. There’s a careful choice of words there in that the browser is ready to paint but is not painting just yet. What’s next requires the hardware to tell the browser the next time to do a paint to the screen. Monitors can only paint so many times a second. Most modern day ones do that 60 times a second, thus the 60 hertz refresh rate.
至此,样式已完成,并且显示树已准备好绘制。 浏览器可以绘画,但目前还不能绘画,因此可以仔细选择单词。 接下来需要硬件通知下一次浏览器在屏幕上绘画。 监视器每秒只能涂漆多次。 当今大多数人每秒做60次,因此刷新频率为60赫兹。
This means that it’s 1000/60 (milliseconds divided by the refresh rate) on most monitors between refreshes which works out to 16.67 milliseconds (roughly). That doesn’t sound like a lot of time but in reality a modern day I7 processor can run roughly 2138333333 instructions (Millions of instructions per second as noted in Wikipedia on Instructions per Second/60). Between me and you, that’s a lot of instructions.
这意味着大多数显示器在两次刷新之间为1000/60(毫秒除以刷新率),大约为16.67毫秒。 听起来似乎不花很多时间,但实际上现代I7处理器可以运行大约2138333333条指令(如Wikipedia在“每秒指令数/ 60”中指出的那样,每秒可以执行数百万条指令)。 在我和您之间,有很多指示。
It’s not infinite but it’s a lot. It means that the computer can do roughly 35638889 instructions between monitor refreshes.
它不是无限的,但是很多。 这意味着计算机在显示器刷新之间可以执行大约35638889条指令。
When the monitor is ready to paint, it sends the hardware interrupt which initiates the paint cycle. At this point, the browser paints the layers of the page to the surface which for IE is DirectX surfaces which are composited and displayed on the monitor for your user’s enjoyment by the Desktop Windows Manager (DWM).
当监视器准备好绘画时,它将发送硬件中断,以启动绘画周期。 此时,浏览器将页面的各层绘制到表面上(对于IE,该表面是DirectX表面),DirectX表面经过合成并显示在监视器上,以供桌面Windows管理器(DWM)使用。
相互作用 (Interaction)
At this point, the browser has shown something on the screen so this is load time. However, there is no animation yet or any interaction.
此时,浏览器已经在屏幕上显示了一些内容,因此这就是加载时间。 但是,还没有动画或任何交互。
Interaction includes things such as mouse, pointer or keyboard events. All of these touch the page in some form or fashion. When a user touches the screen somehow, the browser will have to look at the formatting and layout to see what was touched. Then it has to look through the DOM to see if there was a corresponding event that needed to be fired when that item was touched. If an event is found, then JavaScript can kick off and execute the event code, touching the DOM tree.
交互包括鼠标,指针或键盘事件。 所有这些都以某种形式或方式触摸页面。 当用户以某种方式触摸屏幕时,浏览器将不得不查看格式和布局以查看被触摸的内容。 然后,它必须遍历DOM以查看是否有相应事件需要在触摸该项目时触发。 如果找到事件,则JavaScript可以启动并执行事件代码,只需触摸DOM树即可。
Hopefully at this point you can see the issue there. Touching the DOM tree means that the display tree is no longer an accurate representation of the DOM. This means that the browser needs to redo the layout and the formatting and get ready to re-paint.
希望此时您可以在那里看到问题。 触摸DOM树意味着显示树不再是DOM的准确表示。 这意味着浏览器需要重做布局和格式并准备重新绘制。
This is what I meant earlier when I said that describing the DOM as being “slow” is complicated. It’s not that manipulating the DOM is particularly slow by itself. What’s slow is that touching it creates the domino effect of forcing the other subsystems to trigger.
这就是我之前所说的,将DOM描述为“慢速”是很复杂的。 并不是说操作DOM本身就特别慢。 缓慢的是,触摸它会产生强迫其他子系统触发的多米诺骨牌效应。
Web运行时体系结构概述 (Recap of the Web Runtime Architecture)
Hopefully this gives you a picture of the entire web runtime architecture. There’s not one specific component that drives performance of your site. It’s a myriad of things and in fact, sometimes focusing on one thing will cause another to suffer. For example, if you combine all of your JavaScript files into one, that’s only one file that needs to be downloaded but it also means your page is potentially blocked until that entire JavaScript file has been downloaded and parsed.
希望这可以为您提供整个Web运行时体系结构的图片。 没有哪个特定的组件可以提高网站的性能。 这是无数的事情,实际上,有时专注于一件事会导致另一件事受苦。 例如,如果您将所有JavaScript文件合并为一个,则仅是一个文件需要下载,但这也意味着您的页面可能被阻止,直到下载并解析了整个JavaScript文件为止。
Understanding what to do to get the best performance reduce the impact of those decisions is what makes the difference between a good and a truly great web developer.
了解如何做才能获得最佳性能,可以减少这些决策的影响,从而使优秀的和真正的优秀Web开发人员有所不同。
翻译自: https://www.sitepoint.com/what-makes-website-high-performance/