金沙澳门官网网址_金沙国际登陆

欢迎加入金沙澳门官网网址体验更多不一样的精彩.,金沙国际登陆提供最丰厚回馈!,因为金沙澳门官网网址这里的游戏是多种多样的,为大家打造一个最专业的化的超级五星酒店。

金沙澳门官网网址 > 金沙澳门官网网址 > 【金沙澳门官网网址】pwa重构上海地铁线路图,

原标题:【金沙澳门官网网址】pwa重构上海地铁线路图,

浏览次数:158 时间:2019-10-08

pwa重构上海地铁线路图

2018/03/28 · JavaScript · PWA

原文出处: Neal   

之前一直有在维护一个上海地铁线路图的 pwa,最主要的特性就是 “offline first”。但是由于代码都是通过原生的 js 去实现,之前我都不是很喜欢去用框架,不想具有任何框架的偏好。但是到后期随着代码量的增加,代码的确变得混乱不堪,拓展新功能也变得尤为困难。因此,花了将近两个礼拜的时候对于应用进行了一次完整的重构。网站访问地址:

HTTP Keep-Alive模式

2015/12/01 · HTML5 · 1 评论 · HTTP

原文出处: 吴秦   

故事发生在10月份的一次面试经历中,本来我不想说出来丢人显眼,但是为了警醒自己和告诫后人,我决定写成博文发出来。因为在面试过程中,我讲在2009年写过QQ农场助手,在这期间深入学习了HTTP协议,而且在2010-05-18写了博文:HTTP协议及其POST与GET操作差异 & C#中如何使用POST、GET等。面试官说既然我熟悉HTTP协议,就问“当HTTP采用keepalive模式,当客户端向服务器发生请求之后,客户端如何判断服务器的数据已经发生完成?”

说实话,当时我懵了,一直没有关注过keepalive模式。我只知道:HTTP协议中客户端发送一个小请求,服务器响应以所期望的信息(例如一个html文件或一副gif图像)。服务器通常在发送回所请求的数据之后就关闭连接。这样客户端读数据时会返回EOF(-1),就知道数据已经接收完全了。我就这样被面试官判了死刑!!!说我完全停留在表面,没有深入(当时真的很受打击,一直自认为技术还不错!)。我当时真的很想找各种借口:

  • 之前没有用到HTTP的keepalive模式,所以没有深入
  • 好久没有用HTTP协议,细节忘了
  • 实习的东西跟HTTP协议没有关系,用得少了就忘了
  • 。。。。。。

觉得各种解释都是那么苍白无力!我再次感叹书到用时方恨少,也感叹一个人的时间是多么的有限(曾一度想成为一个IT专业全才),根本没有精力面面俱到,而且当没有真正使用一个东西的时候,往往会忽略掉很多细节。朋友如果你也答不上来,请认真细看下文,不要怀着浮躁了的心,说不定下次就有人问你这个问题。

WebGL技术储备指南

2015/12/22 · HTML5 · 1 评论 · WebGL

原文出处: 淘宝前端团队(FED)- 叶斋   

金沙澳门官网网址 1

WebGL 是 HTML 5 草案的一部分,可以驱动 Canvas 渲染三维场景。WebGL 虽然还未有广泛应用,但极具潜力和想象空间。本文是我学习 WebGL 时梳理知识脉络的产物,花点时间整理出来与大家分享。

准备

准备工作先做好,在 vue 和 react 之间,我还是选择了后者。基于 create-react-app 来搭建环境,crp 为你准备了一个开箱即用的开发环境,因此你无需自己亲手配置 webpack,因此你也不需要成为一名 webpack 配置工程师了。

另外一方面,我们还需要一些数据,包括站点信息,线路路径,文字说明等等。基于之前的应用,可以通过一小段的代码获取信息。就此如要我们获取我们以前的站点在 svg 图中的相关属性,普通的站点使用 circle 元素,为了获取其属性:

const circles = document.querySelectorAll('circle'); let result = []; circles.forEach(circle => { let ele = { cx: circle.cx, cy: circle.cy, sroke: circle.stroke, id: circle.id }; result.push(ele); }) const str = JSON.stringify(result);

1
2
3
4
5
6
7
8
9
10
11
12
13
const circles = document.querySelectorAll('circle');
let result = [];
circles.forEach(circle => {
  let ele = {
    cx: circle.cx,
    cy: circle.cy,
    sroke: circle.stroke,
    id: circle.id
  };
  result.push(ele);
})
const str = JSON.stringify(result);
 

通过这样的代码我们就可以获取 svg 普通站点信息,同理还可获取中转站信息,线路路径信息以及站点以及线路 label 信息。还有,我们还需要获取每个站点的时刻表信息,卫生间位置信息,无障碍电梯信息以及出入口信息。这里是写了一些爬虫去官网爬取并做了一些数据处理,再次就不一一赘述。

