前端性能整理笔记

网站性能优化

1、http请求方面,减少请求数量,请求体积,对应的做法是,对项目资源进行压缩,控制项目资源的dns解析在2到4个域名,提取公告的样式,公共的组件,雪碧图,缓存资源,

2、压缩资源,提取公共资源压缩,提取css ,js公共方法

3、不要缩放图片,使用雪碧图,使用字体图表(阿里矢量图库)

4、使用CDN,抛开无用的cookie

5、减少重绘重排,CSS属性读写分离,最好不要用js修改样式,dom 离线更新,渲染前指定,图片的大小

6、js代码层面的优化,减少对字符串的计算,合理使用闭包,首屏的js资源加载放在最底部

项目优化

1、v-for 遍历必须为 item 添加 key,且避免同时使用 v-if
2、v-if 和 v-show 区分使用场景

v-if是 真正 的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建;也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

v-show就简单得多, 不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 的 display 属性进行切换。

所以,v-if 适用于在运行时很少改变条件,不需要频繁切换条件的场景;v-show则适用于需要非常频繁切换条件的场景。

3、computed 和 watch 区分使用场景

computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值;

watch: 更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作

4、长列表性能优化

Vue 会通过 Object.defineProperty 对数据进行劫持,来实现视图响应数据的变化,然而有些时候我们的组件就是纯粹的数据展示,不会有任何改变,我们就不需要 Vue 来劫持我们的数据,在大量数据展示的情况下,这能够很明显的减少组件初始化的时间,那如何禁止 Vue 劫持我们的数据呢?可以通过 Object.freeze 方法来冻结一个对象,一旦被冻结的对象就再也不能被修改了。

5、图片资源懒加载:Vue 的 vue-lazyload 插件
6、路由懒加载
7、第三方插件的按需引入

react路由懒加载是loadable插件

web项目性能优化

1、压缩源码和图片
JavaScript文件源代码可以采用混淆压缩的方式,CSS文件源代码进行普通压缩,JPG图片可以根据具体质量来压缩为50%到70%,PNG可以使用一些开源压缩软件来压缩,比如24色变成8色、去掉一些PNG格式信息等。

2、选择合适的图片格式
如果图片颜色数较多就使用JPG格式,如果图片颜色数较少就使用PNG格式,如果能够通过服务器端判断浏览器支持WebP,那么就使用WebP格式和SVG格式。

3、合并静态资源
包括CSS、JavaScript和小图片,减少HTTP请求。有很大一部分用户访问会因为这一条而取得最大受益

4、开启服务器端的Gzip压缩
这对文本资源非常有效,对图片资源则没那么大的压缩比率。

5、使用CDN
或者一些公开库使用第三方提供的静态资源地址(比如jQuery、normalize.css)。一方面增加并发下载量,另一方面能够和其他网站共享缓存。

6、延长静态资源缓存时间
这样,频繁访问网站的访客就能够更快地访问。不过,这里要通过修改文件名的方式,确保在资源更新的时候,用户会拉取到最新的内容。

7、把CSS放在页面头部,把JavaScript放在页面底部
这样就不会阻塞页面渲染,让页面出现长时间的空白。

性能优化

  • 编码阶段
  1. 尽量减少data中的数据,data中的数据都会增加getter和setter,会收集对应的watcher
  2. v-if和v-for不能连用
  3. 如果需要使用v-for给每项元素绑定事件时使用事件代理
  4. SPA 页面采用keep-alive缓存组件
  5. 在更多的情况下,使用v-if替代v-show
  6. key保证唯一
  7. 使用路由懒加载、异步组件
  8. 防抖、节流
  9. 第三方模块按需导入
  10. 长列表滚动到可视区域动态加载
  11. 图片懒加载
  • SEO优化
  1. 预渲染
  2. 服务端渲染SSR
  • 打包优化
  1. 压缩代码
  2. Tree Shaking/Scope Hoisting
  3. 使用cdn加载第三方模块
  4. 多线程打包happypack----不常用
  5. splitChunks抽离公共文件
  6. sourceMap优化
  • 用户体验
  1. 骨架屏
  2. PWA—不常用
  3. 客户端缓存、服务端缓存

