前端相关知识与技巧概括

300 阅读39分钟

@TOC

前后端分离与分家

前后端分离与分家:

  • 现在大部分前端新人只写「前后端分离的代码」,所以很难理解前后端分离的边界在哪里。
  • 其实判定很简单:如果前端和后端只通过简单的 API 文档就能进行数据交流,就说明他们的逻辑是 分离的。我们可以称之为「前后端代码分离」。
  • 如果除了 API 文档之外还需要各种其他的数据交流方式,比如后端把数据藏在一个 div 的属性里,那么就不是前后端分离的(因为这根本就不算是一个 API,只能算是一种「私下约定」,但是在实 际工程中,总是会保留一两个这样的约定)。
  • 这看起来是一句废话,但是很早之前的 Web 开发确实没有这个意识。导致页面代码杂乱,PHP 中 有 JS,JSP 中有 JS,ASP 中有JS,JS 中有 HTML,HTML 中有 CSS,HTML 中还有 JS,JS 中还 有 CSS,CSS 中还有 JS(比如 IE这个死浏览器)。代码一点也不「分离」。这种代码结构根本就 没有 API 的概念,只有数据在各处流窜,极难维护。为了鄙视这种代码,才有了前后端分离运动。
  • 但是要注意:前后端分离不代表前后端代码是两个人写的,如果代码是两个人写的,那么就是前后端「分家」。如果代码是一个人写的,这个人也不叫做「全栈开发者」,应该叫做 「Web 开发 者」,流行的叫法叫做「大前端」。
  • 前后端人员「分家」必然导致前后端代码「分离」。
  • 前后端分离的初衷是用「单一职责」原则把代码质量提上去,很难想象为什么之前的开发者连这么 基本的原则都不知道吧,其实是因为以前没有 AJAX这项技术,而且前端代码太少了,不值得花时 间分离。后来突然 Web 大爆发,JS 代码和 CSS代码从几百行跃升到几千行甚至几万行,不分一下 就说不过去了。
  • 前后端分离的一个不好的后果是让前后端人员分家(矫枉过正)。分家的问题我已经吐槽好几年了,不过之所以大公司喜欢让前后端人员分家,也是有一些客观原因的(康威定理)。(其实我很想说前后端分家就是错的,但是好像大家不喜欢听,那我就中庸一下吧) 为了防止有人扩大概念,我举一个明确的例子。 ①使用 groovy 调用 Java 服务 ②使用 groovy 响应前端的 AJAX 和 HTML 请求 ③使用 JavaScript 做前端界面
  • 这三件事都是一个开发者完成的,这就是一个 Web 开发者要做的事情。
  • 他不需要自己去写 SQL 语句,也不需要自己去连接 Redis。 上面的 groovy 可以换成任何你喜欢的语言,比如Python、Ruby 或者 JS,都一样。 这个时候如果你要问前后端分离在哪里,其实没有什么意义。因为既然前后端都是同一个人,其实不写文档也没事(当然还是写文档更好),如果你一定要他写文档,也是很简单事情,因为代码都 是他写的嘛。而且他自己在前端调用 HTTP服务的时候用的就是 AJAX + JSON 的方式,这很分离。
  • 这么做的最大好处就是节省人力和减少沟通时的信息损失。另一个好处就是让你多学一门语(我知道有些人认为多学一门语言是坏处),还有一个好处就是没有什么蛋疼的「前后端联调」了。

总结:

  • 前后端代码分离是百分百正确,而且是现在的主流,但是要不要分家(分成两个团队,一个前端,一个后端)则是值得商榷的。因为每次前后端撕逼和联调都是效率的瓶颈。
  • 请区别对待前后端代码「分离」,和前后端人员「分家」。如果你司已经把前后端「分家」了,那么基本上前后端代码也是「分离」的。但是如果你司没有让前后端「分家」,那么前后端代码可能是「分离」的,也可能是「不分离」的,如何判定前文已经说了。
  • 前后端分家的对立面并不是全栈,而是 Web 开发。未来的趋势是大前端,也就是我上面说到的groovy 的例子。

SSR和CSR

SSR服务端渲染和CSR客户端渲染:

  • SSR服务端渲染: ①SSR(Server Side Rendering) :传统的渲染方式,由服务端把渲染的完整的页面吐给客户端。 ②这样减少了一次客户端到服务端的一次http请求,加快相应速度,一般用于首屏的性能优化。
  • CSR客户端渲染: ①CSR(Client Side Rendering):是一种目前流行的渲染方式,它依赖的是运行在客户端的JS, ②用户首次发送请求只能得到小部分的指引性HTML代码。第二次请求将会请求更多包含HTML字符串的JS文件。
  • 简而言之: ①就是数据拼接HTML字符串这件事放在服务端还是客户端造成了两者区别。 ②也就是数据渲染发生在服务端还是客户端的区别。

两者有何不同:

  • 服务器端渲染的优势在于首屏渲染速度块,简单来讲它不需要来回多次往返于客户端和服务端。但是其性能等众多因素会影响用户体验,比如说:网速,在线活跃人数,服务器的物理位置等等。
  • 而客户端渲染则和服务端渲染相反,因为多次和服务器的交互导致首屏加载速度慢。但一旦这些请求完成之后,用户和页面之间的交互时用户体验就会好很多。
  • 用一个现实生活的例子来看:假如从超市买东西吃,以SSR的角度来看,你每次在超市买完随即吃完再走,每次饿了都需要出发去超市。
  • 而从CSR的角度来看,就是你从超市购买许多原材料再拿回家去自己煮,多了能放冰箱,这样每次肚子饿了就不需要每次都往超市跑,唯一麻烦一点在于你得花时间挑选食材。
  • 简而言之,SSR强在首屏渲染。而CSR强在用户和页面多交互的场景。

为什么会有服务器渲染与客户端渲染?

  • 一开始,Web App 直接由若干 HTML,CSS, JS组成,每一个页面需要特殊的逻辑,因此随着App规模的扩大,后端网站目录下的代码文件就越来越多,而且,彼此之间是没有同步的,比如你改了站点的布局风格。那么你很可能需要改动成百上千的HTML文件,这谁能忍?
  • 聪明的工程师们想到,既然如此多的HTML具有一定的逻辑联系,何不使用代码生成代码?于是后端模板语言诞生了,这可是前端狗的一大痛点啊,于是人们开始广泛使用模板语言代替手写HTML。我认为,模板语言的成功源于它成功地减少了前端工程师的工作量。
  • 后端模板渲染的思路应该是源自“如何管理数以千计的存储于后端的前端页面的版本一致?”这个问题的。通过代码生成代码,本质上是编译,他们基于HTML等基础语言作了更高层次的抽象封装,增强了易用性。各种模板语言大同小异,但大多都有模板中的模板这样的性质来完成继承这样的面向对象特性。
  • 可能,当时工程师们没有考虑前端渲染的一大原因是 以JavaScript为代表的前端技术尚未崛起现在H5,CSS3,JS受到越来越广的普及使得前端的可作为性大大提升,特别是在Node.js出现以后 JS 工程师维护后端的成本大大降低。

客户端渲染如何再度崛起?

  • 在一些jQuery用户的角度看来,JS生成前端无非就是这样的: ①你需要先把DOM生成,然后再插入到其他的DOM里去。 ②纯JS处理DOM确实是一件麻烦事,这可能也是客户端渲染迟迟没有发展起来的原因之一。
var e = document.createElement('div');
$('#container').append(e);
  • 考虑一下为什么后端模板语言方便简洁? 因为它用了与HTML类似的语法。 ①在PHP,JSP页面里面你可以使用大量的HTML语法,只使用少量的变量注入与迭代注入。 ②使用HTML进行设计明显比纯JS更方便快捷并且直观。
  • 那么可以借鉴地,解决客户端渲染问题的最后一个锦囊就是引入模板,在这里我们称之为组件(Component) 。 ①对待模板,新兴的Angular,React,Vue 意见不一,甚至他们对自己在Web App 的定位也不一样。 ②随着前端也支持了模板语言,那么以前的代码管理问题也解决了,以往的后端渲染引擎也大多有了基于JS的前端版本。
  • 前后端真正解耦,前端将专注于UI,后端将专注于数据处理,两端通过设计好的API进行交互,这会是一个趋势。

从后端渲染到前端渲染,发生了什么变化?

  • 计算任务转移 ①原本由服务器执行的渲染任务转移给了客户端,这在大量用户访问的时候大大减轻后端的压力。让后端专注做后端应该做的事情,性能将大大提高,因为服务器做的事情确实减小了,而现在随着客户端软硬件的发展,也能处理好大多数的渲染工作了。
  • 放弃前端权限 ①将整个UI逻辑交给客户端以后,一些有经验有能力的用户可能会劫持UI,使得他们能够看到一些不该看到的界面。这似乎违反了安全的原则。但是“一切在前端谈安全都是耍流氓”,后端不能轻信一切从前端传来的数据,切记一定要做好过滤与验证。只要使用SSL、屏蔽XSS、后端不出漏洞,想伪造身份劫持App还是难以做到的。 ②在前端存在一种名为XSS的攻击,一般通过在页面中插入script标签来远程执行代码。过滤script标签等转义可破被动XSS,另外可以通过提示用户不在console使用未知代码来预防主动XSS攻击。XSS攻击是非常危险的,必须做好防范。

服务器端渲染如何工作:

  • 上面其实提到服务器端渲染就是将一个完整的HTML发送给客户端,客户端只负责HTML的解析。只不过它会被网速等等客观因素所约束造成用户体验不佳的情况。而且如果面临客户端和服务器多次交互的情况就显得非常吃亏,即使在页面只是有稍加改动的地方都需要重新请求到一个完整页面并且重新进行渲染。这谁顶得住阿?服务器它老人家也顶不住。
  • 下面用实例展现一下服务器端渲染的HTML长什么样子:
  • 假设你需要访问的域名叫: example.testsite.com.
<html>
  <head>
    <meta charset="utf-8">
    <title>Example Website</title>
  </head>
  <body>
    <h1>My Website</h1>
    <p>This is an example of my new website</p>
    <a href="http://example.testsite.com/other.html.">Link</a>
  </body>
</html>
  • 我们此时点击 ##Link## 这个链接,弹出来下面这个页面 other.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Example Website</title>
  </head>
  <body>
    <h1>My Website</h1>
    <p>This is an example of my new website</p>
    <p>This is some more content from the other.html</p>
  </body>
</html>
  • 可以看出来两个页面的差异就只有一行,但是渲染过程时将整个页面重新渲染,而不仅仅只是发生更改的一行,在当今越加复杂的页面来看动辄几百行的代码来看,要是每次发生少量更改都需要重新渲染整个页面显然是不符合潮流的。
  • 从上面的页面特征来看,使用服务器端渲染的返回的页面是完整的HTML页面。

客户端渲染如何工作:

  • 客户端渲染代表渲染内容部分转嫁到JS身上。客户端只是从服务器得到相对简单的HTML文档,然后使用JS文件对页面的显示内容进行控制。就像Vue.js用的就是这种方式,还是用刚才那个例子,看看用客户端渲染是怎么做的。
  • 假设你想要访问的域名是example.testsite.com
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Example Website</title>
</head>
<body>
  <div id="root">
    <app></app>
  </div>
    <!--下面两个js文件控制HTML的显示内容 -->
  <script src="https://vuejs.org"type="text/javascript"></script>
  <script src="location/of/app.js"type="text/javascript"></script>
</body>
</html>
  • 从以上的html页面上你只可以看到自定义的组件名id为root的div标签,而所有的逻辑处理都在app.js里面,所有如果需要成功展示出页面原有的样子就需要app.js这个文件下载到本地,如果通过直接访问的方式页面只会一片空白。
  • 因此,下面补充app.js文件内容:
// this is app.js
var data = {
        title:"My Website",
        message:"This is an example of my new website"
      }
  Vue.component('app', {
    template:
    `
    <div>
    <h1>{{title}}</h1>
    <p id="moreContent">{{message}}</p>
    <a v-on:click='newContent'>Link</a>
    </div>
    `,
    data: function() {
      return data;
    },
    methods:{
      newContent: function(){
        var node = document.createElement('p');
        var textNode = document.createTextNode('This is some more content from the other.html');
        node.appendChild(textNode);
        document.getElementById('moreContent').appendChild(node);
      }
    }
  })
  new Vue({
    el: '#root',
  });
  • 目前来看,从显示效果来看能够展示和之前SSR一样的效果,不同的是,当我们点击Link链接的时候,页面不会和服务器之间又交互。此时只对Link那一行的代码做了修改,其余位置保持不变。而不是像SSR做了整个页面的重新渲染。
  • 但是这里暴露的问题也很明显,但控制页面的所有js文件如果没有完全加载的话,整个页面是渲染不出来的,这才是导致客户端渲染弱于首屏渲染的原因。
  • 从这个例子来看,可以看出客户端渲染的页面特征是包含有js链接的script标签。

总结SSR和CSR的优势和劣势:

在这里插入图片描述

html网页渲染的基本过程

简述:

  • 整个渲染的过程其实就是将URL对应的各种资源,通过浏览器渲染引擎的解析,输出可视化的图像。(页面渲染) -
  • 渲染模块:在这里插入图片描述
  • 从图中可以看出,一个渲染引擎大致包括HTML解释器、CSS解释器、布局和JavaScript引擎。
  • HTML解释器:解释HTML语言的解释器,本质是将HTML文本解释成DOM树(文档对象模型)。
  • CSS解释器:解释样式表的解释器,其作用是将DOM中的各个元素对象加上样式信息,从而为计算最后结果的布局提供依据。
  • 布局:将DOM和css样式信息结合起来,计算它们的大小位置等布局信息,形成一个能够表示这所有信息的内部表示模型即渲染树。
  • JavaScript引擎:JavaScript可以修改网页的内容,也能修改CSS的信息,JavaScript引擎解释JavaScript代码并把代码的逻辑和对DOM和CSS的改动信息应用到布局中去,从而改变渲染的结果。
  • 这些模块依赖很多其他的基础模块,这其中包括网络,存储,2D/3D图形,音频视频和图片解码器等。实际上,渲染引擎中还应该包括如何使用这些依赖模块的部分,这部分的工作其实并不少,因为需要使用它们来高效的渲染网页。例如,利用2D/3D图形库来实现高性能的网页绘制和网页的3D渲染,这个实现非常非常的复杂。最后,当然,在最下面,依然少不了操作系统的支持,例如线程支持,文件支持等等。
  • 基本过程 1.解析HTML文件,创建DOM树 2.解析CSS,形成CSS对象模型 3.将CSS与DOM合并,构建渲染树(renderingtree) 4.布局和绘制
  • 对渲染树上的每个元素,计算它的坐标,称之为布局。浏览器采用一种流方法,布局一个元素只需通过一次,但是表格元素需要通过多次。
  • 最后,渲染树上的元素最终展示在浏览器里,这一过程称为“painting”。
  • 当用户与网页交互,或者脚本程序改动修改网页时,前文提到的一些操作将会重复执行,因为网页的内在结构已经发生了改变。
  • html网页渲染的基本过程

模板引擎(前端)

模板引擎:

  • 模板的工作原理可以简单地分成两个步骤:模板解析(翻译)和数据渲染。这两个步骤可分别部署在前端或后端来执行。
  • 如果放在后端执行,则是像Smarty,FreeMarker这样的后端模板引擎,而如果放在前端来执行,则是我们要探讨的前端模板。
  • 前端模版提高了前端开发的可维护性(后期改起来方便)以及可扩展性(想要增加功能,增加需求方便);提高了开发效率提高(程序逻辑组织更好,调试方便)。最重要的一点就是:【视图(包括展示渲染逻辑)与程序逻辑的分离】。好处是减轻服务器负担,坏处是可能不利于seo以及模版错误不好调试。

当今前端模版主要有三类:

  • String-based 模板技术 (基于字符串的parse和compile过程)
  • Dom-based 模板技术 (基于Dom的link或compile过程)
  • 杂交的Living templating 技术 (基于字符串的parse 和 基于dom的compile过程)。