1、什么是Keep-Alive模式?

我们知道HTTP协议采用“请求-应答”模式,当使用普通模式,即非KeepAlive模式时,每个请求/应答客户和服务器都要新建一个连接,完成之后立即断开连接(HTTP协议为无连接的协议);当使用Keep-Alive模式(又称持久连接、连接重用)时,Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接。

金沙澳门官网网址 2

http 1.0中默认是关闭的,需要在http头加入”Connection: Keep-Alive”,才能启用Keep-Alive;http 1.1中默认启用Keep-Alive,如果加入”Connection: close “,才关闭。目前大部分浏览器都是用http1.1协议,也就是说默认都会发起Keep-Alive的连接请求了,所以是否能完成一个完整的Keep-Alive连接就看服务器设置情况。

示例

WebGL 很酷,有以下 demos 为证:

寻找奥兹国
赛车游戏
划船的男孩(Goo Engine Demo)

设计

数据准备好之后,就是应用的设计了。首先,对组件进行一次拆分:

2、启用Keep-Alive的优点

从上面的分析来看,启用Keep-Alive模式肯定更高效,性能更高。因为避免了建立/释放连接的开销。下面是RFC 2616上的总结:

    1. By opening and closing fewer TCP connections, CPU time is saved in routers and hosts (clients, servers, proxies, gateways, tunnels, or caches), and memory used for TCP protocol control blocks can be saved in hosts.
    2. HTTP requests and responses can be pipelined on a connection. Pipelining allows a client to make multiple requests without waiting for each response, allowing a single TCP connection to be used much more efficiently, with much lower elapsed time.
    3. Network congestion is reduced by reducing the number of packets caused by TCP opens, and by allowing TCP sufficient time to determine the congestion state of the network.
    4. Latency on subsequent requests is reduced since there is no time spent in TCP’s connection opening handshake.
    5. HTTP can evolve more gracefully, since errors can be reported without the penalty of closing the TCP connection. Clients using     future versions of HTTP might optimistically try a new feature, but if communicating with an older server, retry with old   semantics after an error is reported.

RFC 2616(P47)还指出:单用户客户端与任何服务器或代理之间的连接数不应该超过2个。一个代理与其它服务器或代码之间应该使用超过2 * N的活跃并发连接。这是为了提高HTTP响应时间,避免拥塞(冗余的连接并不能代码执行性能的提升)。

本文的目标

本文的预期读者是:不熟悉图形学,熟悉前端,希望了解或系统学习 WebGL 的同学。

本文不是 WebGL 的概述性文章,也不是完整详细的 WebGL 教程。本文只希望成为一篇供 WebGL 初学者使用的提纲。

组件结构

将整个地图理解成一个 Map 组件,再将其分为 4 个小组件:

金沙澳门官网网址 3

  • Label: 地图上的文本信息,包括地铁站名,线路名称
  • Station: 地铁站点,包括普通站点和中转站点
  • Line: 地铁线路
  • InfoCard: 状态最复杂的一个组件,主要包含时刻表信息、卫生间位置信息、出入口信息、无障碍电梯信息

这是一个大致的组件划分,里面可能包含更多的其它元素,比如 InfoCard 就有 InfoCard => TimeSheet => TimesheetTable 这样的嵌套。

3、回到我们的问题(即如何判断消息内容/长度的大小?)

Keep-Alive模式,客户端如何判断请求所得到的响应数据已经接收完成(或者说如何知道服务器已经发生完了数据)?我们已经知道了,Keep-Alive模式发送玩数据HTTP服务器不会自动断开连接,所有不能再使用返回EOF(-1)来判断(当然你一定要这样使用也没有办法,可以想象那效率是何等的低)!下面我介绍两种来判断方法。

Canvas

熟悉 Canvas 的同学都知道,Canvas 绘图先要获取绘图上下文:

JavaScript

var context = canvas.getContext('2d');

1
var context = canvas.getContext('2d');

context上调用各种函数绘制图形,比如:

JavaScript

// 绘制左上角为(0,0),右下角为(50, 50)的矩形 context.fillRect(0, 0, 50, 50);

1
2
// 绘制左上角为(0,0),右下角为(50, 50)的矩形
context.fillRect(0, 0, 50, 50);

WebGL 同样需要获取绘图上下文:

JavaScript

var gl = canvas.getContext('webgl'); // 或 experimental-webgl

1
var gl = canvas.getContext('webgl'); // 或 experimental-webgl

但是接下来,如果想画一个矩形的话,就没这么简单了。实际上,Canvas 是浏览器封装好的一个绘图环境,在实际进行绘图操作时,浏览器仍然需要调用 OpenGL API。而 WebGL API 几乎就是 OpenGL API 未经封装,直接套了一层壳。