get与post 通讯的区别

1、Get 请求能缓存,Post 不能

2、Post 相对 Get 安全一点点,因为Get 请求都包含在 URL 里,且会被浏览器保存历史纪录,Post 不会,但是在抓包的情况下都是一样的。

3、Post 可以通过 request body来传输比 Get 更多的数据,Get 没有这个技术

4、URL有长度限制,会影响 Get 请求,但是这个长度限制是浏览器规定的,不是 RFC 规定的

5、Post 支持更多的编码类型且不对数据类型限制

webpack的原理和机制,怎么实现的

  1. 解析webpack配置参数,合并从shell传入和webpack.config.js文件里配置的参数,生产最后的配置结果。

  2. 注册所有配置的插件,好让插件监听webpack构建生命周期的事件节点,以做出对应的反应。

  3. 从配置的entry入口文件开始解析文件构建AST语法树,找出每个文件所依赖的文件,递归下去。

  4. 在解析文件递归的过程中根据文件类型和loader配置找出合适的loader用来对文件进行转换。

  5. 递归完后得到每个文件的最终结果,根据entry配置生成代码块chunk。

  6. 输出所有chunk到文件系统。

webpack

把项目当做一个整体,通过一个给定的主文件(如index.js),webpack将从这个文件开始找到项目的所有依赖文件,使用loader处理他们,最后打包为一个浏览器可识别的javascript文件

Webpack是一个模块打包工具,在webpack里面一切皆模块通过loader转换文件,通过plugin注入钩子,最后输出有多个模块组合成的文件。

Loaders

loader是webpack中最强大的一个特性。使用不同的loader,就可以实现不同的功能。

css-loader 实现css的模块化开发

less-loader less的编译

vue-loader vue的单文件组件

babel-loader es6转es5的功能

什么是loader, 什么是plugin, 两者的不同

概念:

  • loader:模块转换器。用于把模块原内容按照需求转换成新内容。通过使用不同的Loader,Webpack可以要把不同的文件都转成JS文件,比如CSS、ES6/7、JSX等
  • plugin:扩展插件。在 Webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情,一个插件是含有apply方法的一个对象,通过这个方法可以参与到整个webpack打包的各个流程

不同:

  • loader是使webpack拥有加载和解析非js文件的能力
  • plugin 可以扩展webpack的功能,使得webpack更加灵活。可以在构建的过程中通过Webpack的api改变输出的结果

loader是用来对模块的源代码进行转换,而plugin目的在于解决 loader 无法实现的其他事,因为plugin可以在任何阶段调用,能够跨Loader进一步加工Loader的输出


