无需申请自动送彩金68_白菜送彩金网站大全[无需申请秒送彩金]
做最好的网站
来自 无需申请自动 2019-09-21 11:33 的文章
当前位置: 无需申请自动送彩金68 > 无需申请自动 > 正文

Web性能优化,Element节点类型详解

Web性能优化:What? Why? How?

2015/06/23 · HTML5 · 1 评论 · 性能优化

原文出处: 木的树   

为什么要提升web性能?

Web性能黄金准则:只有10%~20%的最终用户响应时间花在了下载html文档上,其余的80%~90%时间花在了下载页面组件上。

web性能对于用户体验有及其重要的影响,根据著名的2-5-8原则:

  • 当用户在2秒以内得到响应,会感觉系统的响应非常快
  • 当用户在2-5秒之内得到响应,会感觉系统的响应速度还可以
  • 当用户在5-8秒之内得到响应,会感觉系统的响应非常慢,但还可以接受
  • 当用户在8秒之后都没有得到响应,会感觉系统糟透了,甚至系统已经挂掉;要么打开竞争对手的网站,要么重新发起第二次请求

凡事都需要研究,通过科学的研究我们就可以找到事物的发展规律。这里要感谢雅虎的工程师总结的14条前端优化法则,使得我们可以站在巨人的肩膀上。《高性能网站建设》这本书中的14条优化原则,总结起来主要是以下个方面的优化:

  1. 减少HTTP请求
  2. 页面内部优化
  3. 启用缓存
  4. 减少下载量
  5. 网络连接上的优化

为什么减少HTTP请求可以提高Web性能?

要回答这个问题,我们就要了解当浏览器向服务器发送一个http请求知道获取数据都经历哪些过程:

开启一个链接(tcp/ip的三次握手过程) -》 发送请求 -》 等待(网络延迟跟服务器的处理时间)-》 下载数据

我们看一下百度首页中的http请求在各阶段耗费的时间,上面不同的颜色代表下图中的不同阶段

图片 1

(点击查看大图)

可以看到除了图片之外,其余大部分http请求的事件花在了建立连接与等待阶段。

http协议建立在TIC/IP协议之上,在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。 简单来说三次握手就是一个身份确认的过程:

(第一次握手:主机A发送位码为syn=1,随机产生seq number=1234567的数据包到服务器,主机B由SYN=1知道,A要求建立联机;)

晴儿:你是潇哥哥吗,我是晴儿

(第二次握手:主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq 1),syn=1,ack=1,随机产生seq=7654321的包)

潇剑:这货是谁,一箫一剑走江湖,下一句是什么?