Canvas 的更多知识,可以参考:

  • JS 权威指南的 21.4 节或 JS 高级程序设计中的 15 章
  • W3CSchool
  • 阮一峰的 Canvas 教程

组件通信和状态管理

本地开发的最大的难点应该就是这一块的内容了。本来由于组件的层级并不算特别复杂,所以我并不打算上 Redux 这种类型的全局状态管理库。主要组件之间的通信就是父子通信和兄弟组件通信。父子组件通信比较简单,父组件的 state 即为子组件的 props,可以通过这个实现父子组件通信。兄弟组件略为复杂,兄弟组件通过共享父组件的状态来进行通信。假如这样的情景,我点击站点,希望能够弹出信息提示窗,这就是 Station 组件和 InfoCard 组件之间的通信,通过 Map 组件来进行共享。点击 Station 组件触发事件,通过回调更新 Map 组件状态的更新,同时也实现了 InfoCard 组件的更新。同时为了实现,点击其它区域就可以关闭信息提示窗,我们对 Map 组件进行监听,监听事件的冒泡来实现高效的关闭,当然为了避免一些不必要的冒泡,还需要在一些事件处理中阻止事件冒泡。

金沙澳门官网网址 4

InfoCard 是最为复杂的一个组件,因为里面包含了好几个 icon,以及状态信息的切换,同时需要实现切换不同的站点的时候能够更新信息提示窗。需要注意信息提示窗信息初次点击信息的初始化,以及切换不同 icon 时分别显示不同的信息,比如卫生间信息或者出入口信息,以及对于时刻表,切换不同的线路的时候更新对应的时刻表。这些状态的转化,需要值得注意。另外值得一题的点就是,在切换不同站点的时候的状态,假如我正在看某个站点的卫生间信息的时候,我点击另外一个站点,这时候弹出的信息提示窗应该是时刻表信息还是卫生间信息呢?我的选择还是卫生间信息,我对于这一状态进行了保持,这样的用户体验从逻辑上来讲似乎更佳。具体实现的代码细节就不一一说明了,里面肯能包含更多的细节,欢迎使用体验。

3.1、使用消息首部字段Conent-Length

故名思意,Conent-Length表示实体内容长度,客户端(服务器)可以根据这个值来判断数据是否接收完成。但是如果消息中没有Conent-Length,那该如何来判断呢?又在什么情况下会没有Conent-Length呢?请继续往下看……

矩阵变换

三维模型,从文件中读出来,到绘制在 Canvas 中,经历了多次坐标变换。

假设有一个最简单的模型:三角形,三个顶点分别为(-1,-1,0),(1,-1,0),(0,1,0)。这三个数据是从文件中读出来的,是三角形最初始的坐标(局部坐标)。如下图所示,右手坐标系。

金沙澳门官网网址 5

模型通常不会位于场景的原点,假设三角形的原点位于(0,0,-1)处,没有旋转或缩放,三个顶点分别为(-1,-1,-1),(1,-1,-1),(0,1,-1),即世界坐标。

金沙澳门官网网址 6

绘制三维场景必须指定一个观察者,假设观察者位于(0,0,1)处而且看向三角形,那么三个顶点相对于观察者的坐标为(-1,-1,-2),(1,-1,-2),(0,1,-2),即视图坐标。

金沙澳门官网网址 7

观察者的眼睛是一个点(这是透视投影的前提),水平视角和垂直视角都是90度,视野范围(目力所及)为[0,2]在Z轴上,观察者能够看到的区域是一个四棱台体。

金沙澳门官网网址 8

将四棱台体映射为标准立方体(CCV,中心为原点,边长为2,边与坐标轴平行)。顶点在 CCV 中的坐标,离它最终在 Canvas 中的坐标已经很接近了,如果把 CCV 的前表面看成 Canvas,那么最终三角形就画在图中橙色三角形的位置。

金沙澳门官网网址 9

上述变换是用矩阵来进行的。

局部坐标 –(模型变换)-> 世界坐标 –(视图变换)-> 视图坐标 –(投影变换)–> CCV 坐标。

以(0,1,0)为例,它的齐次向量为(0,0,1,1),上述变换的表示过程可以是:

金沙澳门官网网址 10

上面三个矩阵依次是透视投影矩阵,视图矩阵,模型矩阵。三个矩阵的值分别取决于:观察者的视角和视野距离,观察者在世界中的状态(位置和方向),模型在世界中的状态(位置和方向)。计算的结果是(0,1,1,2),化成齐次坐标是(0,0.5,0.5,1),就是这个点在CCV中的坐标,那么(0,0.5)就是在Canvas中的坐标(认为 Canvas 中心为原点,长宽都为2)。