webpack 本质上是一个打包工具,它会根据代码的内容解析模块依赖,帮助我们把多个模块的代码打包:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HGkxHCTD-1602323021994)(file:///C:\Users\hp\AppData\Local\Temp\msohtmlclip1\01\clip_image002.gif)]

如上图,webpack 会把我们项目中使用到的多个代码模块(可以是不同文件类型),打包构建成项目运行仅需要的几个静态文件。webpack 有着十分丰富的配置项,提供了十分强大的扩展能力,可以在打包构建的过程中做很多事情。

浅拷贝和深拷贝的问题

  1. 深拷贝和浅拷贝是只针对Object和Array这样的复杂类型的

  2. 也就是说a和b指向了同一块内存,所以修改其中任意的值,另一个值都会随之变化,这就是浅拷贝

  3. 浅拷贝, ”Object.assign() 方法用于将所有可枚举的属性的值从一个或多个源对象复制到目标对象。它将返回目标对象

  4. 深拷贝,JSON.parse()和JSON.stringify()给了我们一个基本的解决办法。但是函数不能被正确处理

  5. 浅拷贝:

    a. 概念:浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。修改时原对象也会受到影响。

    b. 方法:

    • 利用 = 赋值操作符实现浅拷贝。
    • 数组的浅拷贝一般使用 slice、concat。
    • 数组浅拷贝 - 遍历 。
    • 对象浅拷贝 - Object.assign()。
    • 对象浅拷贝 - 扩展运算符

    深拷贝:

    a. 概念:深拷贝就是在拷贝数据的时候,将数据的所有引用结构都拷贝一份。简单的说就是,在内存中存在两个数据结构完全相同又相互独立的数据,将引用型类型进行复制,而不是只复制其引用关系。修改时原对象不再受到任何影响。

    b. 方法:

    • 利用 JSON 对象中的 parse 和 stringify。
  • 利用递归来实现每一层都重新创建对象并赋值。

    数组实现深拷贝:
    • (1)for循环实现数组的深拷贝

    • (2)concat 方法实现数组的深拷贝

    • (3)slice() 方法可从已有的数组中返回选定的元素。

    • (4)ES6扩展运算符实现数组的深拷贝

cookies,sessionStorage和localstorage区别

相同点:都存储在客户端

不同点:

​ 1.存储大小

​ · cookie数据大小不能超过4k。

​ · sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。

​ 2.有效时间

​ · localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;

​ · sessionStorage 数据在当前浏览器窗口关闭后自动删除。

​ · cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭

​ 3.数据与服务器之间的交互方式

​ · cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端

​ · sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。

watch

监听

watch函数的参数中,第一个是改变之前的值,第二个是改变之后的值, 这两个参数非常有用。

这里分别使用了 三种定义函数(或option)的方法。

如果要观察data下一个对象的属性,我们可以使用 ‘对象.属性’ 的方式, 注意: 一定要要引号。

如果改变了一个对象的属性,就必须使用 deep: true, 否则检测不到变化。

说说原型(prototype)、原型链和原型继承

一、原型 prototype__proto__

原型(prototype): 一个简单的对象,用于实现对象的 属性继承
  • 每个对象都有一个__proto__属性,并且指向它的prototype原型对象

  • 每个构造函数都有一个prototype原型对象

    • prototype原型对象里的constructor指向构造函数本身

img

有的同学可能会问prototype__proto__有什么用呢?

实例对象的__proto__指向构造函数的prototype,从而实现继承。

prototype对象相当于特定类型所有实例对象都可以访问的公共容器

原型链如下:

arr ---> Array.prototype ---> Object.prototype ---> null

这就是传说中的原型链,层层向上查找,最后还没有就返回undefined

原型链

当我们在访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去,找到Object.__proto__为止,找不到就返回undefined也就是我们平时所说的原型链的概念。

作用域与作用域链

  • 作用域: 执行上下文中还包含作用域链。作用域其实可理解为该上下文中声明的变量和声明的作用范围。可分为 块级作用域 和 函数作用域( 也可理解为:作用域就是一个独立的地盘,让变量不会外泄、暴露出去。也就是说作用域最大的用处就是隔离变量,不同作 用域下同名变量不会有冲突。)
  • 作用域链:作用域链可以理解为一组对象列表,包含 父级和自身的变量对象,因此我们便能通过作用域链访问到父级里声明的变量或者函数。我们知道,我们可以在执行上下文中访问到父级甚至全局的变量,这便是作用域链的功劳。

闭包

概念:定义在函数内部的函数。里面的函数可以访问 外面函数的变量,外面的变量的是这个内部函数的一 部分

常见的闭包写法就是简单的函数套函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用域链,将函数内部的变量和方法传递到外部,延续变量的生命。使用闭包可以减少全局环境的污染,也可用延续变量的生命。

作用:1.使用闭包可以访问函数中的变量。2.可以使 变量长期保存在内存中,生命周期比较长。

缺点:闭包不能滥用,否则会导致内存泄露,影响网 页的性能。

应用场景:1.函数作为参数传递。2.函数作为返回值

闭包的适用场景

闭包的适用场景非常广泛,首先从闭包的优点出发就是:

防抖节流

减少全局环境的污染生成独立的运行环境

模块化就是利用这个特点对不同的模块都有自己独立的运行环境,不会和全局冲突,模块和模块之间通过抛出的接口进行依赖使用

以及像我们常用的jquery类库(避免和全局冲突使用闭包实现自己独立的环境)

可以通过返回其他函数的方式突破作用域链

可以利用这个功能做一些值的缓存工作,例如常见的设计模式(单例模式),以及现在比较火的框架vue中的计算属性

其实当遇到以下场景的时候都可以使用闭包

1.维护函数内的变量安全,避免全局变量的污染。

2.维持一个变量不被回收。

3.封装模块

闭包的缺点

由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大。所以在闭包不用之后,将不使用的局部变量删除,使其被回收。在IE中可能导致内存泄露,即无法回收驻留在内存中的元素,这时候需要手动释放。

跨域

1、 通过jsonp跨域
2、 document.domain + iframe跨域

module.exports={
    devServer:{
        open:true,
        proxy:{
            "/api":{
                target:"http://localhost:7001/",
                ws:true,
                changeOrigin:true,
                pathRewrite:{
                    "^/api":""
                }
            }
        }
    }
}

防抖和节流

防抖(debounce)

所谓防抖,就是指触发事件后在n秒内函数只能执行一次,如果在n秒内又触发了事件,则重新计算函数执行时间。
防抖函数分为非立即执行版和立即执行版.

防抖 (debounce): 将多次高频操作优化为只在最后一次执行,通常使用的场景是:用户输入,只需再输入完成后做一次输入校验即可。

原理:将若干函数调用合成为一次,并在给定时间过去之后,或者连续事件完全触发完成之后,调用一次(仅仅只会调用一次!!!!!!!!!!)。

举个栗子:滚动scroll事件,不停滑动滚轮会连续触发多次滚动事件,从而调用绑定的回调函数,我们希望当我们停止滚动的时,才触发一次回调,这时可以使用函数防抖。

节流(throttle)

所谓节流,就是指连续触发事件但是在n秒中只执行-次函数。节流会稀释函数的执行频率。
对于节流,一般有两种方式可以实现,分别是时间戳版和定时器版。

节流(throttle): 每隔一段时间后执行一次,也就是降低频率,将高频操作优化成低频操作,通常使用场景: 滚动条事件 或者 resize 事件,通常每隔 100~500 ms执行一次即可。

原理:当达到了一定的时间间隔就会执行一次;可以理解为是缩减执行频率

回流和重绘

什么是回流(重排)

当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow)。每个页面至少需要一次回流,就是在页面第一次加载的时候,这时候是一定会发生回流的,因为要构建render tree。在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程成为重绘。