前端模版的演变:

  • 传统的前端开发方式是通过通过ajax获取数据进行繁琐的数据渲染。随着前端页面的交互越来越繁杂,页面无刷新的传输与页面的显然也越发的频繁,导致页面性能低下。即当前端从后台通过ajax等方式获取到数据更新后,都需要将这个数据渲染到指定的dom元素中,需要重新进行各种字符串拼接工作或者一系列创建元素的工作,这种方式是繁琐且费时的。这种在可读性和维护性上也存在问题。
  • 基于字符串的模板引擎最大的功劳就是把你从大量的夹带逻辑的字符串拼接中解放出来了,由于它的完全基于字符串的特性,它拥有一些无可替代的优势。如下的字符串拼接:在这里插入图片描述
  • Dom-based的模板技术中,如果你需要从一段字符串创建出一个view,你必然通过innerHTML来获得初始Dom结构. 然后引擎会利用Dom API(attributes, getAttribute, firstChild… etc)层级的从这个原始Dom的属性中提取指令、事件等信息,Dom-based的模板技术并没有完整的parse的过程。继而完成数据与View的绑定,使其”活动化”。所以Dom-based的模板技术更像是一个数据与dom之间的“链接”和*“改写”*过程。 完成compile之后,data与View仍然保持联系,即你可以不依赖与手动操作Dom API来更新View。
  • String-based 和 Dom-based的模板技术都或多或少的依赖与innerHTML, 它们的区别是一个是主要是为了Rendering 一个是为了 Parsing 提取信息。Living Template Engine模版引擎的解析过程类似于String-based 模板技术 和 compile过程类似于Dom-based模板技术。
  • 链接:前端数据模版引擎的总结

双向绑定和单向绑定

单向数据绑定是什么?

  • 数据模型(Module)和视图(View)之间的单向绑定。
  • 需要我们先写好模板,然后把模板和数据(可能来自后台)整合到一起形成HTML代码,然后把这段HTML代码插入到文档流里面。 简单的来说就是DOM操作html元素。
  • 单向数据绑定的缺点:一旦HTML代码生成好后,就没有办法再进行改变了,如果有新的数据出现,那就必须要先把之前的HTML代码删掉,然后重新把新的数据和模板一起整合形成新的HTML代码,再插入到文档流中。

双向数据绑定是什么?

  • 数据模型和视图之间的双向绑定。
  • 当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化;可以这样说用户在视图上的修改会自动同步到数据模型中去,数据模型也是同样的变化。
  • 双向数据绑定的优点:无需和单向数据绑定那样进行CRUD(Create,Retrieve,Update,Delete)操作,双向数据绑定最常应用在就表单上,这样当用户在前端页面完成输入后,不用任何操作,我们就已经拿到了用户输入好的数据,并放到数据模型中了。

Node.js和前后端分离

什么是中间层:

  • 通常我们把Web领域分为客户端和服务端,也就是前端和后端,这里的后端就包含了网关,静态资源,接口,缓存,数据库等。
  • 而中间层呢,就是在后端这里再抽离一层出来,在业务上处理和客户端衔接更紧密的部分,比如页面渲染(SSR),数据聚合,接口转发等等。
  • 以SSR来说,在服务端将页面渲染好,可以加快用户的首屏加载速度,避免请求时白屏,还有利于网站做SEO,他的好处是比较好理解的。

那么对于数据的聚合,接口转发来说,这样做有什么意义呢?

  • 业务驱动 ①Node有个突出的优势,他的开发者可以是前端。 ②前端对于页面所需要的数据有更好的理解,每个页面要用到哪些接口,每个接口要用到哪些字段前端是最清楚的。再加上实际业务开发中,前端页面需求经常会发生变化,需要修改字段或者数据结构,所以对接页面的这部分接口由前端直接开发非常合适,可以显著的减少沟通成本。
  • 架构需要 ①面向用户的接口由Node中间层负责以后,真正的服务端可以专注于提供基于领域模型的对内接口,做微服务。 ②比如可以基于Goods模型,提供所有商品相关的接口;基于Users模型,提供所有用户相关接口。当一个接口需要商品+用户信息时,由Node分别查询组装。从整体业务代码维护角度来说,变得更容易,不会因为业务发展使得每个接口都异常繁杂。
  • 性能满足 ①如果仅仅是架构层面的需求,需要有一个中间层来沉淀业务,那用Java,PHP也可以做到,为什么说Node更适合做呢? ②因为Node天生异步! ③众所周知,js是一门单线程语言,所以Node在实现的时候,需要借助libuv来实现异步。
  • 成本较低 ①Node使用js开发,只需要学习简单的api,前端开发者就可以无障碍使用,学习成本很低。 ②而且,Node具有活跃的社区和丰富的模块池,拥有很多现成的功能实现。框架方面,也有成熟的koa,express等基本框架和egg等二次封装框架,可根据需求选择上手也比较方便。 在这里插入图片描述

使用Node.js的演变:

  • 后端MVC ①前端写Demo,后端套页面 <1>问题:后端需要写HTML,且前端仍然需要确认后端写的HTML。 ②前端写View层,后端只管数据 <1>问题:前端需要熟悉后端语言,且前端需要了解后端架构。
  • CLIENT-SIDE MV:接口分离, 后端提供数据, 前端自己搞 ①MODEL层 - JAVASCRIPT OBJECT ②VIEW层 - JAVASCRIPT TEMPLATE ③业界满坑满谷的优秀方案:Backbone, EmberJS, KnockoutJS, AngularJS, React, etc. ④问题: <1>各层职责重叠,并且各玩各的 <2>性能问题 <3>重用问题 <4>跨终端问题 <5>SEO问题
  • 重新定义前后端,使用node.js架构中间层 ①前端熟悉的语言,学习成本低 ②都是JS,可以前后端复用 ③体质适合:事件驱动、非阻塞I/O ④适合IO密集型业务 ⑤执行速度也不差
  • 链接: ①为什么用Node.js搭建中间层基于NodeJS进行前后端分离

总结:

  • 使用Node:vue在npm run dev后为什么就在localhost运行了?这个问题的实质是用node调用http模块启用了一个web服务器。 ①vue写前端工程,用node运行。在node服务端生成页面。返回浏览器。
  • 不使用Node:放在Resource中的static文件夹中。 ①vue工程写好之后,用webpack打包,生成html,js,css。你.net或者静态站点把文件copy过去。

前端路由与后端路由的区别

什么是路由:

  • 在Web开发过程中,经常会遇到『路由』的概念。那么,到底什么是路由?简单来说,路由就是URL到函数的映射。
  • 访问的URL会映射到相应的函数里(这个函数是广义的,可以是前端的函数也可以是后端的函数),然后由相应的函数来决定返回给这个URL什么东西。路由就是在做一个匹配的工作。
  • 链接:说一说前端路由与后端路由的区别

后端路由与服务端渲染:

  • 「你从浏览器地址栏里输入www.baidu.com到你看到网页这个过程中经历了什么」其实讲的也是这个道理。在这里插入图片描述
  • 随着web应用的开发越来越复杂,单纯服务端渲染的问题开始慢慢的暴露出来了——耦合性太强了,jQuery时代的页面不好维护,页面切换白屏严重等等。耦合性问题虽然能通过良好的代码结构、规范来解决,不过jQuery时代的页面不好维护这是有目共睹的,全局变量满天飞,代码入侵性太高。后续的维护通常是在给前面的代码打补丁。而页面切换的白屏问题虽然可以通过ajax、或者iframe等来解决,但是在实现上就麻烦了——进一步增加了可维护的难度。
  • 于是,我们开始进入了前端路由的时代。

过渡到前端路由:

  • 前端路由——顾名思义,页面跳转的URL规则匹配由前端来控制。而前端路由主要是有两种显示方式: ①带有hash的前端路由,优点是兼容性高。缺点是URL带有#号不好看 ②不带hash的前端路由,优点是URL不带#号,好看。缺点是既需要浏览器支持也需要后端服务器支持
  • 前端路由应用最广泛的例子就是当今的SPA的web项目。不管是Vue、React还是Angular的页面工程,都离不开相应配套的router工具。前端路由带来的最明显的好处就是,地址栏URL的跳转不会白屏了——这也得益于前端渲染带来的好处。
  • 讲前端路由就不能不说前端渲染。我以Vue项目为例。如果你是用官方的vue-cli搭配webpack模板构建的项目,你有没有想过你的浏览器拿到的html是什么样的?是你页面长的那样有button有form的样子么?我想不是的。在生产模式下,你看看构建出来的index.html长什么样:
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Vue</title>
</head>
<body>
  <div id="app"></div>
  <script type="text/javascript" src="xxxx.xxx.js"></script>
  <script type="text/javascript" src="yyyy.yyy.js"></script>
  <script type="text/javascript" src="zzzz.zzz.js"></script>