上面出现的(0,0,1,1)是(0,0,1)的齐次向量。齐次向量(x,y,z,w)可以代表三维向量(x,y,z)参与矩阵运算,通俗地说,w 分量为 1 时表示位置,w 分量为 0 时表示位移。

WebGL 没有提供任何有关上述变换的机制,开发者需要亲自计算顶点的 CCV 坐标。

关于坐标变换的更多内容,可以参考:

  • 计算机图形学中的5-7章
  • 变换矩阵@维基百科
  • 透视投影详解

比较复杂的是模型变换中的绕任意轴旋转(通常用四元数生成矩阵)和投影变换(上面的例子都没收涉及到)。

关于绕任意轴旋转和四元数,可以参考:

  • 四元数@维基百科
  • 一个老外对四元数公式的证明

关于齐次向量的更多内容,可以参考。

  • 计算机图形学的5.2节
  • 齐次坐标@维基百科

性能优化

以上这些的开发得益于之前的维护,所以重构过程还是比较快的,稍微熟悉了下 react 的用法就完成了重构。但是,在上线之后使用 lighthouse 做分析,performan 的得分是 0 分。首屏渲染以及可交互得分都是 0 分,首先来分析一下。因为整个应用都是通过 js 来渲染,而最为核心的就是那个 svg。整个看下来,有几点值得注意:

  • 代码直接将 json 导入,导致 js 体积过大
  • 所有组件都在渲染的时候进行加载

找到问题点,就可以想到一些解决方案了。第一个比较简单,压缩 json 数据,去除一些不需要的信息。第二个,好的解决办法就是通过异步加载来实现组件加载,效果明显,尤其是对于 InfoCard 组件:

3.2、使用消息首部字段Transfer-Encoding

当客户端向服务器请求一个静态页面或者一张图片时,服务器可以很清楚的知道内容大小,然后通过Content-length消息首部字段告诉客户端需要接收多少数据。但是如果是动态页面等时,服务器是不可能预先知道内容大小,这时就可以使用Transfer-Encoding:chunk模式来传输数据了。即如果要一边产生数据,一边发给客户端,服务器就需要使用”Transfer-Encoding: chunked”这样的方式来代替Content-Length。

chunk编码将数据分成一块一块的发生。Chunked编码将使用若干个Chunk串连而成,由一个标明长度为0的chunk标示结束。每个Chunk分为头部和正文两部分,头部内容指定正文的字符总数(十六进制的数字)和数量单位(一般不写),正文部分就是指定长度的实际内容,两部分之间用回车换行(CRLF)隔开。在最后一个长度为0的Chunk中的内容是称为footer的内容,是一些附加的Header信息(通常可以直接忽略)。

Chunk编码的格式如下:

Chunked-Body = *chunk
“0” CRLF
footer
CRLF
chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF

hex-no-zero = <HEX excluding “0”>

chunk-size = hex-no-zero *HEX
chunk-ext = *( “;” chunk-ext-name [ “=” chunk-ext-value ] )
chunk-ext-name = token
chunk-ext-val = token | quoted-string
chunk-data = chunk-size(OCTET)

footer = *entity-header

即Chunk编码由四部分组成:1、0至多个chunk块,2、“0” CRLF,3、footer,4、CRLF.而每个chunk块由:chunk-size、chunk-ext(可选)、CRLF、chunk-data、CRLF组成。

着色器和光栅化

在 WebGL 中,开发者是通过着色器来完成上述变换的。着色器是运行在显卡中的程序,以 GLSL 语言编写,开发者需要将着色器的源码以字符串的形式传给 WebGL 上下文的相关函数。

着色器有两种,顶点着色器和片元(像素)着色器,它们成对出现。顶点着色器任务是接收顶点的局部坐标,输出 CCV 坐标。CCV 坐标经过光栅化,转化为逐像素的数据,传给片元着色器。片元着色器的任务是确定每个片元的颜色。

顶点着色器接收的是 attribute 变量,是逐顶点的数据。顶点着色器输出 varying 变量,也是逐顶点的。逐顶点的 varying 变量数据经过光栅化,成为逐片元的 varying 变量数据,输入片元着色器,片元着色器输出的结果就会显示在 Canvas 上。

金沙澳门官网网址 11

着色器功能很多,上述只是基本功能。大部分炫酷的效果都是依赖着色器的。如果你对着色器完全没有概念,可以试着理解下一节 hello world 程序中的着色器再回顾一下本节。

关于更多着色器的知识,可以参考:

  • GLSL@维基百科
  • WebGL@MSDN

本文由金沙澳门官网网址发布于金沙澳门官网网址,转载请注明出处:【金沙澳门官网网址】pwa重构上海地铁线路图,

关键词:

上一篇:用手机访问本地环境的利器ngrok,10分钟学会前端

下一篇:没有了