什么是重绘

当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。

区别:

他们的区别很大:
回流必将引起重绘,而重绘不一定会引起回流。比如:只有颜色改变的时候就只会发生重绘而不会引起回流
当页面布局和几何属性改变时就需要回流
比如:添加或者删除可见的DOM元素,元素位置改变,元素尺寸改变——边距、填充、边框、宽度和高度,内容改变

宏任务和微任务

img

宏任务:

  • setTimeout

  • setInterval

微任务:Promise.then()

http缓存

https://www.jianshu.com/p/227cee9c8d15

https://blog.csdn.net/jutal_ljt/article/details/80021545

一、什么是HTTP缓存 ?

http缓存指的是: 当客户端向服务器请求资源时,会先抵达浏览器缓存,如果浏览器有“要请求资源”的副本,就可以直接从浏览器缓存中提取而不是从原始服务器中提取这个资源。

强制缓存,协商缓存

1.1、强制缓存
强制缓存在缓存数据未失效的情况下(即Cache-Control的max-age没有过期或者Expires的缓存时间没有过期),那么就会直接使用浏览器的缓存数据,不会再向服务器发送任何请求。强制缓存生效时,http状态码为200。这种方式页面的加载速度是最快的,性能也是很好的,但是在这期间,如果服务器端的资源修改了,页面上是拿不到的,因为它不会再向服务器发请求了。这种情况就是我们在开发种经常遇到的,比如你修改了页面上的某个样式,在页面上刷新了但没有生效,因为走的是强缓存,所以Ctrl + F5一顿操作之后就好了。 跟强制缓存相关的header头属性有(Pragma/Cache-Control/Expires)

1.2、协商缓存
当第一次请求时服务器返回的响应头中没有Cache-Control和Expires或者Cache-Control和Expires过期还或者它的属性设置为no-cache时(即不走强缓存),那么浏览器第二次请求时就会与服务器进行协商,与服务器端对比判断资源是否进行了修改更新。如果服务器端的资源没有修改,那么就会返回304状态码,告诉浏览器可以使用缓存中的数据,这样就减少了服务器的数据传输压力。如果数据有更新就会返回200状态码,服务器就会返回更新后的资源并且将缓存信息一起返回。跟协商缓存相关的header头属性有(ETag/If-Not-Match 、Last-Modified/If-Modified-Since)请求头和响应头需要成对出现

http状态码

2开头的http状态码

表示请求成功

**200 成功处理了请求,一般情况下都是返回此状态码; **
201 请求成功并且服务器创建了新的资源。
202 接受请求但没创建资源;
203 返回另一资源的请求;
204 服务器成功处理了请求,但没有返回任何内容;
205 服务器成功处理了请求,但没有返回任何内容;
206 处理部分请求;

3xx (重定向)

重定向代码,也是常见的代码

300 (多种选择) 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302 表示重定向(临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
303 (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
304 浏览器缓存的资源,使用缓存(未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
305 (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。
307 (临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

4开头的http状态码表示请求出错

400 服务器不理解请求的语法。
**401 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。 **
403 服务器拒绝请求。没有权限
404 服务器找不到请求的网页。 表示访问内容不存在
405 禁用请求中指定的方法。
406 无法使用请求的内容特性响应请求的网页。
407 此状态代码与 401类似,但指定请求者应当授权使用代理。
408 服务器等候请求时发生超时。
409 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。
410 如果请求的资源已永久删除,服务器就会返回此响应。
411 服务器不接受不含有效内容长度标头字段的请求。
412 服务器未满足请求者在请求中设置的其中一个前提条件。
413 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
414 请求的 URI(通常为网址)过长,服务器无法处理。
415 请求的格式不受请求页面的支持。
416 如果页面无法提供请求的范围,则服务器会返回此状态代码。
417 服务器未满足”期望”请求标头字段的要求。

5开头状态码并不常见,但是我们应该知道

**500 (服务器内部错误) 服务器遇到错误,无法完成请求。 **
501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

mixins

混入 (mixins): 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。

怎么用?
  • 定义一个混入对象

img

把混入对象混入到当前的组件中

img

mixins与vuex的区别

经过上面的例子之后,他们之间的区别应该很明显了哈~

  • vuex:用来做状态管理的,里面定义的变量在每个组件中均可以使用和修改,在任一组件中修改此变量的值之后,其他组件中此变量的值也会随之修改。
  • Mixins:可以定义共用的变量,在每个组件中使用,引入组件中之后,各个变量是相互独立的,值的修改在组件中不会相互影响。

RBAC:

基于策略的权限控制

角色访问权限

RBAC是Role Based Access Control的英文缩写,意思是基于角色访问控制。

RBAC0
RBAC0是RBAC96模型家族中的基础,也称作核心部分,RBAC1、RBAC2和RBAC3是在此基础之上发展演变而来。

可以理解它是由四个部分组成:用户、角色、会话、权限
这就导致了这种分配关系是多对多:用户对应多个角色、角色对应多个权限。
用户与会话一对一,会话与角色一对多

RBAC1
RBAC1是在RBAC0模型基础之上增加了角色分层概念和角色之间的继承关系。

角色分层指的是同一个角色可以用不同等级,不同等级又对应着不同的权限;
角色继承关系指的是子角色可以对父角色的权限进行继承,但是子角色的权限一定小于父角色。

RBAC2
RBAC2是在RBAC0模型基础之上增加了角色约束,主要约束哪些操作是可进行,哪些是不可进行。

主要约束有以下三个方面:

角色互斥约束:是指在系统运行中,只可以同时激活运行时互斥角色集合中的一个角色;
角色基数约束:是限制某一个用户最多被分配或者激活的角色数目,或者限制某一个角色最多被赋予的权限数目;
先决条件角色约束:是指某些用户只有在己经拥有特定角色的前提下,才能被分配到某种角色,或者某种角色只有在已经被分配到特定权限的前提下,才能被赋予某些权限
RBAC3
RBAC3则是集聚了RBAC1和RBAC2的全部特点,同时将角色继承关系和约束条件关系两者都融入到模型中。

axios是什么?

请求后台资源的模块

服务端渲染 SSR or 预渲染

服务端渲染是指 Vue 在客户端将标签渲染成的整个 html 片段的工作在服务端完成,服务端形成的 html 片段直接返回给客户端这个过程就叫做服务端渲染。
1.服务端渲染的优点:
更好的 SEO: 因为 SPA 页面的内容是通过 Ajax 获取,而搜索引擎爬取工具并不会等待 Ajax 异步完成后再抓取页面内容,所以在 SPA 中是抓取不到页面通过 Ajax 获取到的内容;而 SSR 是直接由服务端返回已经渲染好的页面(数据已经包含在页面中),所以搜索引擎爬取工具可以抓取渲染好的页面;
更快的内容到达时间(首屏加载更快): SPA 会等待所有 Vue 编译后的 js 文件都下载完成后,才开始进行页面的渲染,文件下载等需要一定的时间等,所以首屏渲染需要一定的时间;SSR 直接由服务端渲染好页面直接返回显示,无需等待下载 js 文件及再去渲染等,所以 SSR 有更快的内容到达时间;
2.服务端渲染的缺点:
更多的开发条件限制: 例如服务端渲染只支持 beforCreate 和 created 两个钩子函数,这会导致一些外部扩展库需要特殊处理,才能在服务端渲染应用程序中运行;并且与可以部署在任何静态文件服务器上的完全静态单页面应用程序 SPA 不同,服务端渲染应用程序,需要处于 Node.js server 运行环境;
更多的服务器负载:在 Node.js 中渲染完整的应用程序,显然会比仅仅提供静态文件的 server 更加大量占用CPU 资源,因此如果你预料在高流量环境下使用,请准备相应的服务器负载,并明智地采用缓存策略。
如果你的项目的 SEO 和 首屏渲染是评价项目的关键指标,那么你的项目就需要服务端渲染来帮助你实现最佳的初始加载性能和 SEO。如果你的 Vue 项目只需改善少数营销页面(例如 /products, /about, /contact 等)的 SEO,那么你可能需要预渲染,在构建时 (build time) 简单地生成针对特定路由的静态 HTML 文件。优点是设置预渲染更简单,并可以将你的前端作为一个完全静态的站点,具体你可以使用 prerender-spa-plugin 就可以轻松地添加预渲染 。

优点:

  • SSR有着更好的SEO
  • 首屏加载速度更快

缺点:

  • 开发条件会受到限制
  • 服务器端渲染只支持beforeCreate和created两个钩子,当我们需要一些外部扩展库时需要特殊处理,服务端渲染应用程序也需要处于Node.js的运行环境。
  • 服务器会有更大的负载需求。

什么叫优雅降级和渐进增强?

优雅降级:Web站点在所有新式浏览器中都能正常工作,如果用户使用的是老式浏览器,则代码会针对旧版本的IE进行降级处理了,使之在旧式浏览器上以某种形式降级体验却不至于完全不能用。
如:border-shadow

渐进增强:从被所有浏览器支持的基本功能开始,逐步地添加那些只有新版本浏览器才支持的功能,向页面增加不影响基础浏览器的额外样式和功能的。当浏览器支持时,它们会自动地呈现出来并发挥作用。
如:默认使用flash上传,但如果浏览器支持 HTML5 的文件上传功能,则使用HTML5实现更好的体验;

常见的浏览器兼容性问题:

1、不同浏览器的标签默认的外补丁( margin )和内补丁(padding)不同
解决方案: css 里增加通配符 * { margin: 0; padding: 0; }

2、IE6双边距问题;在 IE6中设置了float , 同时又设置margin , 就会出现边距问题
解决方案:设置display:inline;

3、当标签的高度设置小于10px,在IE6、IE7中会超出自己设置的高度
解决方案:超出高度的标签设置overflow:hidden,或者设置line-height的值小于你的设置高度

4、图片默认有间距
解决方案:使用float 为img 布局

5、IE9一下浏览器不能使用opacity
解决方案:
opacity: 0.5;filter: alpha(opacity = 50);filter: progid:DXImageTransform.Microsoft.Alpha(style = 0, opacity = 50);

6、边距重叠问题;当相邻两个元素都设置了margin 边距时,margin 将取最大值,舍弃最小值;
解决方案:为了不让边重叠,可以给子元素增加一个父级元素,并设置父级元素为overflow:hidden;

7、cursor:hand 显示手型在safari 上不支持
解决方案:统一使用 cursor:pointer

8、两个块级元素,父元素设置了overflow:auto;子元素设置了position:relative ;且高度大于父元素,在IE6、IE7会被隐藏而不是溢出;
解决方案:父级元素设置position:relative

懒加载的原理及实现

1.懒加载概念

对于页面有很多静态资源的情况下(比如网商购物页面),为了节省用户流量和提高页面性能,可以在用户浏览到当前资源的时候,再对资源进行请求和加载。

2.懒加载实现原理
2.1监听onscroll事件判断资源位置

首先为所有懒加载的静态资源添加自定义属性字段,比如如果是图片,可以指定data-src为真实的图片地址,src指向loading的图片。
然后当资源进入视口的时候,将src属性值替换成data-src的值。
可以使用元素的getBoundingRect().top判断是否在视口内,也可以使用元素距离文档顶部的距离offsetTop和scrollTop是否小于视口高度来判断:

移动端的 click 有300 ms的延时原因:

在移动端触发时间会按照 touchstart,touchmove,touchend,click 顺序触发;触发touchend,click之间会有200-400不等的时间延时(因为移动端需要判断用户是不是想要进行双击);
fastclick 和 zepto 的tap 事件 都可以解决 300 ms延时;
fastclick 原理:是在检测到touchend事件的时候,会通过DOM自定义事件立即出发模拟一个click事件,并把浏览器在300ms之后的click事件阻止掉。
tap 原理:在touchstart 时会记录一个值x1,y1,在touchend时会记录x2,y2,通过对比着几个值,判断用户是否是点击事件,而不是滑动事件,然后直接触发事件;
注意:fastclick 在ios 上会影响元素自动触发,比如 直接click();会拦截第一次,需要执行两次click();才会触发;安卓上不需要;

chrome–浏览器调试工具详解

面板

1.定位小箭头按钮(左边第一个):
选中Elements面板,并启动该按钮,可以在页面中定位相应元素的源代码位置,或者选择源代码位置可定位到页面相应的元素。
2.手机-PC视图切换按钮(左边第二个):
启动该按钮,网页可以在pc网址网页和手机网址网页之间进行转换。由于在爬虫过程中,爬取手机网址网页相对来说更容易,所以可以通过该按钮将网页切换至移动网页实现更快速爬取操作。(例如新浪微博)
3.Elements面板
该面板显示了渲染完毕后的全部HTML源代码,在使用selenium爬取网页时可通过这些源代码找到各标签的位置,属性等特征。更重要的是,双击html源码或者右侧的css,可以更改网页外观,即可以对静态网页进行调试。
4.Console面板
该面板用来显示网页加载过程中的日志信息,包括打印,警告,错误及其他可显示的信息等。同时它也是一个js交互控制台。
.Sources面板
该面板以站点为分组,存放着请求下来的所有资源(html,css,jpg,gif,js等)。正是因为该面板存放了所有的资源,因此在调试js时,目标代码都是在此处寻找的。
该面板也提供了调试按钮工具。
6.Network面板
Network面板记录了网络请求的详细信息,包括请求头,响应头,表单数据,参数信息等等,只要是做爬虫的这个面板必须要了解。

network

红色圆圈内代表的是请求的不同类型的数据,其中XHR表示ajax请求,即异步请求,在爬虫中最重要的是分析该项。Doc表示的是html文档类型。其他几个不是很重要不详细讲解。
若要保留请求记录,勾选上preserve log选项。

XSS攻击

1.XSS攻击:指的是跨脚本攻击,指的是攻击者在网页中嵌套,恶意脚本程序,当用户打开网页时,程序开始在浏览器上启动,盗取用户的cooks,从而盗取密码等信息,下载执行木马程序。

解决方法:XSS之所以会发生,是因为用户输入的数据变成了代码。因此,我们需要对用户输入的数据进行HTML转义处理,将其中的“尖括号”、“单引号”、“引号” 之类的特殊字符进行转义编码。

前端面试:区分XSS和CSRF

xss:跨站点攻击。xss攻击的主要目的是想办法获取目标攻击网站的cookie,因为有了cookie相当于有了session,有了这些信息就可以在任意能接进互联网的PC登陆该网站,并以其他人的身份登陆做破坏。预防措施防止下发界面显示html标签,把</>等符号转义。

csrf:跨站点伪装请求。csrf攻击的主要目的是让用户在不知情的情况下攻击自己已登录的一个系统,类似于钓鱼。如用户当前已经登陆了邮箱或bbs,同时用户又在使用另外一个,已经被你控制的网站,我们姑且叫它钓鱼网站。这个网站上面可能因为某个图片吸引你,你去点击一下,此时可能就会触发一个js的点击事件,构造一个bbs发帖的请求,去往你的bbs发帖,由于当前你的浏览器状态已经是登陆状态,所以session登陆cookie信息都会跟正常的请求一样,纯天然的利用当前的登陆状态,让用户在不知情的情况下,帮你发帖或干其他事情。预防措施,请求加入随机数,让钓鱼网站无法正常伪造请求。

new 具体干了什么事创建出来了对象

new 一个构造函数,生成一个对象–总体发生了四件事
1:在内存中生成一个空对象;
2:空对象的__proto__被构造函数prototype赋值;
3:运行构造函数,同时通过call,apply改变构造函数内部this指向;
4:检查构造函数运行的返回值,如果返回的是对象—会把第一步生成的空对象扔掉,
如果返回的是基本数据类型,会无视掉,并把第一步生成的对象给返回;

输入完网址按下回车,到看到网页这个过程中发生了什么?

1.域名解析

2.发起TCP3次握手

3.建立TCP连接后发起http请求

4.服务器端响应http请求,浏览器得到HTML代码

5.浏览器解析HTML代码,并请求HTML代码中的资源

6.浏览器对页面进行渲染呈现给用户

delete接口 axios的时候传参有问题

rf攻击的主要目的是让用户在不知情的情况下攻击自己已登录的一个系统,类似于钓鱼。如用户当前已经登陆了邮箱或bbs,同时用户又在使用另外一个,已经被你控制的网站,我们姑且叫它钓鱼网站。这个网站上面可能因为某个图片吸引你,你去点击一下,此时可能就会触发一个js的点击事件,构造一个bbs发帖的请求,去往你的bbs发帖,由于当前你的浏览器状态已经是登陆状态,所以session登陆cookie信息都会跟正常的请求一样,纯天然的利用当前的登陆状态,让用户在不知情的情况下,帮你发帖或干其他事情。预防措施,请求加入随机数,让钓鱼网站无法正常伪造请求。

new 具体干了什么事创建出来了对象

new 一个构造函数,生成一个对象–总体发生了四件事
1:在内存中生成一个空对象;
2:空对象的__proto__被构造函数prototype赋值;
3:运行构造函数,同时通过call,apply改变构造函数内部this指向;
4:检查构造函数运行的返回值,如果返回的是对象—会把第一步生成的空对象扔掉,
如果返回的是基本数据类型,会无视掉,并把第一步生成的对象给返回;

输入完网址按下回车,到看到网页这个过程中发生了什么?

1.域名解析

2.发起TCP3次握手

3.建立TCP连接后发起http请求

4.服务器端响应http请求,浏览器得到HTML代码

5.浏览器解析HTML代码,并请求HTML代码中的资源

6.浏览器对页面进行渲染呈现给用户

delete接口 axios的时候传参有问题

写项目过程中,测试delete的一个接口,有的接口能正常传参,有的接口却不行,后来看了下delete的源码 ,发现 delete 和 post 、put 的参数不一样。post、put都有三个参数,url、data和config,而delete只有两个参数,第一个是url,第二个是config,post 和 put 第二个参数是data,所以可以直接在第二个参数的位置写上数据,后台可以访问到,而delete第二个参数是 config ,所以要通过 config 里面的 data 来传参,如果不写,后台没解析的话,就接收不到。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值