</body>
</html>
  • 通常长上面这个样子。可以看到,这个其实就是你的浏览器从服务端拿到的html。这里面空荡荡的只有一个\<div id="app"\>\</div\>这个入口的div以及下面配套的一系列js文件。所以你看到的页面其实是通过那些js渲染出来的。这也是我们常说的前端渲染。在这里插入图片描述
  • 前端渲染把渲染的任务交给了浏览器,通过客户端的算力来解决页面的构建,这个很大程度上缓解了服务端的压力。而且配合前端路由,无缝的页面切换体验自然是对用户友好的。不过带来的坏处就是对SEO不友好,毕竟搜索引擎的爬虫只能爬到上面那样的html,对浏览器的版本也会有相应的要求。
  • 需要明确的是,只要在浏览器地址栏输入URL再回车,是一定会去后端服务器请求一次的。而如果是在页面里通过点击按钮等操作,利用router库的api来进行的URL更新是不会去后端服务器请求的。

两种路由模式:

  • Hash模式: ①hash模式利用的是浏览器不会对#号后面的路径对服务端发起路由请求。也即在浏览器里输入如下这两个地址:http://localhost/#/user/1和http://localhost/其实到服务端都是去请求http://localhost这个页面的内容。 ②而前端的router库通过捕捉#号后面的参数、地址,来告诉前端库(比如Vue)渲染对应的页面。这样,不管是我们在浏览器的地址栏输入,或者是页面里通过router的api进行的跳转,都是一样的跳转逻辑。所以这个模式是不需要后端配置其他逻辑的,只要给前端返回http://localhost对应的html,剩下具体是哪个页面,就由前端路由去判断便可。
  • History模式: ①不带#号的路由,也就是我们通常能见到的URL形式。router库要实现这个功能一般都是通过HTML5提供的history这个api。比如history.pushState()可以向浏览器地址栏push一个URL,而这个URL是不会向后端发起请求的!通过这个特性,便能很方便地实现漂亮的URL。不过需要注意的是,这个api对于IE9及其以下版本浏览器是不支持的,IE10开始支持,所以对于浏览器版本是有要求的。vue-router会检测浏览器版本,当无法启用history模式的时候会自动降级为hash模式。 ②上面说了,你在页面里的跳转,通常是通过router的api去进行的跳转,router的api调用的通常是history.pushState()这个api,所以跟后端没什么关系。但是一旦你从浏览器地址栏里输入一个地址,比如http://localhost/user/1,这个URL是会向后端发起一个get请求的。后端路由表里如果没有配置相应的路由,那么自然就会返回一个404了!这也就是很多朋友在生产模式遇到404页面的原因。 ③那么很多人会问了,那为什么我在开发模式下没问题呢?那是因为vue-cli在开发模式下帮你启动的那个express开发服务器帮你做了这方面的配置。理论上在开发模式下本来也是需要配置服务端的,只不过vue-cli都帮你配置好了,所以你就不用手动配置了。 ④那么该如何配置呢?其实在生产模式下配置也很简单,参考vue-router给出的配置例子。一个原则就是,在所有后端路由规则的最后,配置一个规则,如果前面其他路由规则都不匹配的情况下,就执行这个规则——把构建好的那个index.html返回给前端。这样就解决了后端路由抛出的404的问题了,因为只要你输入了http://localhost/user/1这地址,那么由于后端其他路由都不匹配,那么就会返回给浏览器index.html。 ⑤浏览器拿到这个html之后,router库就开始工作,开始获取地址栏的URL信息,然后再告诉前端库(比如Vue)渲染对应的页面。到这一步就跟hash模式是类似的了。 ⑥当然,由于后端无法抛出404的页面错误,404的URL规则自然是交给前端路由来决定了。你可以自己在前端路由里决定什么URL都不匹配的404页面应该显示什么。

MVC与前后端分离和模版引擎

MVC与后端模版引擎渲染:

  • MVC是一种经典的设计模式,Model-View-Controller,即模型-视图-控制器。M主要负责数据与模型,V主要负责显示,C主要负责交互与业务。
  • 模型是用于封装数据的载体,其本质是一个普通的Java Bean,包含一系列的成员变量及其getter/setter方法;
  • 视图而言,更加偏重于展现,在Java中可通过JSP来充当视图,或通过纯HTML进行展现,目前的主流是纯HTML;
  • 模型和视图需要通过控制器来进行粘合,如用户发送一个HTTP请求,此时该请求首先会进入控制器,然后控制器去获取数据并将其封装为模型,最后将模型传递到视图中进行展现。在这里插入图片描述
  • 缺点: ①前端写完静态页面,要让后台去「套模板」,每次前端稍有改动,后台对应的模板页面同时也需要改动,非常麻烦。页面中如果有复杂的 JS,前端写还是后端写?前端写的话,没有大量的数据,调试不方便,后端写的话...
  • 优点: ①这样做有利于 SEO,并且与前端请求接口的方式相比,少了个 HTTP 请求,理论上加载速度可能会稍微快些。

MVC与前端JS渲染:

  • 为了使数据展现过程更加直接,提供更好的用户体验,对MVC做了改进。
  • AJAX 的出现使得前后端分离成为可能。后端专注于业务逻辑,给前端提供接口,而前端通过 AJAX 的方式向后端请求数据,然后动态渲染数据。 在这里插入图片描述 在这里插入图片描述

MVC与前端模版引擎渲染:

  • 将 HTML 代码(View 层)和 JS 代码(Controller 层)混杂在了一起,UI与逻辑代码混杂在一起,阅读起来会非常吃力。一旦业务复杂起来,或者多人维护的情况下,几乎会失控。而且如果需要拼接的 HTML代码里有很多引号的话(比如有大量的 href 属性,src 属性),那么就非常容易出错了。
  • 这个时候,前端模板引擎出现了,常用的模板引擎有tpl.js、baiduTemplate、doT.js、art-template等等。模板引擎就是把js数据传到html中展示出来。
  • 这样一来,如果前端需要改 HTML 代码,只需要改模板即可。这样做的优点很明显,前端 UI 和逻辑代码不再混杂,阅读体验良好,改动起来也方便了许多。

MVMM与前端模版引擎渲染:

  • 任何开发模式在交互层面做的事最终只有两件: ①DOM节点的CRUD ②DOM事件的CRUD

  • “模板+ajax” 的开发模式下,这两件事,都需要手动一个一个去完成

  • angular和vue的开发模式下,viewmodel层对这两件事进行了集成,通过特有的半配置化的ng-和v-语法来完成。viewmodel响应model的变化事件来影响view,也响应view的变化事件来影响model。重点在理解viewmodel

  • “arttemplate+ajax”开发模式转VUE时,要时刻注意两者思路区别:界面不是被事件改变的,事件只需要改变数据,界面是数据的实时反馈。”arttemplate+ajax”是组合操作,而vue的着眼点是前端开发框架

  • JQuery使用最多的是:选择器$,操作DOM树,ajax,JQuery各种插件。vue的所有的操作关注点都在data上面,通过修改data来控制DOM树!从DOM操作时代完美过渡到MVVM时代。

  • arttemplate+ajax 转 vue

前后端分离最大的缺点:

  • 就是 SEO 无力了,毕竟爬虫只会抓取 HTML 代码,不会去渲染 JS。

Node 中间层:

  • 单纯的后端模板引擎(后端 MVC)以及前端模板引擎方式都有一定的局限性,Node 的出现让我们有了第三种选择,让 Node 作为中间层。
  • 简单地说就是让一门后台语言(比如 Java?PHP?)单纯提供渲染页面所需要的接口,Node中间层用模板引擎来渲染页面,使得页面直出。这样一来,后台提供的接口,不仅 Web 端可以使用,APP,浏览器也可以调用,同时页面 Node直出也不会影响 SEO,并且前后端也分离,不失为一种比较完美的方案。
  • 也就是通过Node来实现SSR使得不影响SEO与加快首屏渲染。

单页应用SPA:

  • 所谓单页应用,指的是在一个页面上集成多种功能,甚至整个系统就只有一个页面,所有的业务功能都是它的子模块,通过特定的方式挂接到主界面上。它是AJAX技术的进一步升华,把AJAX的无刷新机制发挥到极致,因此能造就与桌面程序媲美的流畅用户体验。
  • 简单来说就是SPA只有一个入口文件(index.html),靠路由切换组件,后台提供api。
  • 为了解决单页应用规模增大时候的代码逻辑问题,出现了不少MV*框架,他们的基本思路都是在JS层创建模块分层和通信机制。有的是MVC,有的是MVP,有的是MVVM,而且,它们几乎都在这些模式上产生了变异,以适应前端开发的特点。
  • 这类框架包括Backbone,Knockout,AngularJS,Avalon等。
  • 传统的页面型产品是不存在路由与状态的管理的问题,因为它就是以页面为单位的,也有的时候,服务端路由处理了这一切。但是在单页应用中,这成为了问题,因为我们只有一个页面,界面上的各种功能区块是动态生成的。所以我们要通过对路由的管理,来实现这样的功能。
  • 传统的Web产品通常使用JSONP或者AJAX这样的方式与服务端通信,但在单页Web应用中,有很大一部分采用WebSocket这样的实时通讯方式。WebSocket与传统基于HTTP的通信机制相比,有很大的优势。它可以让服务端很便利地使用反向推送,前端只响应确实产生业务数据的事件,减少一遍又一遍无意义的AJAX轮询。
  • 缺陷:单页应用最根本的缺陷就是不利于SEO,因为界面的绝大部分都是动态生成的,所以搜索引擎很不容易索引它。
  • 构建单页Web应用

总结来说:

  • 前后端分离不在于是否MVC还是MVMM,在于数据与视图是否耦合,在于前后端是否能靠接口api实现。
  • MVC和MVMM的区别在于后者比前者有更高的开发效率和性能!

前端构建工具

简介:

  • 历史上先后出现了一系列构建工具,它们各有优缺点。由于前端工程师很熟悉JavaScript,Node.js又可以胜任所有构建需求,所以大多数构建工具都是用Node.js开发的。
  • 前端技术发展之快,各种可以提高开发效率的新思想和框架层出不穷。但是它们都有一个共同点:源代码无法直接运行,必须通过转换后才可以正常运行。
  • 构建就是做这件事情,将源代码转换成可执行的JavaScript、CSS、HTML代码,包括如下内容: ①代码转换:将TypeScript编译成JavaScript、将SCSS编译成CSS等。 ②文件优化:压缩JavaScript、CSS、HTML代码,压缩合并图片等。 ③代码分割:提取多个页面的公共代码,提取首屏不需要执行部分的代码让其异步加载。 ④模块合并:在采用模块化的项目里会有很多个模块和文件,需要通过构建功能将模块分类合并成一个文件。 ⑤自动刷新:监听本地源代码的变化,自动重新构建、刷新浏览器。 ⑥代码校验:在代码被提交到仓库前需要校验代码是否符合规范,以及单元测试是否通过。 ⑦自动发布:更新代码后,自动构建出线上发布代码并传输给发布系统。
  • 构建其实是工程化、自动化思想在前端开发中的体现,将一系列流程用代码去实现,让代码自动化地执行这一系列复杂的流程。构建为前端开发注入了更大的活力,解放了我们的生产力。

Npm Script:

  • Npm Script(docs.npmjs.com/misc/script… 是一个任务执行者。Npm是在安装Node. js时附带的包管理器,Npm Script则是Npm内置的一个功能,允许在package.json文件里面使用scripts字段定义任务:
{
  "scripts": {
    "dev": "node dev.js",
    "pub": "node build.js"
  }
}
  • 里面的scripts字段是一个对象,每个属性对应一段Shell脚本,以上代码定义了两个任务:dev和pub。其底层实现原理是通过调用Shell去运行脚本命令,例如,执行npm run pub命令等同于执行node build.js命令。

  • NpmScript的优点是内置,无须安装其他依赖。其缺点是功能太简单,虽然提供了pre和post两个钩子,但不能方便地管理多个任务之间的依赖。

Grunt:

  • Grunt(gruntjs.com) 和Npm Script类似,也是一个任务执行者。
  • Grunt有大量现成的插件封装了常见的任务,也能管理任务之间的依赖关系,自动化地执行依赖的任务,每个任务的具体执行代码和依赖关系写在配置文件Gruntfile.js里,
  • 例如:
module.exports = function(grunt) {
  // 所有插件的配置信息
  grunt.initConfig({
    // uglify插件的配置信息
    uglify: {
      app_task: {
        files: {
          'build/app.min.js': ['lib/index.js', 'lib/test.js']
        }
      }
    },
    // watch插件的配置信息
    watch: {
      another: {
          files: ['lib/*.js'],
      }
    }
  });
  // 告诉Grunt我们将使用这些插件
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');
  // 告诉Grunt我们在终端中启动Grunt时需要执行哪些任务
  grunt.registerTask('dev', ['uglify','watch']);
};
  • 在项目根目录下执行命令grunt dev,就会启动JavaScript文件压缩和自动刷新功能。
  • Grunt的优点是: ①灵活,它只负责执行我们定义的任务; ②大量的可复用插件封装好了常见的构建任务。 ③Grunt的缺点是集成度不高,要写很多配置后才可以用,无法做到开箱即用。 ④Grunt相当于进化版的Npm Script,它的诞生其实是为了弥补Npm Script的不足。

Gulp:

// 引入 Gulp
var gulp = require('gulp'); 
// 引入插件
var jshint = require('gulp-jshint');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
// 编译SCSS任务
gulp.task('sass', function() {
  // 读取文件,通过管道喂给插件
  gulp.src('./scss/*.scss')
    // SCSS 插件将 scss 文件编译成 CSS 文件
    .pipe(sass())
    // 输出文件
    .pipe(gulp.dest('./css'));
});
// 合并压缩JavaScript文件
gulp.task('scripts', function() {
  gulp.src('./js/*.js')
    .pipe(concat('all.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./dist'));
});
// 监听文件的变化
gulp.task('watch', function(){
  // 当 scss 文件被编辑时执行 SCSS 任务
  gulp.watch('./scss/*.scss', ['sass']);
  gulp.watch('./js/*.js', ['scripts']);    
});
  • Gulp的优点是好用又不失灵活,既可以单独完成构建,也可以和其他工具搭配使用。其缺点和Grunt类似,集成度不高,要写很多配置后才可以用,无法做到开箱即用。

  • 可以将Gulp看作Grunt的加强版。相对于Grunt,Gulp增加了监听文件、读写文件、流式处理的功能。

Fis3:

  • Fis3(fex.baidu.com/fis3/)是一个来自… ①读写文件:通过fis.match读文件,release配置文件的输出路径。 ②资源定位:解析文件之间的依赖关系和文件位置。 ③文件指纹:在通过useHash配置输出文件时为文件URL加上md5戳,来优化浏览器的缓存。 ④文件编译:通过parser配置文件解析器做文件转换,例如将ES6编译成ES5。 ⑤压缩资源:通过optimizer配置代码压缩方法。 ⑥图片合并:通过spriter配置合并CSS里导入的图片到一个文件中,来减少HTTP请求数。
  • 大致使用如下:
// 加md5
fis.match('*.{js,css,png}', {
  useHash: true
});
// 通过fis3-parser-typescript插件可将TypeScript文件转换成JavaScript文件
fis.match('*.ts', {
  parser: fis.plugin('typescript')
});
// 对CSS进行雪碧图合并
fis.match('*.css', {
  // 为匹配到的文件分配属性useSprite
  useSprite: true
});
// 压缩JavaScript
fis.match('*.js', {
  optimizer: fis.plugin('uglify-js')
});
// 压缩CSS
fis.match('*.css', {
  optimizer: fis.plugin('clean-css')
});
// 压缩图片
fis.match('*.png', {
  optimizer: fis.plugin('png-compressor')
});
  • 可以看出Fis3很强大,内置了许多功能,无须做太多配置就能完成大量工作。
  • Fis3的优点是集成了各种Web开发所需的构建功能,配置简单、开箱即用。其缺点是目前官方已经不再更新和维护,不支持最新版本的Node.js。
  • Fis3是一种专注于Web开发的完整解决方案,如果将Grunt、Gulp比作汽车的发动机,则可以将Fis3比作一辆完整的汽车。

Webpack:

在这里插入图片描述

  • 一切文件如JavaScript、CSS、SCSS、图片、模板,对于Webpack来说都是一个个模块,这样的好处是能清晰地描述各个模块之间的依赖关系,以方便Webpack对模块进行组合和打包。经过Webpack的处理,最终会输出浏览器能使用的静态资源。
  • Webpack具有很大的灵活性,能配置处理文件的方式,使用方法大致如下:
module.exports = {
  // 所有模块的入口,Webpack从入口开始递归解析出所有依赖的模块
  entry: './app.js',
  output: {
    // 将入口所依赖的所有模块打包成一个文件bundle.js输出 
    filename: 'bundle.js'
  }
}
  • Webpack的优点是: ①专注于处理模块化的项目,能做到开箱即用、一步到位; ②可通过Plugin扩展,完整好用又不失灵活; ③使用场景不局限于Web开发; ④社区庞大活跃,经常引入紧跟时代发展的新特性,能为大多数场景找到已有的开源扩展; ⑤良好的开发体验。 ⑥Webpack的缺点是只能用于采用模块化开发的项目。

Rollup:

为什么选择Webpack:

  • 上面介绍的构建工具是按照它们诞生的时间排序的,它们是时代的产物,侧面反映出Web开发的发展趋势,如下所述: ①在Npm Script和Grunt时代,Web开发要做的事情变多,流程复杂,自动化思想被引入,用于简化流程; ②在Gulp时代,开始出现一些新语言用于提高开发效率,流式处理思想的出现是为了简化文件转换的流程,例如将ES5转换成ES6; ③在Webpack时代,由于单页应用的流行,网页的功能和实现代码变得复杂、庞大,Web开发向模块化改进。
  • 这些构建工具都有各自的定位和专注点,它们之间既可以单独完成任务,也可以相互搭配来弥补各自的不足。在了解这些常见的构建工具后,我们需要根据自己的需求去判断应该如何选择和搭配它们才能更好地满足自己的需求。
  • 经过多年的发展,Webpack已经成为构建工具中的首选,这是有原因的: ①大多数团队在开发新项目时会采用紧跟时代的技术,这些技术几乎都会采用“模块化+新语言+新框架”,Webpack可以为这些新项目提供一站式的解决方案; ②Webpack有良好的生态链和维护团队,能提供良好的开发体验并保证质量; ③Webpack被全世界大量的Web开发者使用和验证,能找到各个层面所需的教程和经验分享。

NPM

什么是npm?

  • npm 由三个独立的部分组成: ①网站:网站是开发者查找包(package)、设置参数以及管理 npm 使用体验的主要途径。 ②注册表(registry):注册表 是一个巨大的数据库,保存了每个包(package)的信息。 ③命令行工具 (CLI):CLI 通过命令行或终端运行。开发者通过 CLI 与 npm 打交道。
  • 一般来说提起npm有两个含义, ①一个是说npm官方网站, ②一个就是说npm包管理工具。
  • npm社区或官网是一个巨大的Node生态系统,社区成员可以随意发布和安装npm生态中的包,也就是不用在重复造轮子了,别人造好了,你直接安装到你的项目中就可以使用,但是因为前面说了,当包引入数量很多时管理就成为了一个问题,这个就是npm为开发者行了方便之处,npm已经为你做好了依赖和版本的控制,也就是说使用npm可以让你从繁杂的依赖安装和版本冲突中解脱出来,进而关注你的业务而不是库的管理。

npm与webpack的关系:

  • webpack就是将你从npm中安装的包打包成更小的浏览器可读的静态资源,
  • 这里需要注意的是,webpack只是一个前端的打包工具,打包的是静态资源,和后台没有关系,虽然webpack依赖于node环境

NPM使用:

  • NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种: ①允许用户从NPM服务器下载别人编写的第三方包到本地使用。 ②允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。 ③允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。

浏览器F12开发者工具

如何调出开发者工具:

  • 按F12调出
  • 右键检查(或快捷键Ctrl+Shift+i)调出

开发者工具初步介绍:

  • 元素(Elements):用于查看或修改HTML元素的属性、CSS属性、监听事件、断点等。css可以即时修改,即时显示。大大方便了开发者调试页面。
  • 控制台(Console):控制台一般用于执行一次性代码,查看JavaScript对象,查看调试日志信息或异常信息。还可以当作JavascriptAPI查看用。例如我想查看console都有哪些方法和属性,我可以直接在Console中输入"console"并执行。
  • 源代码(Sources):该页面用于查看页面的HTML文件源代码、JavaScript源代码、CSS源代码,此外最重要的是可以调试JavaScript源代码,可以给JS代码添加断点等。
  • 网络(Network):网络页面主要用于查看header等与网络连接相关的信息。
  • 详细链接:浏览器F12开发者工具介绍

元素(Elements):

  • 查看元素的代码:点击左上角的箭头图标(或按快捷键Ctrl+Shift+C)进入选择元素模式,然后从页面中选择需要查看的元素,然后可以在开发者工具元素(Elements)一栏中定位到该元素源代码的具体位置
  • 查看元素的属性:定位到元素的源代码之后,可以从源代码中读出改元素的属性。如下图中的class、src、width等属性的值。在这里插入图片描述
  • 当然从源代码中读到的只是一部分显式声明的属性,要查看该元素的所有属性,可以在右边的侧栏中查看:在这里插入图片描述
  • 修改元素的代码与属性:点击元素,然查看右键菜单,可以看到chrome提供的可对元素进行的操作:包括编辑元素代码(Edit as HTML)、修改属性(Add attribute、Edit attribute)等。选择Edit as HTML选项时,元素进入编辑模式,可以对元素的代码进行任意的修改。当然,这个修改也仅对当前的页面渲染生效,不会修改服务器的源代码,故而这个功能也是作为调试页面效果而使用。在这里插入图片描述
  • 查看元素的CSS属性:在元素的右边栏中的styles页面可以查看该元素的CSS属性,这个页面展示该元素原始定义的CSS属性以及从父级元素继承的CSS属性。从这个页面还可以查到该元素的某个CSS特性来自于那个CSS文件,使编码调试时修改代码变得非常方便。在这里插入图片描述
  • 在Styles页旁边,有一个Computed页面,这个页面展示该元素经过计算之后的所有CSS属性,即最后浏览器渲染页面时使用的属性。属性的计算由浏览器自动进行,是浏览器渲染页面的一个必不可少的过程。在这里插入图片描述
  • 修改元素的CSS属性:在元素的Styles页面,可以对元素的CSS属性进行修改,甚至删除原有、添加新属性。不过,这些修改,仅对当前浏览器的页面展示生效,不会修改CSS源代码。所以在这里进行CSS属性的修改一般用来调整和完善元素的渲染效果。
  • 给元素添加断点:在元素的右键菜单中选择断点选项(Break on…),选中之后,当元素被修改(通常是被JS代码修改)时,页面加载会暂停,然后可以查看该元素的属性。在这里插入图片描述
  • 元素断点添加之后,可以在右侧栏的DOM Breakpoints页面中看到,这个页面可以看到当前网页的所有元素断点在这里插入图片描述
  • 查看元素的监听事件:元素的右边栏的Event Listener页面,可以查看到该元素的所有监听事件。在开发中,尤其是维护其他人的代码时,会出现不了解元素对应的监听事件,这个时候,可以在这个页面中找到。这个页面不仅能看到对应的事件函数,还可以定位该函数所在的JS文件以及在该文件中的具体位置(行数),大大提高开发维护的效率。 在这里插入图片描述

控制台(Console):

  • 查看JS对象的及其属性在这里插入图片描述
  • 执行JS语句在这里插入图片描述
  • 查看控制台日志:当网页的JS代码中使用了console.log()函数时,该函数输出的日志信息会在控制台中显示。日志信息一般在开发调试时启用,而当正式上线后,一般会将该函数去掉

源代码(Source):

  • 查看文件:在源代码(Source)页面可以查看到当前网页的所有源文件。在左侧栏中可以看到源文件以树结构进行展示。在这里插入图片描述
  • 添加断点:在源代码左边有行号,点击对应行的行号,就好给改行添加上一个断点(再次点击可删除断点)。右键点击断点,在弹出的菜单中选择Edit breakpoint可以给该断的添加中断条件。在这里插入图片描述
  • 中断调试:添加断点后,当JS代码运行到断点时会中断(对于添加了中断条件的断点在符合条件时中断),此时可以将光标放在变量上查看变量的
  • 也可以在右边的侧栏上查看在这里插入图片描述
  • 在右侧变量上方,有继续运行、单步跳过等按钮,可以在当前断点后,逐行运行代码,或者直接让其继续运行。在这里插入图片描述

网络(Network): 在这里插入图片描述

  • 从左往右介绍:
  • 记录按钮 处于打开状态时会在此面板进行网络连接的信息记录,关闭后则不会记录。
  • 清除按钮 清除当前的网络连接记录信息。(点击一下就能清空)
  • 捕获截屏 记录页面加载过程中一些时间点的页面渲染情况,截图根据可视窗口截取,如下图所示。 在这里插入图片描述
  • 过滤器 能够自定义筛选条件,找到自己想要资源信息,如下图所示。 指定条件有哪些? ①domain:资源所在的域,即url中的域名部分。如 domain:api.github.com ②has-response-header:资源是否存在响应头,无论其值是什么。如 has-response-header:Access-Control-Allow-Origin ③is:当前时间点在执行的请求。当前可用值:running ④larger-than:显示大于指定值大小规格的资源。单位是字节(B),但是K(kB)和M(MB)也是可以的~ 如larger-than:150K ⑤method:使用何种HTTP请求方式。如 GET ⑥mime-type:也写作content-type,是资源类型的标识符。如 text/html ⑦scheme:协议规定。如 HTTPS ⑧set-cookie-name:服务器设置的cookies名称 ⑨set-cookie-value:服务器设置的cookies的值 ⑩set-cookie-domain:服务器设置的cookies的域 ⑪status-code:HTTP响应头的状态码在这里插入图片描述
  • 显示详细信息在这里插入图片描述在这里插入图片描述
  • 显示时间流能够根据时间,查看对应时间下 浏览器请求的资源信息在这里插入图片描述

NetWork名词解释:

  • Name/Pat:资源名称以及URL路径 (main.css)
  • Method:Http请求方法 (GET或者POST)
  • status/Text:Http状态码/文字解释 (200,ok)
  • Type :请求资源的MIME类型,MIME是Multipurpose Internet Mail Extensions (html,css,js等)
  • Initiator:解释请求是怎么发起的,有四种可能的值 ①Parser :请求是由页面的html解析时发送 ②Redirect:请求是由页面重定向发送 ③script :请求是由script脚本处理发送 ④other :请求是由其他过程发送的,比如页面里的Link链接点击
  • size/content:size是响应头部和响应体结合的大小,content是请求解码后的大小
  • NetWork中的Perview和Response: ①Perview的意思是(response preview):响应-预览 (响应资源进行了格式处理的内容) ②Response的意思是:(Raw response data):原始-响应-的数据(响应资源未进行格式处理的内容) ③这里所讲的的格式化是指:对后台传输过来的json、html、css等数据进行格式上的转换。

W3C标准

简介:

  • 万维网联盟(外语缩写:W3C)标准不是某一个标准,而是一系列标准的集合。网页主要由三部分组成:结构(Structure)、表现(Presentation)和行为(Behavior)
  • 应的标准也分三方面:结构化标准语言主要包括XHTML和XML,表现标准语言主要包括CSS,行为标准主要包括对象模型(如W3C DOM)、ECMAScript等。这些标准大部分由W3C起草和发布,也有一些是其他标准组织制订的标准,比如ECMA(European Computer Manufacturers Association)的ECMAScript标准。

VSCode及插件

安装使用步骤:

  • 安装VSCode
  • 安装中文语言包
  • 尝试安装ayu主题
  • 将一个目录作为项目目录
  • 创建一个新网页
  • 安装live server
  • 尝试通过live server来运行网页
  • 设置代码自动存储

VSCode中新建一个.html文件实现快速生成模板:

  • !+tab(感叹号+TAB键)

语言包插件:

  • Chinese (Simplified) Language Pack for Visual Studio Code
    中文语言包(安装后vs code 就是中文了)

css相关插件:

  • HTML to CSS autocompletion,外联样式提示插件
  • css-class-intellisense,内联样式提示插件

live server插件:

  • 安装之后可以打开一个简单的服务器。而且还会自动更新
  • 安装之后,打开项目文件夹,再在文件上点击右键就会出现一个Open with Live Server的选项,就会自动打开浏览器了。
  • 默认端口号是5500 ①http://127.0.0.1:5500/1.html
  • Live Server的其他配置,比如端口号,默认浏览器等等。

JS&CSS Minifler插件:

  • min后缀名表示经过压缩后。 在这里插入图片描述在这里插入图片描述在这里插入图片描述

less插件 Easy LESS:

  • less文件中的代码不能直接被浏览器解析渲染,需要在koala等软件中编译后,才能生成对应的文件和css代码,然后浏览器解析它。
  • 如果想在less文件中写css代码,通过正常保存(ctrl+s),自动生成浏览器可以解析的代码,那么通过Easy LESS这个插件可以实现,这样不仅省去了繁琐使用软件编译less文件的过程,每次正常保存,就像写css代码一样,实时观察效果。
  • Auto-compile LESS to CSS on save

.min.js和.js文件的区别

JavaScript中.min.js和.js文件的区别:

  • .js是JavaScript 源码文件, .min.js是压缩版的js文件。
  • 为什么要压缩为.min.js文件? ①减小体积 .min.js文件经过压缩,相对编译前的js文件体积较小,传输效率快。 ②防止窥视和窃取源代码 经过编码将变量和函数原命名改为毫无意义的命名,以防止他人窥视和窃取 js 源代码。
  • .js文件: ①优点: 可读性较好,易于debug和更改. ②缺点:体积较大,传输时间长
  • .min.js文件: ①优点:体积较小传输快, 源码防窃 ②缺点:可读性差
  • 如何生成.min.js文件? ①使用压缩工具:Google的在线版本 Javascript Closure Compiler
  • 压缩原理? ①压缩:删除 js 代码中所有注释、跳格符号、换行符号及无用的空格,从而压缩 JS 文件大小。 ②混淆:经过编码将变量和函数原命名改为毫无意义的命名,删除无用代码,内联函数,等价语句替换等(以防止他人窥视和窃取源码)

id,name,class属性

id,name,class属性总结:

  • Class 在程序中称“类”,同时在CSS中也书面语也叫“类”。在CSS样式中以小写的“点”及“.”来命名如:.css5{属性:属性值;} ,而在html页面里则以class="css5" 来选择调用,命名好的CSS又叫css选择器,而且class(类)在同一个html网页页面可以无数次的调用相同的class类
  • ID是表示着标签的身份,在JS脚本中会用到id,当JS要修改一个标签的属性时,JS会将id名作为该标签的唯一标识进行操作。也就是说ID只是页面元素的标识,供其他元素脚本等引用。假如你的页面里出现了两个ID那JS效果特性较出现逻辑错误不知道依据哪个ID来改变其标签属性。
  • 在CSS里的ID不一定为JS而设置的,但是同样ID在页面里也只能出现一次,并且是唯一性。虽然可能我们才学DIV+CSS爱好者在一个页面里同时调用相同的ID多次但是仍然没有出现页面混乱错误,但是我们为了W3C及各个标准我们也要遵循ID在一个页面里唯一性。以免出现浏览器兼容问题。
  • name主要是用于获取提交表单的某表单域信息, 作为可与服务器交互数据的HTML元素的服务器端的标示,比如input、select、textarea、框架元素(iframe、frame、 window的名字,用于在其他frame或window指定target )和button等,这些元素都与表单(框架元素作用于form的target)提交有关,浏览器会根据name来设定发送到服务器的request, 在表单的接收页面只接收有name的元素, 所以赋ID的元素通过表单是接收不到值的。 我们可以在服务器端根据其Name通过Request.Params取得元素提交的值。在form里面,如果不指定name,就不会发送到服务器端
  • 除去与表单相关的元素,只能赋id不能赋name。这些元素有body、li、a、table、tr、td、th、p、div、span、pre、dl、dt、dd、font、b等等

script,css标签放哪里

BS的标准模版:

	  <!DOCTYPE html>
<html>
  <head>
     <!--网页页面字符集-->
    <meta charset="utf-8">
 
    <!--让IE使用最新的渲染模式-->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
 
    <!--针对移动设备,网站显示宽度等于设备屏幕显示宽度,内容缩放比例为1:1-->
    <meta name="viewport" content="width=device-width, initial-scale=1">
 
    <!--将下面的 <meta> 标签加入到页面中,可以让部分国产浏览器默认采用高速模式渲染页面:-->
    <meta name="renderer" content="webkit">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
 
    <title>Bootstrap Basic Template</title>
    <!-- Bootstrap -->
    <link href="css/bootstrap.min.css" rel="stylesheet">

    <!--下面这一大块的注释是说:"为了让IE9以下的浏览器支持响应式和HTML5标签.需要引入下面两个JS文件"-->

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
 
    <!-- 英:jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <!--中:必须在JS文件引入之前引入JQ文件,这里src引用的是本地.线上建议使用CDN引用)
    <script src="js/jquery-2.1.3.min.js"></script>
 
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="js/bootstrap.min.js"></script>
  </body>
</html> 

css样式标签放哪里:

  • 浏览器会识别该文档为CSS,并行下载,不会停止对当前文档的加载,在加载html生成DOM tree的时候,就可以同时对DOMtree进行渲染,这样可以防止闪跳,白屏或者布局混乱
  • 至于link和style,还是放在head里的做法比较常见。link也是要下载CSS的啊,
  • 为毛不考虑下载CSS阻塞HTML解析的问题呢?其实,一般情况下,JS和CSS,放在head和放在body区别不大。
  • CSS的link放在body也是可以的,只是可能导致页面暂时没有样式。

script标签到底该放在哪里?

  • 加载js文件会停止对dom的创建,而且js加载完会立即执行,同时会阻塞后面资源的加载
  • 在HTML5中引入JS文件时 到底应该在head标签中还是body中: ①有的js是立即执行,有的js是调用执行。 <1>立即执行在网页上打开时就可以看到效果,而调用执行的,一般会在其它控件触发事件的时候调用。 ②对于调用执行的,我们最好放在head里,直接声明或者引用外部文件(head)。 ③对于即时执行的,我们在需要js执行的地方声明或者引用外部文件(body)。
  • 追求效率高的话: ①JS建议在body的尾部引入,(强调是自己编写的或者不是非初始化就要加载的); 原因:当页面依次序载入到script的时候,dom树的解析和渲染会暂停,在js载入执行完毕之前, 页面会保持后续内容不完整的状态。将script后置,可以避免这个情况,特别在脚本下载和执行耗时很长的时候会更明显 <1>PS:js执行顺序问题,script标签写在上边的先执行