(第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq number 1,以及位码ack是否为1,若正确,主机A会再发送ack number=(主机B的seq 1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功。)

晴儿:这首诗。。。你真的是潇哥哥,一萧一剑走江湖,千古情愁酒一回。。。

潇剑:晴儿,你真的是晴儿。。。。

(啪啪啪啪啪啪啪啪啪啪啪啪啪啪啪。。。。。。。。。。。。)

言归正传,这个过程也是需要消耗时间的,在百度首页找到一个极端的例子:图片 2

(点击查看大图)

而等待的时间通常也大于内容下载的时间,这里同样找到一个极端例子:图片 3

(点击查看大图)

由此我们可以得出结论:一个http请求绝大多数的时间消耗在了建立连接跟等待的时间,优化的方法是减少http请求。

如何提高web性能?

1、减少HTTP请求

一般来说要减少http请求通常从两个方面下手:减少图片的请求、减少脚本文件与样式表的请求

图片的减少通常有两种方式:css sprites、内联图片、IconFont。

CSS Sprites:将多张图片合并成一幅单独的图片,使用css的background-position属性,将html元素的背景图片放到sprites 图片中的期望位置上。使用这项技术的附加优点是他降低了下载量,合并后的图片比分离的图片和更小,因为它降低了图片自身的开销(颜色表、格式信息等等)。实际项目中css sprites是一项体力活,因为开发过程中需要对这张大图进行维护(添加、减少图片),张鑫旭同学的文章中有介绍如何管理sprites图片可以作为参考(这里)。如果需要在页面中为背景、链接、导航栏提供大量的图片,css sprites绝对是一种优秀的解决方案(干净的标签、较少的图片、较短的响应时间)。

内联图片:通过使用data:URL模式可以再页面中包含图片而无需任何额外的请求。缺点就是IE8以下的浏览器不支持这种方式,而IE8在数据大小上有限制,只能支持23kb以内的数据。对于较小的图片来说可以直接内联到web页面中,但对于大图片内联到页面里会导致页面变大,聪明的做法是使用css,将内联的图片作为背景使用,并放到外部样式表中,这意味着数据可以缓存在样式表内部。使用外部样式表虽然增加了一个http请求,但样式可以被浏览器缓存,得到额外的收获。另外一点需要注意:base64是有损压缩。

图片 4

IconFont:图标字体,这是近年来新流行的一种以字体代替图片的技术。它可以适应任何分辨率而不会出现图片模糊问题,与图片相比它具有更小的容量,更高的灵活性(像字体一样可以设置图标大小、颜色、透明度、hover状态、反转等),IE8以上的浏览器都支持该技术。在使用IconFont之前,你首先要确定你选则的字体库是否是收费。详细内容可以参考这篇文章:图标字体化浅谈

减少脚本与样式表的请求主要原则就是合并。在实际开发中我们遵循模块化的原则将代码分散到许多小文件中,按照软件开发的原则这是完全正确的,但对于上线页面来说,每一个文件都会产生一个http请求,严重影响性能。和css sprites一样,将这些小文件合并到一个文件中,可以减少http请求的数量并缩短最终用户响应时间。在合并过程中我们还需要使用工具精简(移除不必要的字符以减小文件大小缩减下载时间)和混淆(除了移除不必要字符外,还会改写源代码,比如函数和变量名使用更短的标量名)Javascript代码。对于采用AMD或CMD进行模块化开发的同学,在合并过程中通常会将依赖的其他模块打包到一个文件中,而模板html通常以字符串的方式内联到Javascript文件中。目前最常用的前端构建工具就是glup,这里有一篇初步应用的文章:前端 | gulp 打包 require.js 模块依赖

2、页面内部优化

关于页面内部优化主要方向:样式表放在顶部、脚本文件放在底部、避免css表达式、把脚本的样式表放在外部、移除重复脚本

关心性能的工程师都希望页面能否尽快的展现在用户面前,对于页面中很多内容的页面我们都希望内容能够逐步加载,为用户提供可视化回馈。而将样式表放在底部会导致浏览器阻止内容逐步呈现。为避免当页面变化时重绘页面元素,浏览器会阻塞页面呈现,直到样式表解析完毕(详细内容可以查看我的这篇博客)。所以如果将样式表放在顶部并不会减少资源的加载时间,它减少的是页面的呈现时间。小米主页曾经犯过这样的错误:图片 5

将样式表放在底部会阻塞页面的逐步呈现,而将script文件放在页面顶部同样会阻塞页面的逐步呈现。script元素会阻塞后续内容的解析,因为script中可以同过document.write来更改页面。解决的办法就是将script标签放在页面底部。这样既可以让内容逐步呈现,也可以提高下载的并行度。如果我们确定不需要document.write那可以为script标签加上asyn属性(Ie中要加上defer)提高并行下载度。

CSS表达式是ie支持的可以用来动态更改css属性的一种方式,我们不需要了解太多,她的书写方式如下,一旦在产品中发现expression关键字就要彻底消灭。

图片 6

使用外部脚本和样式这一条,我想凡是有点经验的工程师都会这么干。

移除重复脚本:这条说的主要是避免在页面中多次加入同一份Javascript代码,如果我们的开发中有依赖管理的方式比如AMD、CMD,基本不会出现这种情况。

 

3、启用缓存

关于缓存的使用这里介绍两套方案:expires/If-Modified-Since、Cache-Control/Etag;前者是HTTP1.0中的缓存方案,后者是HTTP1.1中缓存方案,若http头部中同时出现二者,后者的优先级更高。

If-modified-since的方式通常被称为条件Get。浏览器缓存中保存了一个文件的副本,但需要向服务器询问此副本是否可用。If-Modified-Since是浏览器将最后修改时间发送给服务器,服务器相应头中Last-Modified进行对比;若If-Modified-Since <= Last-Modified 则浏览器读取本地副本。此时响应状态为304 Not Modified, 并不在发送响应体。

图片 7

Expries:虽然使用条件GET和304响应能够节省时间,但浏览器跟服务器端仍然要发送一次请求进行确认。通过明确设置副本的过期时间可以避免条件GET。当浏览器发现响应头中的expires时,会将过期时间和文件一起保存到缓存中去。在过期之前一直从缓存中读取。expires头使用一个特定的时间来指定缓存的有效期,他要求浏览器与服务器时间完全一致。而且一旦过期,服务器端配置中需要重新设顶一个过期时间。

图片 8

ETag(实体标签):是服务器用于检查浏览器缓存有效性的一种机制。ETag在HTTP1.1中引入,ETag是唯一标识了一个组件的一个特定版本的字符串。唯一的格式约束是这个字符串必须使用双引号。如果浏览器要验证一个组件是否有效他会使用If-None-Match将etag字符串传送给服务器。如果ETag是匹配的,服务器端会返回304.(如果实体数据需要根据User-Agent或Accept-Language来改变时,ETag提供了更高的灵活性)。对于使用服务器集群的网站来说,从一台服务器到另一台服务器,ETag通常是无法匹配的。这是ETag的问题。而且即便同时使用If-Modified-Since和If-None-Match也并不能达到预期效果。解决方法总是有的:自定义Etag格式

图片 9

Cache-Control:HTTP1.1引入了来代替Expires,它使用max-age指令来指定副本被缓存多久,该指令以秒为单位定义了一个更新窗,组件从被请求开始到现在的秒数小于设定值,则一直使用副本。避免了一次http请求。相比Expries,Cache-Control指令提供了更细粒度的控制。详细内容请看大额同学的文章:透过浏览器看HTTP缓存

 

4、减少下载量

减少下载量最有效的方式就是开启gzip压缩,gzip是GNU开发的一种免费格式。压缩组件通过减小http响应的大小来加快响应速度。HTTP1.1通过使用DontTrackMeHere来标识支持的压缩,如果服务器看到这个标识,会使用请求头中的一种方式来压缩响应。并通过Content-Encoding来通知web客户端。很多网站会压缩html文件,实际上包括xml跟json在内的任何文本都可以压缩,但图片和pdf不应该压缩。根据经验通常可以对大于1kb或2kb的文件进行压缩。压缩通常能将响应的数据量减少70%。压缩的成本在于:服务器需要耗费额外的cpu进行压缩,客户端需要解压缩。所以需要在cpu的消耗和数据块的大小之间进行取舍。

 

5、优化网络连接

网络连接的优化主要有三个规则:使用CDN加速、减少DNS查找、避免重定向

CDN:CDN是地理上分布的web server的集合,用于更高效地发布内容。通常基于网络远近来选择给具体用户服务的web server。 这缩短了资源的传输响应时间,有效提高web性能。

DNS用于映射主机名和IP地址,一般一次解析需要20~120毫秒。浏览器会首先根据页面的主机名进行域名解析,在有ISP返回结果之前页面不会加载任何内容,所以减少DNS查找可以有效降低等待时间。为达到更高的性能,DNS解析通常被多级别地缓存,如由ISP或局域网维护的caching server,本地机器操作系统的缓存(如windows上的DNS Client Service),浏览器。IE的缺省DNS缓存时间为30分钟,Firefox的缺省缓冲时间是1分钟。 我们能做的是尽量减少一个页面的主机名,但要在浏览器最大并行下载数跟dns查找之间做权衡。根据雅虎的研究,最好将主机名控制在2-4个内。

重定向:将一个URL重新路由到另一个URL。重定向功能是通过301和302这两个HTTP状态码完成的,如:
HTTP/1.1 301 Moved Permanently
Location:
Content-Type: text/html

浏览器自动重定向请求到Location指定的URL上,重定向的主要问题是降低了用户体验。 种最耗费资源、经常发生而很容易被忽视的重定向是URL的最后缺少/,导致自动产生结尾斜线的原因是,浏览器在进行get请求是必须指定一些路径;如果没有路径它就会简单的使用文档根。(主机缺少结尾斜线是不会发生重定向:)

雅虎的14条优化规则在很长的一段时间里发挥着重要作用,随着技术的发展,单单这十四条原则已经不能够满足前端性能优化。在一些大公司出现了前端工程化这一概念,详细内容可以参考一下这篇文章:前端性能优化工程化进阶

 

参考资料:

web前端性能意思、关注重点、测试方案、

WEB站点性能优化实践(加载速度提升2s)

HTTP协议三次握手过程

高性能WEB开发 – 为什么要减少请求数,如何减少请求数!

我是如何对网站CSS进行架构的

图标字体化浅谈

利用ETag缓存优化请求

透过浏览器看HTTP缓存

1 赞 2 收藏 1 评论

图片 10

DOM Element节点类型详解

2015/09/21 · HTML5 · DOM

本文作者: 伯乐在线 - 韩子迟 。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者。

上文中我们讲解了 DOM 中最重要的节点类型之一的 Document 节点类型,本文我们继续深入,谈谈另一个重要的节点类型 Element 。

H5游戏开发:一笔画

2017/11/07 · HTML5 · 游戏

原文出处: 凹凸实验室   

图片 11

1、概况


Element 类型用于表现 HTML 或 XML 元素,提供了对元素标签名、子节点及特性的访问。 Element 节点具有以下特征:

  1. nodeType 的值为 1
  2. nodeName 的值为元素的标签名
  3. nodeValue 的值为null
  4. parentNode 可能是 Document 或者 Element
  5. 其子节点可能是 ElementTextCommentProcessingInstructionCDATASection 或者 EntityReference

要访问元素的标签名,可以用 nodeName 属性,也可以用 tagName 属性;这两个属性会返回相同的值。在 HTML 中,标签名始终都以全部大写表示,而在 XML(有时候也包括 XHTML)中,标签名始终和源代码中保持一致。假如你不确定自己的脚本将会在 HTML 还是 XML 文档中执行,最好还是在比较之前将标签名转换成相同的大小写形式:

JavaScript

var myDiv = document.querySelector('div'); console.log(myDiv.tagName); // DIV console.log(myDiv.nodeName); // DIV if (myDiv.tagName.toLowerCase() === 'div') { // 这样最好,适用于任何文档 // ... }

1
2
3
4
5
6
7
var myDiv = document.querySelector('div');
console.log(myDiv.tagName);  // DIV
console.log(myDiv.nodeName);  // DIV
 
if (myDiv.tagName.toLowerCase() === 'div') { // 这样最好,适用于任何文档
  // ...
}

H5游戏开发:一笔画

by leeenx on 2017-11-02

一笔画是图论[科普](https://zh.wikipedia.org/wiki/图论)中一个著名的问题,它起源于柯尼斯堡七桥问题[科普](https://zh.wikipedia.org/wiki/柯尼斯堡七桥问题)。数学家欧拉在他1736年发表的论文《柯尼斯堡的七桥》中不仅解决了七桥问题,也提出了一笔画定理,顺带解决了一笔画问题。用图论的术语来说,对于一个给定的连通图[科普](https://zh.wikipedia.org/wiki/连通图)存在一条恰好包含所有线段并且没有重复的路径,这条路径就是「一笔画」。

寻找连通图这条路径的过程就是「一笔画」的游戏过程,如下:

图片 12

2、HTML 元素


所有 HTML 元素都由 HTMLElement 类型表示,不是直接通过这个类型,也是通过它的子类型来表示。 HTMLElement 类型直接继承自 Element 并添加了一些属性。每个 HTML 元素中都存在下列标准属性:

  1. id 元素在文档中的唯一标识符
  2. title 有关元素的附加说明信息,一般通过工具提示条显示出来
  3. lang 元素内容的语言代码,很少使用
  4. dir 语言的方向,值为 ltr 或者 rtl,也很少使用
  5. className 与元素的 class 特性对应

游戏的实现

「一笔画」的实现不复杂,笔者把实现过程分成两步:

  1. 底图绘制
  2. 交互绘制

「底图绘制」把连通图以「点线」的形式显示在画布上,是游戏最容易实现的部分;「交互绘制」是用户绘制解题路径的过程,这个过程会主要是处理点与点动态成线的逻辑。

3、特性的获取和设置


每个元素都有一个或多个特性,这些特性的用途是给出相应元素或其内容的附加信息。操作特性的 DOM 方法主要有三个,分别是getAttribute() setAttribute() removeAttribute()

注意,传递给 getAttribute() 的特性名与实际的特性名相同,因此要想得到 class 特性值,应该传入 class 而不是 className,后者只有在通过对象属性(property)访问特性时才用。如果给定名称的特性不存在,getAttribute() 返回 null。

<div id='myDiv' title='hanzichi'> </div> <script> var myDiv = document.querySelector('div'); // attribute console.log(myDiv.getAttribute('id')); // myDiv console.log(myDiv.getAttribute('class')); // null console.log(myDiv.getAttribute('title')); // hanzichi console.log(myDiv.getAttribute('lang')); // null console.log(myDiv.getAttribute('dir')); // null // property console.log(myDiv.id); // myDiv console.log(myDiv.className); // '' console.log(myDiv.title); // hanzichi console.log(myDiv.lang); // '' console.log(myDiv.dir); // '' </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id='myDiv' title='hanzichi'> </div>
<script>
  var myDiv = document.querySelector('div');
 
  // attribute
  console.log(myDiv.getAttribute('id')); // myDiv
  console.log(myDiv.getAttribute('class')); // null
  console.log(myDiv.getAttribute('title')); // hanzichi
  console.log(myDiv.getAttribute('lang')); // null
  console.log(myDiv.getAttribute('dir')); // null
 
  // property
  console.log(myDiv.id); // myDiv
  console.log(myDiv.className); // ''
  console.log(myDiv.title); // hanzichi
  console.log(myDiv.lang); // ''
  console.log(myDiv.dir); // ''
</script>

通过 getAttribute() 方法也可以取得自定义特性。

在实际开发中,开发人员不常用 getAttribute(),而是只使用对象的属性(property)。只有在取得自定义特性值的情况下,才使用getAttribute() 方法。为什么呢?比如说 style,在通过 getAttribute() 访问时,返回的 style 特性值包含的是 css 文本,而通过属性来访问会返回一个对象。再比如 onclick 这样的事件处理程序,当在元素上使用时,onclick 特性包含的是 Javascript 代码,如果通过 getAttribute() 访问,将会返回相应代码的字符串,而在访问 onclick 属性时,则会返回 Javascript 函数。

与 getAttribute() 对应的是 setAttribute(),这个方法接受两个参数:要设置的特性名和值。如果特性已经存在,setAttribute()会以指定的值替换现有的值;如果特性不存在,setAttribute() 则创建该属性并设置相应的值。

而 removeAttitude() 方法用于彻底删除元素的特性。调用这个方法不仅会清除特性的值,而且也会从元素中完全删除特性。

JavaScript

div.setAttribute('id', 'someOtherId'); div.setAttribute('title', 'some other text'); div.removeAttribute('class')

1
2
3
4
div.setAttribute('id', 'someOtherId');
div.setAttribute('title', 'some other text');
 
div.removeAttribute('class')

底图绘制

「一笔画」是多关卡的游戏模式,笔者决定把关卡(连通图)的定制以一个配置接口的形式对外暴露。对外暴露关卡接口需要有一套描述连通图形状的规范,而在笔者面前有两个选项:

  • 点记法
  • 线记法

举个连通图 —— 五角星为例来说一下这两个选项。

图片 13

点记法如下:

JavaScript

levels: [ // 当前关卡 { name: "五角星", coords: [ {x: Ax, y: Ay}, {x: Bx, y: By}, {x: Cx, y: Cy}, {x: Dx, y: Dy}, {x: Ex, y: Ey}, {x: Ax, y: Ay} ] } ... ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
levels: [
// 当前关卡
{
name: "五角星",
coords: [
{x: Ax, y: Ay},
{x: Bx, y: By},
{x: Cx, y: Cy},
{x: Dx, y: Dy},
{x: Ex, y: Ey},
{x: Ax, y: Ay}
]
}
...
]

线记法如下:

JavaScript

levels: [ // 当前关卡 { name: "五角星", lines: [ {x1: Ax, y1: Ay, x2: Bx, y2: By}, {x1: Bx, y1: By, x2: Cx, y2: Cy}, {x1: Cx, y1: Cy, x2: Dx, y2: Dy}, {x1: Dx, y1: Dy, x2: Ex, y2: Ey}, {x1: Ex, y1: Ey, x2: Ax, y2: Ay} ] } ]

1
2
3
4
5
6
7
8
9
10
11
12
13
levels: [
// 当前关卡
{
name: "五角星",
lines: [
{x1: Ax, y1: Ay, x2: Bx, y2: By},
{x1: Bx, y1: By, x2: Cx, y2: Cy},
{x1: Cx, y1: Cy, x2: Dx, y2: Dy},
{x1: Dx, y1: Dy, x2: Ex, y2: Ey},
{x1: Ex, y1: Ey, x2: Ax, y2: Ay}
]
}
]

「点记法」记录关卡通关的一个答案,即端点要按一定的顺序存放到数组 coords中,它是有序性的记录。「线记法」通过两点描述连通图的线段,它是无序的记录。「点记法」最大的优势是表现更简洁,但它必须记录一个通关答案,笔者只是关卡的搬运工不是关卡创造者,所以笔者最终选择了「线记法」。:)

本文由无需申请自动送彩金68发布于无需申请自动,转载请注明出处:Web性能优化,Element节点类型详解

关键词: