域名系统(DNS)提供了域名和 IP 的对应关系,就像电话本中人名和他们的电话号码的 关系一样。当你在浏览器地址栏中输入www.800hr.com时,DNS解析服务器就会返回这个 域名对应的 IP 地址。DNS 解析的过程同样也是需要时间的。一般情况下返回给定域名对 应的 IP 地址会花费 20 到 120 毫秒的时间。而且在这个过程中浏览器什么都不会做直到 DNS 查找完毕。
缓存 DNS 查找可以改善页面性能。这种缓存需要一个特定的缓存服务器,这种服务器一 般属于用户的 ISP 提供商或者本地局域网控制,但是它同样会在用户使用的计算机上产 生缓存。DNS 信息会保留在操作系统的 DNS 缓存中(微软 Windows 系统中 DNS Client Service)。大多数浏览器有独立于操作系统以外的自己的缓存。由于浏览器有自己的 缓存记录,因此在一次请求中它不会受到操作系统的影响。
InternetExplorer 默认情况下对 DNS 查找记录的缓存时间为 30 分钟,它在注册表中的 键值为 DnsCacheTimeout。Firefox 对 DNS 的查找记录缓存时间为 1 分钟,它在配置文 件中的选项为 network.dnsCacheExpiration(Fasterfox 把这个选项改为了 1 小时)。
当客户端中的 DNS 缓存都为空时(浏览器和操作系统都为空),DNS 查找的次数和页面 中主机名的数量相同。这其中包括页面中 URL、图片、脚本文件、样式表、Flash 对象 等包含的主机名。减少主机名的数量可以减少 DNS 查找次数。
减少主机名的数量还可以减少页面中并行下载的数量。减少 DNS 查找次数可以节省响应 时间,但是减少并行下载却会增加响应时间。我的指导原则是把这些页面中的内容分割 成至少两部分但不超过四部分。这种结果就是在减少 DNS 查找次数和保持较高程度并行 下载两者之间的权衡了。
3、避免跳转
跳转是使用 301 和 302 代码实现的。下面是一个响应代码为 301 的 HTTP 头:
1 2 3
HTTP/1.1 301 Moved Permanently Location: http://example.com/newuri Content-Type: text/html
服务器根据文件类型来选择需要进行 gzip 压缩的文件,但是这过于限制了可压缩的文件。 大多数 web 服务器会压缩 HTML 文档。对脚本和样式表进行压缩同样也是值得做的事情, 但是很多 web 服务器都没有这个功能。实际上,压缩任何一个文本类型的响应,包括 XML 和 JSON,都值得的。图像和 PDF 文件由于已经压缩过了所以不能再进行 gzip 压缩。如果 试图 gizp 压缩这些文件的话不但会浪费 CPU 资源还会增加文件的大小。 Gzip 压缩所有可能的文件类型是减少文件体积增加用户体验的简单方法。
4、配置 ETag
Entity tags(ETags)(实体标签)是 web 服务器和浏览器用于判断浏览器缓存中的内 容和服务器中的原始内容是否匹配的一种机制(“实体”就是所说的“内容”,包括图 片、脚本、样式表等)。增加 ETag 为实体的验证提供了一个比使用“last-modified date (上次编辑时间)”更加灵活的机制。Etag 是一个识别内容版本号的唯一字符串。唯一 的格式限制就是它必须包含在双引号内。原始服务器通过含有 ETag 文件头的响应指定页 面内容的 ETag。
1 2 3 4
HTTP/1.1 200 OK Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT ETag: “10c24bc-4ab-457e1c1f” Content-Length: 12195
The src attribute must be present, and must contain a valid URL referencing a non-interactive, optionally animated, image resource that is neither paged nor scripted. If the base URI of the element is the same as the document’s address, then the src attribute’s value must not be the empty string.
注重性能的前端服务器往往希望页面有秩序地加载。同时,我们也希望浏览器把已经接 收到内容尽可能显示出来。这对于拥有较多内容的页面和网速较慢的用户来说特别重要。 向用户返回可视化的反馈,比如进程指针,已经有了较好的研究并形成了正式文档。在 我们的研究中 HTML 页面就是进程指针。当浏览器有序地加载文件头、导航栏、顶部的 logo 等对于等待页面加载的用户来说都可以作为可视化的反馈。这从整体上改善了用户体验。 把样式表放在文档底部的问题是在包括 Internet Explorer 在内的很多浏览器中这会中 止内容的有序呈现。浏览器中止呈现是为了避免样式改变引起的页面元素重绘。用户不 得不面对一个空白页面。 HTML 规范清楚指出样式表要放包含在页面的<head />区域内:”和<a />不同,<link /> 只能出现在文档的<head />区域内,尽管它可以多次使用它”。无论是引起白屏还是出 现没有样式化的内容都不值得去尝试。最好的方案就是按照 HTML 规范在文档<head />内 加载你的样式表。
在 Internet Explorer 中会产生不必要的 HTTP 请求,而在 Firefox 却不会。在 Internet Explorer 中,如果一个脚本被引用两次而且它又不可缓存,它就会在页面加载过程中产 生两次 HTTP 请求。即时脚本可以缓存,当用户重载页面时也会产生额外的 HTTP 请求。 除增加额外的 HTTP 请求外,多次运算脚本也会浪费时间。在 Internet Explorer 和 Firefox 中不管脚本是否可缓存,它们都存在重复运算 JavaScript 的问题。 一个避免偶尔发生的两次引用同一脚本的方法是在模板中使用脚本管理模块引用脚本。 在 HTML 页面中使用<script />标签引用脚本的最常见方法就是:
有时候我们会感觉到页面反应迟钝,这是因为 DOM 树元素中附加了过多的事件句柄并且 些事件句病被频繁地触发。这就是为什么说使用 event delegation(事件代理)是一种 好方法了。如果你在一个 div 中有 10 个按钮,你只需要在 div 上附加一次事件句柄就可 以了,而不用去为每一个按钮增加一个句柄。事件冒泡时你可以捕捉到事件并判断出是 哪个事件发出的。
你同样也不用为了操作 DOM 树而等待 onload 事件的发生。你需要做的就是等待树结构中 你要访问的元素出现。你也不用等待所有图像都加载完毕。
“The value null represents the intentional absence of any object value. It is one of JavaScript’s primitive values.” — MDN Docs
The JavaScript primitive type null represents an intentional absence of a value — it is usually set on purpose to indicate that a variable has been declared but not yet assigned any value.
This contrasts null from the similar primitive value undefined , which is an unintentional absence of any object value.
That is because a variable that has been declared but not assigned any value is undefined, not null.
Unfortunately, typeof returns "object" when called on a null value, because of a historical bug in JavaScript that will never be fixed.
That means checking for null cannt be performed using typeof.
The simplest way to check for null is to know that null evaluates to false in conditionals or if coerced to a [boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean) value:
Next, I explore using the == or === equality operators to check for null.
Falsy equality using ==
“Despite the fact that null is [falsy], it isn’t considered loosely equal to any of the other falsy values in JavaScript. In fact, the only values that null is loosely equal to are undefined and itself.” —Josh Clanton at A Drip of JavaScript
One way to check for null in JavaScript is to check if a value is loosely equal to null using the double equality [==](https://medium.com/better-programming/making-sense-of-vs-in-javascript-f9dbbc6352e3) operator:
As shown above, null is only loosely equal to itself and undefined, not to the other falsy values shown.
This can be useful for checking for the absence of value — null and undefined both indicate an absence of value, thus they are loosely equal (they have the same value even though they are different types).
So, when programming to check if a variable has any value at all before trying to process it, you can use == null to check for either null or undefined.
Strict equality using ===
Tomake sure we have exactly a null value, excluding any undefined values, using the triple equality [===](https://medium.com/better-programming/making-sense-of-vs-in-javascript-f9dbbc6352e3) operator will do the trick:
Generally, it is a good idea to catch both null and undefined values, as both represent an absence of a value.
That means checking for null is one of the few times in JavaScript that using == is recommended, while otherwise [===](https://medium.com/better-programming/making-sense-of-vs-in-javascript-f9dbbc6352e3) is generally recommended.
Comparing == vs === when checking for null
Some JavaScript programmers prefer everything to be explicit for clarity, and there is nothing wrong with that.
Indeed, the code linter JSLint explicitly disallows [==](https://jslint.com/help.html) to prevent accidental bugs resulting from type coercion.
That means that if you (or your linter) are in the habit of always using the strict equality operator ===, then you can check whether a value strictly equals null OR (||) strictly equals undefined instead of using ==:
It is more verbose than the == operator, but everyone who reads your code will clearly know that both null and undefined are being checked for.
A real world example of when to check for null
“One way this error [‘null is not an object’] might occur in a real world example is if you try using a DOM element in your JavaScript before the element is loaded. That’s because the DOM API returns null for object references that are blank.” — Rollbar on the Top 10 JavaScript errors
This TypeError (“null is not an object”) can occur if the DOM elements have not been created before loading the script, such as if the script higher than the HTML on the page, which is interpreted from top-to-bottom.
The solution would be using an event listener that will notify us when the page is ready, and then running the script.
But still, it might be prudent to check if the DOM element is null before trying to access it.
Use typeof anyway with falsy power
“Thankfully since null isn’t really an object, it’s the only ‘object’ that is a falsy value, empty objects are truthy.” — Casey Morris in Daily JS
Another method of checking for null is based on the fact that null is falsy, but empty objects are truthy, so null is the only falsy object.
This can be conveniently checked using the logical NOT [!](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Description) operator:
Using typeof can be a helpful trick, because if a variable is undeclared, then trying to reference it will throw a [ReferenceError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError).
But, the typeof an undeclared value is undefined, so using typeof can be a good way to check for null, undefined, and undeclared variables.
Using Object.is()
The ES6 function [Object.is()](https://medium.com/coding-at-dawn/es6-object-is-vs-in-javascript-7ce873064719) differs from the strict [===](https://medium.com/better-programming/making-sense-of-vs-in-javascript-f9dbbc6352e3) and loose [==](https://medium.com/better-programming/making-sense-of-vs-in-javascript-f9dbbc6352e3) equality operators in how it checks for [NaN](https://medium.com/coding-in-simple-english/how-to-check-for-nan-in-javascript-4294e555b447) and negative zero [-0](https://medium.com/coding-at-dawn/is-negative-zero-0-a-number-in-javascript-c62739f80114).
For null, the behavior of Object.is() is the same as ===:
That means that you will need to explicitly check for both null and undefined if you are using Object.is(), which is the helper method checking for changes in state under the hood in React.
Conclusion
Checking for null is a common task that every JavaScript developer has to perform at some point or another.
The typeof keyword returns "object" for null, so that means a little bit more effort is required.
Comparisons can be made: null === null to check strictly for null or null == undefined to check loosely for either null or undefined.
The value null is falsy, but empty objects are truthy, so typeof maybeNull === "object" && !maybeNull is an easy way to check that a value is not null.
Finally, to check if a value has been declared and assigned a value that is neither null nor undefined, use typeof:
Now go out there and check for null with confidence!