总结:

  • JS 和 CSS 在页面中的位置,会影响其他资源(指 img 等非 js 和 css 资源)的加载顺序,有三个值得注意的点: ①JS 有可能会修改 DOM. 典型的,可能会有 document.write. 这意味着,在当前 JS 加载和执行完成前,后续所有资源的下载有可能是没必要的。 这是 JS 阻塞后续资源下载的根本原因。 ②JS 的执行有可能依赖最新样式。比如,可能会有 var width = $('#id').width(). 这意味着,JS 代码在执行前,浏览器必须保证在此 JS 之前的所有 css(无论外链还是内嵌)都已下载和解析完成。这是 CSS 阻塞后续 JS 执行的根本原因。 ③现代浏览器很聪明,会进行 prefetch 优化。性能是如此重要,现代浏览器在 竞争中,在 UI update 线程之外,还会开启另一个线程,对后续 JS 和 CSS 提前下载(注意,仅提前下载,并不执行)。有了prefetch 优化,这意味着,在不存在任何阻塞的情况下,理论上 JS 和 CSS 的下载时机都非常优先,和位置无关。

把js文件放在头部,怎么处理?

  • 当浏览器解析到script标签时,默认会先先下载js文件下载完了就执行,脚本的执行时同步和阻塞的,为了解决阻塞的问题,script标签新增了两个布尔属性,分别是defer(延迟)和async(异步)
<script src="home.js" defer></script>
<script src="home.js" async></script>
  • 当使用defer时,js和html并行下载,不会阻塞dom树的创建,当dom树创建完成时才会执行js
  • 当使用async时,js和html并行下载,当下载完会立即执行js,执行期间会阻塞html的解析 在这里插入图片描述

js与dom加载问题

dom加载问题:

$("#myButton").click(function(){
                //...
                alert("点击了!");
})
  • 如果放在body前onload事件外,由于dom未加载,是找不到“myButton”id的,因此无效
  • 如果放在body前onload事件内,在dom加载后才执行这段代码,可行
  • 如果放在放在body后面是可以读取到id的

如何让ajax方法一进页面就加载(不包括页面的图片):

  • 使用$(function())
$(function(){
	$.ajax({
		操作的代码
	});
})
  • 或者是ready()
$(document).ready(function(){
	$.ajax({
		操作的代码
	});
})

在js 加了 window.onload 和不加 window.onload 有什么区别:

  • window.onload方法执行的时间是页面内包括图片的所有元素加载完毕后执行
  • 不加的或就是加载到js脚本就执行

浮动与定位

脱标的元素的特性:

  • 只要是脱离了标准流,元素都是不区分行、块的,体现在任何元素都可以设置宽、高了。都有了收缩的性质,就是不设置宽度,就自动缩减为里面内容的宽度。
  • 脱离文档流常用属性:浮动的元素有贴边的性质绝对定位的元素可以自由定位

浮动float:

  • 浮动可以使块级元素并排显示,用于页面布局。
  • 注意: ①某个元素设置了浮动,则同级元素都需要设置浮动。 ②有高度的父盒子不用清除浮动,否则都需要清除浮动。

定位position:

  • 相对定位不脱标,仅设置position: relative 没有任何效果。相对定位是相对自己原来的位置进行移动,原位置保留,margin将作用在原位置上。相对定位的用途非常的小,就是微调元素的位置。
  • 绝对定位在实际应用中很少单独使用,通常会“子绝父相”给父盒子设置position: relative;(相对定位),这样子盒子会以父盒子作为参考。 ①绝对定位的盒子,不能以任何方式用margin 影响别的盒子父盒子的padding 不会影响绝对定位的子盒子。border可以影响子盒子。

浮动与定位区别:

  • 定位可设置水平与垂直距离,而浮动只可设置水平方向(不可设置距离)
  • 文字会环绕浮动的元素,而定位不会

注意:

  • 脱了文档流时由于变成行内块,父元素设置了一定宽度时,若每个子元素都不超过父元素宽度时,则众子元素水平排列,多出的部分换行。即跟行内元素一样
  • 不管有没有脱离文档流,父元素设置了一定宽度时若子元素宽度超过父元素宽度时则溢出。
  • 垂直方向一直都是超过时溢出
  • 溢出时可以通过设置overflow选择处理方式

CSS 中width、height中auto与100%

总结:

  • width、height使用固定值是一定会显示的,但是除非是小型项目或是特殊情况,最好不要使用固定值。不利于响应式开发,当从移动端看页面就会非常不美观。
  • 不设置width、height时默认为auto,当position不同时显示效果不同,浮动可能会导致其不显示,需要清除浮动。 ①width:auto表示宽度是可变动的,这个div的所有部分(content+margin+padding+border)相加为父元素的width大小。 ②height:auto表示高度可变动的,如果div设置了auto但是却没有显示有三种可能: 1、cotent里没有能将其height支撑的子元素 2、由于定位和浮动导致其不显示,清除浮动或修改定位
  • width、height强制将子元素充满父元素的content。 ①width:100%子元素的width值为父元素的width值,加margin时不改变子元素width值大小,而是溢出父元素。 ②height:100%不显示的原因可能为没有设置父元素的height,可以通过将父元素的height设为固定值或是将父元素及父元素的父元素设置height:100%显示。
  • auto与子元素有关,100%与父元素有关
  • CSS | width、height中auto与100%与固定值有什么不同

ECharts

ECharts简介:

  • ECharts,一个纯 Javascript 的图表库,可以流畅的运行在 PC 和移动设备上
  • ECharts,缩写来自 Enterprise Charts,商业级数据图表,是百度的一个开源的数据可视化工具,一个纯 Javascript 的图表库,能够在 PC 端和移动设备上流畅运行,兼容当前绝大部分浏览器(IE6/7/8/9/10/11,chrome,firefox,Safari等)。
  • 底层依赖轻量级的 Canvas 库 ZRender,ECharts 提供直观,生动,可交互,可高度个性化定制的数据可视化图表。创新的拖拽重计算、数据视图、值域漫游等特性大大增强了用户体验,赋予了用户对数据进行挖掘、整合的能力。
  • 链接:ECharts教程

ECharts 有哪些特点:

  • ECharts 属于开源软件,并且我们提供了非常炫酷的图形界面,特色是地图,另外还提供了柱状图、折线图、饼图、气泡图及四象限图等;
  • ECharts 使用简单,在官网中为我们封装了 JS,只要会引用就会得到完美的展示效果;
  • ECharts 种类多,ECharts 实现简单,各类图形都有;相应的模板,还有丰富的 API 及文档说明,非常详细;
  • ECharts 兼容性好,基于HTML5,有着良好的动画渲染效果。