【无标题】

 line-height:1 ,相当于line-height:100%,会根据该元素本身的字体大小设置行高,比如字体大小是15px,行高就是15px。

图片渲染下方有一条白线是什么原因造成的

图片渲染的时候会有个参考线 参考线的空隙就是这个白线  fontsize设置为0 参考线会重合在一起 把图片设置为块元素 就不会按照行内元素的形式排列了

h5的特性

移动端开发  语义化的标签 视频 音频标签 本地存储 

css3 

新增的一些选择器  :nth-child :not() 阴影 box-shadow backgroundsize transform 旋转 缩放 平移 rotate 旋转 scale 缩放 translate 平移 性能更好 开启硬件 加速 更加平滑 transtion animation 执行时间durating 延时时间 delay border-radious 圆角边框 fontsize fontfamily lineheight min-height

BFC

规定了元素如何对其内容进行定位以及和其他元素的相互作用 盒模型的一种css渲染方式外边距合并和float覆盖都是促发了bfc

http请求方法

options

trace激发一个远程 应用层的请求消息回路

connect把请求连接转换到透明的tcp或者iptongdai  

http和https

http是超文本传输协议,规定了浏览器和服务器的通信规则。http的连接时无状态的,默认端口号为80,https是基于http和ssl加密协议,存在于不同于http的端口添加了一个加密层,体哦概念股了身份验证和加密通讯的方法,https需要申请证书

http网站 rsa加密麻省理工 私钥加密数据 公钥加密签名

https加密过程

使用的是加密算法 非对称算法和对称算法 

DNS

OK,好,要讲明白这个问题。我们要先把域名的结构讲清楚! www.tmall.com对应的真正的域名为www.tmall.com.。末尾的.称为根域名,因为每个域名都有根域名,因此我们通常省略。

根域名的下一级,叫做"顶级域名"(top-level domain,缩写为TLD),比如.com、.net

再下一级叫做"次级域名"(second-level domain,缩写为SLD),比如www.tmall.com里面的.tmall,这一级域名是用户可以注册的;

再下一级是主机名(host),比如www.tmall.com里面的www,又称为"三级域名",这是用户在自己的域里面为服务器分配的名称,是用户可以任意分配的。

那么解析流程就是分级查询

递归查询

dns是域名服务器,它是域名和ip地址之间相互映射的分布式的数据库。

完整版dns解析过程  我们手动输入url,先去浏览器的dns缓存里头查询,dns缓存中没有,会先调用浏览器的gethostbyname这个函数,这个函数会向DNS服务器发UDP请求,gethostbyname函数在进行DNS解析之前首先检查域名是否在本地 Hosts 里,如果没找到再去DNS服务器上查,接收结果,然后将结果给返回给浏览器。

TCP UDP

DNS有两种2种类型的DNS服务器,一个叫主DNS服务器,一个叫辅助DNS服务器。主DNS服务器从自己本机的数据文件中读取数据,而辅助DNS服务器则从区的主DNS服务器中读取数据信息。当一个辅助DNS服务器启动时,它需要与主DNS服务器通信,并加载数据信息,这就叫做区传送( 这种情况下,使用TCP协议。

UDP快啊!UDP的DNS协议只要一个请求、一个应答就好 udp协议传送的字节不能超过521,区域复制中传递的数据没有超过521字节。

因为TCP协议可靠性好啊!辅助dns服务器要从主DNS上复制内容,需要保证数据的安全和可靠,而且数据可能不止521字节

tcp报文包括 ack syn fin 标志为1为打开 标志为0为关闭

syn是同步通信 同步通信后客户端和服务端就可以进行通信了

为什么需要seq序号 因为客户端可能会发送多个seq序号  服务器有依据知道哪些时累赘信息

三次握手

客户端发送tcp报文的时候会把syn打开表示想要进行同步通信,并且初始化自己的一个seq报文随机生成的,发送给服务端,服务端收到后,会把syn和ack报文都打开表示确认同步 ack时确认 syn是同步的意思 服务端也会初始化自己的序列号 并且对客户端的序号+1进行一个确认 

最后一次握手 服务端需要知道自己发送的确认同步的信息有没有被接收 ,客户端会把tcp报文的ack开启 序号会用对方的确认号+1

为什么需要三次握手

来知道那些来连接和响应是应该废弃的

为什么是三次握手

避免重复链接 客户端可能会连续发送多次请求。如果只设计成两次握手的情况,服务端只能一直接收请求,然后返回请求信息,也不知道客户端是否请求成功。这些过期请求的话就会造成网络连接的混乱。

所以设计成三次握手的情况,客户端在接收到服务端返回消息之后,就会知道这个连接是历史连接,所以会发送报文给服务端,告诉服务端。

4次挥手

客户端和服务端都能主动发起关闭连接

如果由客户端发起关闭连接的化 客户端会把服务端的确认应答号+1作为自己的序列号  确认号为服务端的序列号 并把tcp报文的fin finish完成的意思 和ack打开发送给服务端 服务端接收到后 会把客户端的确认应答号加1作为自己的序列号 把客户端的序列号作为自己的应答号 发送 把tcp报文的ack打开 传给客户端表示确认 客户端未必关闭连接了 因为服务端可能还有数据需要发送 服务端会发送一个 包含ack和fin的报文 序列号和确认号不变 发给客户端 表示确认关闭 客户端接收到后会把对方的确认号+1作为自己的序列号 序列号为自己的确认号  把tcp报文的ack打开发送给服务端关闭表示确认

浏览器输入页面到页面渲染发生了什么

我们在浏览器中输入url,会根据域名交给dns去解析找到真实的ip地址,建立tcp连接,向IP地址发送http请求,服务端交给后台去处理,把结果返回给浏览器,浏览器堆数据进行解析,建立相应的dom结构渲染页面。

http和tcp的区别

http对应应用层是超文本传输协议。。。基于tcp协议的 识别数据的 tcp对应传输层 规定了如何传输数据的

tcp

tcp在不可靠的ip协议上加了个可靠的传输层

tcp是面向连接的协议 基于运输链接来传送tcp报文字段 tcp运输连接的建立和释放是每一次面向连接的通信中必不可少的过程,tcp运输连接主要有三个阶段 建立tcp连接 数据传输 释放tcp连接 

建立连接是3次握手 释放连接是4次挥手

tcp的可靠性是怎么实现的

根据序列号来进行双方的互相确认  如果超时或者丢包的情况会进行重新传送,发送包到接收包是有一个时间的,超过了这个时间会重新传输  规定了最大消息长度 

tcp的滑动窗口

可以通过窗口大小来达到双方都支持传输的最大传输大小

为了通信的效率

主机a要向主机b发送序号从1开始到100 的100个包,他会将这100个包打包成一个数据端 一同发送给主机b 主机b确认应答会把最后一个也就是最大的序号包+1返回给主机a 主机a就知道了他确认接收的信息  如果直接收了1-40 主机b会传输一个序列号41作为确认应答 并传输一个窗口大小40来表示确认我接受到了40个包 

一个 TCP 连接可以对应几个 HTTP 请求

浏览器与服务器建立一个TCP链接之后,会不会在完成一个HTTP请求后立马断开?

主要是根据connection属性设置的

  • HTTP/1.0的时候是会的,需要手动设置Connection: keep-alive
  • HTTP/1.1的时候Connection默认为keep-alive 。

一个TCP链接可以对应多个HTTP请求,只要这个TCP链接没有断开,就可以发送HTTP请求。

http请求的并发性是如何体现的

览器最多允许对同一个域名Host建立6个TCP连接

补充关于HTTPS

如果图片都是HTTPS的连接,并且在同一域名下,浏览器会先和服务器协商使用HTTP2Multiplexing 某特扑来新功能进行多路传输,不过未必所有的挂在这个域名下的资源都会使用同一个TCP连接。如果用不了HTTPS或者HTTP2(HTTP2是在HTTPS上实现的),那么浏览器会就在同一个host建立多个TCP连接,每一个TCP连接进行顺序请求资源。

http请求分为三个部分 请求行 请求头和消息主体

请求行 GET /chatware/chatroom.php HTTP/1.1
post提交的数据一般放在消息主体内 不限制提交的数据类型但是发送的http请求要支持数据的格式

但是服务器要根据请求头的contenttype的树形来解析数据 

  1. application/x-www-form-urlencoded 原生表单 enctype 音ktype
  2. application/json 以json的格式
  3. multipart/form-data一般用于上传文件 毛体part

  4. text/xml  使用htto xml

http2

t头信息和数据体都是二进制形式的 

多路复用 客户端和服务端只会建立一个连接,当页面有多个并发请求时,浏览器会把它分解成互不依赖的帧,在连接中交错发送,服务端拿到这些帧后会把他们重新组装起来,返回数据给浏览器,不在依赖多个连接,没有了并发的限制,

HTTP头部

通用头部 cache-control 请求和响应应该遵循的缓存机制 no-cache 请求和响应不能缓存,

no-store用于防止重要的信息被发布 Public 可以被任何缓存区缓存 Private只能被单个用户缓存 max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应; min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应; max-stale指示客户机可以接收超出超时期间的响应    

data头域名 消息发送的事件 Pragma 实现特定的指令 

请求响应都包含的 Connection表示连接状态 close关闭 keepalive 保持连接

请求头部 method 请求方法  request-url 请求的url  http-version 当前支持的http版本

accept 客户端支持的内容类型 accept-encoding支持的编码格式 content-length 内容的长度

content-type 定义网络文件的类型和网页的编码 content-length内容的长度 host 要请求的域名

use-agent 发出请求的用户信息

响应 expries 文件的有效时间

缓存

前端缓存一般分为 http缓存和浏览器缓存

http缓存分为强缓存 协商缓存 一般缓存的是get请求的资源

浏览器第一次向服务器发起请求,服务器把该资源返回给浏览器,并在返回的响应头中设置cache-control 的max-age 最大有效期 浏览器第二次向服务器发起请求的时候,会检查max-age有没有过期 如果过期就直接使用本地缓存,直接返回200

强缓存的缺点 

他只会在本地拿取资源,不走服务器,如果服务器上的资源修改了,拿的也是修改前的 他只会等有效期过了才会重新请求, memory cache是内存中的缓存 disk cache是硬盘中的缓存  先走内存中的缓存 没有才走硬盘中的缓存 js文件和图片存在内存缓存中,css文件存在硬盘缓存中

我们修改了页面上的某个样式,但是并没有生效,因为走的是强缓存

刷新强缓存

我们按一下ctrl+f5强制刷新 或者把浏览器控制台的disable cache勾上 让他不走缓存

更新我们的js文件 但是我们本地更新了 浏览器使用的还是之前的js文件 可以在js文件后手动加一个版本号  这样浏览器就会更新 但是这样还有一个不好的地方就是所有的静态文件都会更新 解决方法就是让url的修改与文件内容相关联即只有文件内容变化时,才会导致相应的url的变更 这个自己其实没有实现过,只是知道可以这样做

强缓存  -age pragma expries

expires是http1.0的规范 现在使用的是http1.1规范 cache-control的max-age

http1.0和http1.1的区别

主要是一些添加了一些请求头和响应头的信息参数

没有命中强缓存会走协商缓存

协商缓存

服务器返回给浏览器资源的时候会附带一个资源标识 包含last-modified 上一次修改的事件 和该资源对应的标识字符串 e-tag 浏览器下一次像服务器发起请求的时候会携带上这写标识 服务器会根据这个标识判断资源有没有更新 如果更新了会返回200 并把最新资源返回给浏览器 没有更新会返回304状态码

不同资源采用什么缓存策略

一些变 

 HTTP缓存

浏览器根据cache-control判断

expires是http1.0的

强缓存 max-age 文件被用户访问后的存活时间 expries是缓存文件的有效期 max-age大于erpries

HTTP状态码 

1开头的是服务器接收请求需要客户端进一步处理

2开头的是请求成功

3开头的是请求重定向了需要进一步的处理

4开头的是客户端错误

5开头的是服务端错误

100服务器接收清华,客户端需要进一步处理,201请求成功并在服务器上建立了新的资源 202接受请求还没处理完成 203请求成功但返回的实体头部信息是从第三方拷贝过来的

301 请求的资源备用移动到新的地址,浏览器自动重定向到新地址,返回的数据中也包含新的地址

302 跟301类似,资源地址只是被临时移动到了新的的地方客户端应该继续请求原来的地址

304 请求的资源没有被修改,不会返回任何数据,浏览器一般会从本地缓存拿数据

401 用户身份没有被认证 没有权限 403 跟401 401的权限不够访问 相比需要更高的权限来访问

501 服务器不支持请求的功能,无法完成请求 502从上游服务器接收的响应是无效的

JS跨域

 服务器返回了响应信息,但是被浏览器限制了 因为浏览器的同源策略 

同源策略

域名 协议 端口号

为了限制不同源之间的交互 不同源之间是不可以请求的

解决方法 允许cors策略读取 跨域资源共享 http头部组成的 不允许脚本读取跨域返回的数据

proxy代理

jsonp跨域

动态生成一个全局方法,动态生成script标签,将script的src属性改为请求地址,呈现出执行js的语句,生成了假象的ajax,jsonp只能用于get请求

为什么不是真正的ajax

ajas核心是通过xmlhttprequest获取,jsonp核心是通过动态添加script标签获取服务器提供的js脚本

ajax支持get post请求 jsonp只支持get请求

nginx反向代理 把跨域变成不跨域,支持各种请求方法 nginx.conf文件

php修改header 设置为允许所有来源访问 和允许访问的方式

window.name 在页面的生命周期里共享了一个window.name

get 和post

既然get不安全为什么还要使用get

POST会进行两次连接,一次发送header一次发送body,而GET只有一次,网络耗时相比之下就低,所以在请求响应并不是很隐私的信息或者重要信息的时候,最好使用GET

get请求的参数以key value的形式放在地址栏url中是可见的 所以不安全,如果是英文会是英文,如果是中文会base64加密  post请求的参数放在消息主体   bod 里面 url的长度有限制,所以get传递的参数也有限制, get只能发送ASCII的字符 post支持更多的数据格式 contenttype  get会将资源缓存起来,在第二次请求的是相同资源的时候,会把资源缓存起来 只是静态资源 数据不会缓存 

get比post请求更快 post在请求中会包含更多的数据比如contenttype之类的,会先将请求头header发送给服务器确认,在发送body数据 但其实http协议并没有指定post会发送两个tcp包,只是因为部分浏览器和框架导致的

post和get其实都不安全  因为http协议是明文传输的 使用https

js

高阶函数

函数中传入一个函数作为参数并返回一个函数

用户登录之后关闭网页再次打开页面,这个登录状态还会在吗

第一种使用cookie 设置很长的过期时间

第二种使用session 服务端本地保存着session_id,这样每次用户进来的时候向服务器传一个包含session_id的cookie过来,服务器根据自己本地的session_id进行比对

谈谈你对cookie的理解

一般用于用户登录时,登陆成功时服务端会返回一个cookie,浏览器会把它存储到本地。浏览器下次请求时会自动在请求头上携带这个cookie 他的大小只有4kb,

token

服务端用来存储用户状态的  服务端根据客户端传过来的session id,但是可以被伪造,没有采取加密的方法!!!,一旦攻击者通过session id伪造攻击,就会给服务器带来压力甚至击垮服务器。

    5. Token是通过加密算法(如:HMAC-SHA256算法)来实现session对象验证的 具有很强大的扩展性 是个字符串返回给客户端,服务端不保存这个东西,下次浏览器请求的时候会加在请求头里authorization里面 Authorization 请求消息头含有服务器用于验证用户代理身份的凭证,服务端根据这个token用同样的加密在生成一个token,进行比对,就可以知道用户是否登录,优势,不需要再服务器保存,可以保存再浏览器,js,降低了服务器负担

token反解析 

通过浏览器返回的token 服务器在自己的本地生成一个token跟客户端传过来的token进行比对

token和cookie的区别

token完全有应用管理,可以避开同源策略

token可以避开csrf攻击 是无状态的可以在多个服务间共享

cookie seesion token实现多个站点共享数据

cookie 加上define语句来定义 

cookie session 本地存储的区别

cookie的属性(怎么构成的) name value domain cookie对于那个域名是有效的 path 路径 expries max-age有效事件 max-age设置0 立即失效 设置负数 关闭页面失效 size cookie的大小 httponly 是否允许脚本读取 document.cookie true false secure蛇care 安全属性true只能https和一些加密协议能携带 SameSite限制第三方cookie

cookie会话cookie 持久cookie 默认为-1 cookie会被删除

expires不设置该属性 浏览器关闭cookie就消失 设置了在规定的时间内有效

session 属性 session-id 获取session编号 cout 获取session数量 timeout 设置session事件 keys通过keys获取session

用户登录后,服务器会返回一个cookie给浏览器用来记录用户登录状态,下次客户端再请求时会带上这个cookie,服务端就能知道他的登陆状态

cookie是放在客户端的,他的大小只有4kb Cookie 超过 4KB 时,它将面临被裁切,cookie对于客户端来说是可见的,安全性不可靠 最多可以生成60个

cookie ,有效时间前cookie一直有效 session放在服务端用来记录用户状态,他的安全性更加更加可靠,它可以存任何类型的数据session是基于cookie的sessionId生成的,但是存储的数据不能太多不然会影响浏览器的性能

session和cookie是一起使用的,客户端登陆之后,返回给浏览器cookie,服务端会在自己本地生成session-id保存在服务器上,返回的cookie里面就包含session-id,下次请求带上cookie时,服务端会根据cookie-id来进行验证 存储session过多会影响服务器性能,分布式处理,负载均衡时记录不到用户登陆状态 session-id没有加密容易被黑客获取

refresh-token

,用于访问令牌过期之后重新获取新的访问令牌

本地存储他的大小可以达到5mb之多,存储再客户端

箭头函数和普通函数的区别

类数组 geteElementByTagName document.querySelectAll 这些获取dom元素的 arguments

他有着类似数组的结构,也有length属性是一个特殊的对象,但是不能使用数组的方法,arguments有一个callee属性,指向拥有arguments的函数可以用来递归调用,原型上的区别 类数组原型是Object 数组原型是Array 

类数组转数组

...运算符 array.from array.prototype.slice.call先把类数组每一项拷贝到数组中再调用slice方法

...rest是es6引入的 时真正的数组 可以使用数组的方法 原型时Array 

es6新增的特性 const let 模板字符串 字符串新增的一些方法repeat重复某个字符 startwithin检查字符串是否以某个字符开头 endwithin检测字符串是否以某个字符结尾 includes 就是否包含某个字符

解构赋值 对象的结构 数组的结构 数组新增的方法 ...rest获取函数剩余的参数 箭头函数 find  findindex fill  class类关键字 extends实现继承 promise

fill 只有一个参数 全部填充 第二第三 填充起始下标

typeof 和instanceof的区别

typeof只能判断基本数据类型,检测引用数据类型返回object 

instanceof 检测一个对象是否是一个类的实例 不能检测基础数据类型

display:none隐藏时不占位,当再次显示时会发生页面回流和重绘,visibility:hidden隐藏时占位,当再次显示时不会回流和重绘,所以display:none是彻底隐藏了,visibility:hidden的性能要高一些。这两者都无法对dom元素进行一个监听 opactiy 自己还了解到如果使用了animation transtion的opcaty的元素他会被提升成合成层 不会发生重绘

meta标签告诉浏览器如何解析这个页面

doctype告知浏览器以什么标准解析这个文档

原型

每创建一个函数 浏览器的解析器就会向其添加一个prototype的属性,这个属性指向一个对象,这个对象就叫做函数的原型对象里面保存着一些属性和方法,通过new 构造函数创建的实例可以通过__proto属性隐式属性访问到原型对象 原型对象想当于一个公共仓库,所有同一个类的实例都可以访问属性和方法 避免了全局变量的污染,把属性和方法放在原型对象中,不会污染全局和局部作用域

原型链 当我们访问一个对象的属性时,如果它自身没有这个属性他会去他的原型对象上去找,他的原型对象也会有原型,就这样一直一层一层的查找,最终指向null 一般找到2层就能找到,也分情况

es5继承

原型 子类的原型指向了父类的实例 不能传递参数 根据原型链的规则,顺便绑定一下constructor, 这一步不影响继承, 只是在用到constructor时会需要 修改父类实例的属性会影响所有子例

构造函数继承 使用call把父类的this指向了子类的实例实现继承继承不到父类原型上的方法

组合式继承调用的时候会创建两个构造函数

事件处理机制 eventloop

js是单线程的,意味着js代码在执行的时候只有一个主线程来处理所有的任务二非阻塞适当遇到异步任务的时候会先将异步任务挂起,接着往下执行同步代码,等异步任务返回结果后在执行响应的回调

执行js脚本时,会将其同步代码放到栈中进行处理,当遇到异步代码不会等待返回结果,二是先将异步任务挂起,接着往下执行同步任务,等异步任务有了返回结果把他放入事件队列中,等栈中所有同步任务执行完毕后才会执行事件队列中的任务,主线程处于闲置状态会去事件队列中查找任务,优先执行微任务,把事件对应的回调放到栈中去处理同步代码,这样就形成了一个事件循环

为什么要有宏 微任务

微任务执行快,一次性可以执行很多个

进程和线程

单线程 一个线程可以有多个进程

区分数组和对象

Array.isArray() Array.prototype.isprototypeof() 判断他是不是在数组的原型链上  instanceof 判断他是不是数组的实例 object.prototype.tostring.call call让obj借用了prototype.tostring这个方法 【object object】 判断constructor array

instanceof constructor object.prototype.tostring.call

es6的新特性

变量  模板字符串 symbol  class 函数参数 对象的方法 object。keys values assign for of  set map 数组去重 模块化 

闭包

内部函数可以访问外部函数的变量  局部变量会常驻再内存中 造成内存泄漏,避免使用全局变量防止全局变量污染,在退出函数前把不使用的局部变量全部删除,避免变量的循环赋值和引用

使用场景 定时器 防抖

伪类和伪元素的区别

它们是否创造了的元素,

伪类操作的是文档树中已有的元素,伪元素是创造了一个文档树之外的元素,

var  let const 

var是es5就有的语法,var声明的而变量会变成window的属性,他有变量提升,而且能重复声明,let const是es6引入的语法,let 声明的变量可以被修改但不能重复声明,let他的作用域属于块级作用域,变量只在当前这一块级有作用,全局作用域可以声明同一个变量,他也存在变量提升,只不过没有初始化,在代码还没执行到声明的那部分时,会报引用类型的错误。 const声明的是一个常量,作用域和变量提升和let一致,只不过他声明的是一个常量,只能读取,不可以被修改,声明的应用类型的数据可以修改对象的属性值 因为const保存的只是对象的指针,但指针指向的数据是可以更改的

react.cloneelement  不同的是它传入的第一个参数element是一个 React 元素,而不是标签名或组件。新添加的属性会并入原有的属性,传入到返回的新元素中,而旧的子元素将被替换。将保留原始元素的键和引用。

ts

定义类型的方式 type和interface 

类型断言 as 尖括号

编译ts文件 tsc

泛型约束 制每个类型变量接受的类型数量

泛型就是使用一个类型变量来表示一种类型,类型值通常是在使用的时候才会设置。泛型的使用场景非常多,可以在函数、类、interface接口中使用。

axios拦截器 请求拦截器 header添加Authorization  contenttype 等之类的 响应拦截器判断code码 删除token 重新登陆 或者返回正确信息 

React

组件通信的方式

props 

context 父组件传递provider 子组件通过consoumer接收

redux 状态管理工具 将App组件连接到redux 是组件能dispatch函数获取修改reducer的数据

父组件传递给子组件一个方法,子组件在自己组件也写一个方法调用props传过来的这个方法,cbind修改this

context createcontext 创建context上下文

函数组件和类组件的区别

类组件的话重新渲染会重新调用render 

函数组件重新渲染的时候会调用整个函数 读取的不是当前的状态 而是更新后的 

函数组件用户性能优化,没有自己的this 没有生命周期 没有自己的state

hooks

useMemo  缓存的结果是回调函数中return回来的值,主要用于缓存计算结果的值,应用场景如需要计算的状态
useCallback  缓存的结果是函数,主要用于缓存函数,应用场景如需要缓存的函数,因为函数式组件每次任何一个state发生变化,会触发整个组件更新,一些函数是没有必要更新的,此时就应该缓存起来,提高性能,减少对资源的浪费;另外还需要注意的是,useCallback应该和React.memo配套使用,缺了一个都可能导致性能不升反而下降。

useCallback 和 useMemo 参数相同,第一个参数是函数,第二个参数是依赖项的数组。主要区别是 React.useMemo 将调用 fn 函数并返回其结果,而 React.useCallback 将返回 fn 函数而不调用它。

为什么hooks不能用在函数和循环中

最顶层调用他们。能确保 Hook 在每一次渲染中都按照同样的顺序被调用。用在函数和循环中会导致执行顺序的错位 react找不到对应的数据

useState 可以手动添加state状态

useCallback 针对于子组件渲染也是用来作性能优化的,返回的是一个函数,当依赖值不发生变化的时候则不会促发

useContext 组件之间共享状态的,接收context上下文

useReducer 状态管理工具,第一个参数时当前值,第二个时发送action的dispatch函数

useMemo  针对于当前组件高开销的计算,返回的时函数运行的结果一般子组件用到 性能优化的 当依赖的值不发生变化的时候,不触发状态改变

useRef 强制性 返回一个 ref 对象,该对象只有个 current 属性 侵略性比较强

首屏优化

图片懒加载

不一次性展示全部图片,只显示当前窗口的图片 原理是用到了h5的data-属性先暂存图片的地址,在需要显示的地方把图片地址重新赋值到img的src标签上

场景

滑动加载图片

先把img的src属性设置为空字符串,data-属性暂存图片地址,页面滚动的时候监听scroll事件 判断是否滚动到了要加载的图片上,主要使用了getboundingclientrect这个获取元素位置的这个属性,然后将data-属性的图片地址赋值给img的src属性 top小于浏览器可视高度+100 让他提前请求

使用懒加载优先加载主要模块,使用webpack打包之类的

懒加载的原理而新增的 值 需要重新监听起来

webpack会将懒加载的路由分块打包到一个单独的js中去,只有加载该路由的时候,才会加载这个chunk文件。实现按需加载

性能优化

减少http请求多使用http缓存 

使用http2

3. 使用服务端渲染

客户端渲染: 获取 HTML 文件,根据需要下载 JavaScript 文件,运行文件,生成 DOM,再渲染。

服务端渲染:服务端返回 HTML 文件,客户端只需解析 HTML。

  • 优点:首屏渲染快,SEO 好。
  • 缺点:配置麻烦,增加了服务器的计算压力

图片可以切换的svg

静态文件使用cdn

懒加载 cdn

html文件 减少一些不必要的标签的使用,多使用一些语义化的标签利于seo  css文件放在head标签里面 js文件放在body底部

css文件放在head中会先加载css 解析css后构建cssdom树 同时会构建dom树 两者都构建完后会构建render树

而放在body里面 先构建dom树 然后构建render树 渲染一次页面 然后加载css 解析css 构建css树 和dom树重新构建render树再次渲染页面

图片文件可以对它进行压缩

使用http2

使用cdn 一些静态资源 技术文件 音频 视频可以把他上传到cdn上

使用懒加载 像是路由懒加载 图片懒加载 

node中间件 middleware 封装一些http请求细节处理

使用缓存 本地缓存 cdn缓存  浏览器缓存

减少页面的重绘和回流  按需加载和使用模块化 等

react使用usememo usecallback hooks

谈谈你对模块化的理解

将一个复杂的程序分成若干个块,并组合在一起,块的内部结构是独立的

避免了命名冲突,更好的分离组件,保证了按需加载。组件有更好的复用性,和可维护性

在es6之前,实现模块化使用的是requirejs和seajs 也就是AMD和CMD,他们是异步加载模块的 使用define来定义的 他们是基于浏览器端的模块化,还有基于node的common js模块化,它适用于服务端的  模块导出exports 模块导入require 还有模块标识module   es6的模块化分为导入导出export 和import两个模块还有默认导出export default    

export 可以在任何模块中声明 但必须放在最顶层 import 会提升到页面的首部 率先执行 import * as 一次性导出全部 导入的变量名必须与文件名一致 import 可以改写引用类型的属性值 不能改写基本类型 次重复执行同一句 import 语句,那么只会执行一次

移动端适配

主要会从元素单位和媒体查询

宽度和高度使用百分比 需要给html及body和他的父元素设置微100%

使用rem单位 html的fontsize来决定的 给html fontsize设置为16px 那么1rem就是16px

设置rem方式 使用媒体查询 当屏幕宽度和高度小于指定的范围时设置fontsize

通过js方式获取屏幕的可见宽度 clientwidth

使用媒体查询 适配各种屏幕时设置临界值展示不同的分辨率

使用 vw vh单位  1vw就是屏幕宽度的1%

rem和em的区别

rem相对于根元素的字体大小 em是一个相对单位 相对于父元素的字体大小 

script标签 async defer的区别

加了async script代码执行的时候遇到js文件会继续往下页面,等到js文件有了返回结果会暂停解析页面,先解析我们的js文件,解析完之后才解析我们的页面

defer 遇到js文件会继续往下解析,当js文件有了返回结果后不会取解析js文件,而是把当前页面解析完毕后才会执行js,所以加了defer js文件是最后解析的

js异步方法

JS 编程中为什么需要异步?

我们都知道 JavaScript 是单线程的,如果 JS 都是同步代码执行,那么就会阻塞后面的代码执行;而如果使用异步则不会阻塞,我们不需要等待异步代码执行的返回结果,可以继续执行该异步任务之后的代码逻辑。

事件监听

任务的执行不取决于代码的顺序,而取决于某个事件是否发生。

发布/订阅

回调函数 回调地狱

Generator 最大的特点就是可以控制函数的执行。Generator 函数除了状态机,还是一个遍历器对象生成函数。
可暂停函数, yield可暂停,next方法可启动,每次返回的是yield后的表达式结果。
yield表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。

promise属于宏任务也就是同步任务

Promise.resolve()函数被执行时, 会将promise的状态从 pending 改成 fulfilled 成功

2.Promise.reject()函数被执行时, 会将promise的状态从pending 改成 rejected 失败

使用场景 promise.then 这个下个请求依赖上个请求的返回结果 链式调用

.race 图片加载超时提示信息 一个请求的接口 一个错误信息的提示 

promise  .then函数实现链式调用,将promise的resolve方法注入其中有三个状态 pending进行中 fullfilled成功 rejected失败 promise有一些方法 .then是状态发生改变时触发的回调函数,有两个参数 第一个是返回的是一个新的promise实例也就是实现链式调用的原因,第一个参数时resolve第二个是reject 失败时触发的函数,第三个时finnaly不管状态结果如何都会触发的函数。 

promise.all 

组合多个promise实例,如果状态都为成功则返回成功,如果有一项失败则返回失败,它返回的结果是一个数组,传空返回一个已完成,不包含promise返回一个一步完成

promise并发控制以需要我们控制同时执行的promise个数,比如控制为2个,后面的所有promise都排队等待前面的执行完成。

promise.all和eventloop有很大的关系 从eventloop的角度看 是把每一个promise的返回结果放在了任务队列里面 是个异步操作

promise.race 组合多个promise,返回一个率先执行完毕的promise状态

promise.allsettled 组合多个promise 不管状态失败还是成功,都会返回。

async await 外部调用async函数时时异步调用 调用async函数会返回一个promise对象,resolve负责传递这个值,await会等待promise执行返回结果,async函数内部同步执行 await相当于.then 使用trycatch 捕获异常

new 关键字

、开辟内存空间(堆)

2、this指向该内存(让函数内部的this)

3、执行函数代码

4、生成对象实例返回(把空间的地址返回)

Set map

es6新增的数据结构

set叫集合,内部成员是唯一的,存储的是value值, set添加值会判断值是否不同使用的运算类似===。set的一些方法add,delete,has clear

遍历方法 .keys .values .enteries 以键值对的形式遍历

map叫字典 以键值对的形式存储

方法 set(key,value) get(key)查找指定key的value has检查是否有某个key

delete(key)  clear() 

遍历方法 .keys .values .enteries .forEach

for of 可以用来遍历map对象 

for of 可以遍历迭代器对象

浅拷贝深拷贝

防抖和节流

登录或者发送短信 以及一些表单提交的时候避免多次点击

输入框输入内容 让他输入完成后 scroll事件

节流是阻止一个事件在规定时间内重复触发,只有当上一个函数执行后达到规定时间间隔,才会调用。 scoll计算高度 输入框输入内容只在输入完才校验

防抖是事件触发后n秒再执行回调,如果n秒内再次触发,会重新计时 登录 发送短信 连续点击

null == undefined

undefined的值派生至null的值  声明了一个变量但没有赋值,null一般用于可能会返回对象的变量作为初始化 要存一个对象但是还没有保存对象 typeof微object

css处理器

sass less Stylus  postcss 

less在客户端处理 sass在服务端处理的 sass以$定义变量 less以@符 sass支持一些条件语句 if else less不支持  sass功能更加强大 less语法更加简易 更加清晰 

less和sass的编译环境

sass在服务端处理的 使用ruby

less需要引入less.js输出css到浏览器

为什么使用less不适用sass

sass编译环境比较严格需要下载ruby 如比 less编译环境比较宽松 使用less开发

postcss 后处理器 由js处理css 把他解析成ast 在使用一些插件进行处理  autoprofixer 给csss属性添加一些浏览器前缀

js中的事件传播流程

捕获 目标 冒泡

1.捕获阶段:事件对象从目标的祖先节点Window开始传播直至目标。
2.目标阶段:事件对象传递到事件目标。如果事件的type属性表明后面不会进行冒泡操作,那么事件到此就结束了。
3.冒泡阶段:事件对象以一个相反的方向进行传递,从目标开始,到Window对象结束。

vue

npm run serve做了什么

首先会去pakeage.json文件下找对应的script serve命令执行了 vue-cli-service serve  直接执行vue-cli-service serve,会报错,因为操作系统中没有存在vue-cli-service这一条指令

为什么执行 npm run serve 就相当于执行了vue-cli-service

我们在安装依赖的时候,是通过npm i xxx 来执行  安装这个依赖的时候,就会node_modules/.bin/ 目录中创建 好vue-cli-service 为名的几个可执行文件了 是 npm run serve时会到 ./node_modules/.bin 中找到 vue-cli-service 文件作为 脚本来执行,则相当于执行了   npm i 的时候,npm 就帮我们把这种软连接配置好了,其实这种软连接相当于一种映射,执行npm run xxx 的时候,就会到 node_modules/bin中找对应的映射文件,然后再找到相应的js文件来执行。

computed和computed的区别

computed时函数的返回值变了 重新求值 一个值依赖多个值  一个值影响别的值watch是监听的值变了 执行监听的函数

vue的watch

当监听的值发生变化时执行对应的监听函数

watch的其他属性

immediate 设置true 在watch里面声明的这个函数会 立即执行函数的handler方法 设置为false就和原来一样 

deep属性深度监听 设置为true 监听对象的某个属性变化  影响性能 可以单独监听对象的某个属性

Vue 的响应式原理中 Object.defineProperty 有什么缺陷?为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty?

因为数组的位置不固定,数量多变,正常对象key对应value一般不会变,但是如果数组删除了某个元素,比如第一个元素被删除或者头部增加一个元素,那么将导致后面所有的key对应value错位,如果6个元素,也就会触发5次set。数组元素可能非常非常多,每个元素进行劫持有一定浪费Vue将数组的7个变异方法进行了重写,也就是更改了Array原型上的方法达到劫持变化。

而新增的 值 需要重新监听起来

proxy代理了整个对象,不需要预先劫持属性,而是在获取/修改的时候,通过get/set方法来告诉你key。所以不管如何新增属性,总是能被捕获到。

为什么 Vue.$nextTick 通常比 setTimeout 优先级高,渲染更快生效?

nextTick 在vue 源码中是利用 Promise.resolve()实现的

split('') 穿孔默认每个字符以,分割 传空(’   ‘)以空格切割 传(’,‘)每一项以逗号分隔

sort函数

序顺序可以是按字母或数字,也可以是升序(向上)或降序(向下)。

默认情况下,sort() 方法将按字母和升序将值作为字符串进行排序改变原数组

css盒模型

标准盒模型 怪异盒模型(ie盒模型) css弹性伸缩盒模型

Vue双向数据绑定原理

ue.js是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图。

MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,

observer对数据对象进行递归遍历,给属性加上setter和getter,当属性发生变化就会促发setter达到监听数据的变化

compile 解析模板指令 将模板中的变量替换成数据,并绑定更新函数添加 订阅者

watcher 是compile和observer之间通信的桥梁,当observer监听到数据发生改变的时候,执行compile的解析指令触发更新函数渲染页面

Dep来专门收集这些订阅者,然后在监听器Observer和订阅者Watcher之间进行统一管理的

vue核心面试题:组件中的data为什么是一个函数

vue中组件是用来复用的,为了防止data复用,将其定义为函数

数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的data

如何告诉 react 它应该编译生产环境版本?

通常情况下我们会使用 webpack 的 DefinePlugin 方法来将 node_ENV 变量值设置为

production。

如何判断当前脚本运行在浏览器还是node环境中

通过判断 Global (隔了包)对象是否为 window ,如果不为window ,当前脚本没有运行在浏览器中

什么是JSON?

JSON是一种轻量级的数据交换格式。

AJAX最大的特点是什么

 Ajax可以实现动态不刷新(局部刷新)

就是能在不更新整个页面的前提下维护数据。

数组的方法

pop删除最后一项 返回删除的元素  shift删除第一项 返回删除的元素 删除都是返回删除的元素

push unshift 添加返回的都是新数组的长度

涉及到增删的方法 都会改变原数组

字符串的方法

字符串的方法 slice 其实下标 substring 起始下标 包前不包后 substr 开始下标 截取个数

返回的都是截取的字符

0.1+0.2===0.3

精度缺失会发生在二进制和对阶运算中 先转成二进制 位数会无限循环 数字后面的浮点数会造成精度缺失, math.js big.js

谷歌67版本第八种数据类型 bigint 比gingt 安全存储 symbol

vue的eventbus

EventBus 来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,

手动实现eventbus

webpack

前工程化

包含一个项目从创建到开发再到发布的一个流程

为什么说它是前端工程化的一个很好的解决方案

它提供了友好的前端模块化开发支持,以及代码压缩混淆处理浏览器端JavaScript的兼容性 (babel-loder es6转es5)性能优化 对js 图片 css等文件进行一个解析   把一些的的文件进行解析 拆分成多个小的模块 等强大的功能

基于nodejs的项目工程化解决方案 vue vue-cli 一键生成webpack的项目 react都是基于

loader的作用 webpack默认只能打包.js .json后缀的文件 使用loader可以打包不同后缀名的文件比如。css.less 和一些图片等 

工作原理给定一个入口文件entry,output为出口文件  index.js 从这个文件找到所有的文件依赖 用loader处理各种需求,plugin处理loder处理不了的需求 最终会打包成一个js文件

css-loader sass-loder less-loder babel-loder image-loder 加载图片 编译的 es6转es5  热更新 devserver hot为true port 端口号 contentbase输出的文件名 compress 开启gzip压缩  *plugin

html-webpack-plugin 为html文件映入外部资源  mini-css-extract-pliugin 分离css的

plugin怎么实现扩展的

给webpack的每个生命周期绑定了一个触发函数,当执行到对应的生命周期对应的事件就会触发

为什么需要webpack 对项目进行打包发布

因为开发环境下 打包生成的文件存放在内存中,无法获取到最终打包的文件,而且不会被压缩

为了在生产环境下高性能的运行 需要对他进行打包发布

在package.json scripts命令中 添加一个build 命令 webpack--mode production  --model指定的参数会覆盖webpack config 中的model 开发 develop 选项

souce-map

开发环境下 默认是开启的,运行出错时,可以在控制台定位到出错的位置 但是他与实际代码的行数不一致  记录的是生成后代码行报错的位置 与源代码不一致 把他设置为 eval-souce-map

生产环境 建议关闭 或者设置为哦nosourcemap 防止源码被泄露

flex布局

flex-direction 延主轴对齐方式   flex-wrap 是否换行 flex-flow 是flex-direction 和flex-wrap两个缩写默认值为row no-wrap  justify-content 水平方向排列方式 align-items纵轴对齐方式 align-content多线对其方式

项目亮点 难点

登录

我主要就是负责迭代一些模块,封装一些像是form组件table分页,model组件,联调接口等 

项目的一些规范 :  组件结构构清晰,consts文件 config文件 还有子组件都抽离了出来 数据处理同意放在外部不房子啊jsx  图片以及一些svg都使用的cdn   组件中的数据定义一个对象变量 css样式同意都是bem  BlockElement–Modifier  元素嵌套过深可以考虑重新命名结构了  双class  请求数据统一放在父组件里面, 子组件只处理校验,给子组件传递 data数据,loading,和submit 给表单传值时  如果服务端的表单返回了全数据 就会传一个formData

自己怎么手动封装一个form表单组件 使用useState定义数据的时候,判断为一组对象的时候使用一个变量 ,就比如一个添加modal 会定义一个addModalData 为一个对象,有 visibile formData 还有loading  请求数据统一放在父组件里面,还有之前开发的一个模板配置页面 有短信 验证码 和邮箱这三个模块 是一个tab页,在父组件请求完数据后,分别把数据注入到每个子组件里面  

表单的请求放在父组件里面,子组件只处理校验,给子组件传递 data数据,loading,和submit 给表单传值时 如果服务端的表单返回了全数据 就会传一个formData,如果没有没有返回,或者已经进入了子页面 就会传一个id 由子组件去调查询接口 提交的时候会对输入的内容进行一个校验,校验通过,如果有一些参数需要自己修改,比如像是一些日期格式后端需要我们传一个时间搓,我们就需要把日期格式转为时间戳(valueOf转为原始类型值 或者使用momen的方法转换时间戳),电话号码前面需要加上+86之类的 然后提交表单,提交成功,设置loading为 false关闭model,提交失败 会给出提示信息

有个展示页面 有很多卡片,每一个卡片之间的间距统一,每一行只显示3个,给父元素设置flex flex-wrap: wrap;换行 

justify-content: flex-start; /* 从行首起始位置开始排列 */
justify-content: flex-end;  

,子元素设置flex 1 设置外边距,设置他的宽度为 100%-3个盒子边距的总和,设置第三个卡片的右边距为0 

项目难点 

批量编辑

当控制台将页面翻译为英文的时候,添加用户目录或者编辑应用流程都会报错 google翻译会导致html结构发生变化 如果要删改的内容外面是以空标签的形式包裹 点击翻译会在文本节点外面包裹两层font标签,这样父元素就找不到她了 ,解决方法是在外面包裹一层span标签 这样点击翻译的时候是在span标签里面包裹两层font,

后端返回表单定义的数据,规定了form编辑的定义类型和格式,使用普通的form组件实现有点麻烦

在做编辑回显表单的时候,有个请求高并发的场景,不光要查询数据,还要表单定义的数据(优秀一些邮箱电话 用户名密码等支持的类型和是否为必传项)当时是使用了promise.all这个方法实现的,form组件是使用的公司内部封装的form组件,支持像是复选框单选框 如期框文本域 等格式他就只接受一个schema参数,这个参数就是我们要传的数据,每一项的数据里包含type类型,defaultvalue和校验规则,还有componens属性,我们可以自己单独封装组件的样式和格式,还接收一个props属性就是要给自己封装的组件传递的参数,基于上述这些,我们需要自己组装一个数据传给它, switch循环 如果是code为password则给他加上必传和校验规则 还有defaultValue属性,

table分页

 pageable 分页的,设置总数和页码还有每页显示个数 onPagingChange 切换页码的时候触发的 ,当我们搜索的时候需要把页码,和每页显示个数重置 

recordKey优化渲染的

http请求自动携带cookies的条件:

  1. 本地已经缓存有cookies
  2. 根据请求的URL来匹配cookies的domain、path属性,如果都符合才会发送

react如何防止xss攻击的

会对元素和内容进行一个转移 < > 空格符号等会转义成 lt gt nbsp等

react中有一个dangerouslySetinnerhtml 用户替代innerhtml 来给元素设置内容,但他是直接给元素设置内容,如果黑客设置了一些脚本会造成风险

$$type react 0.14版本引入的 存储的是 Symbol 类型的变量,数据库是无法存储 Symbol 类型数据的,所以用户恶意存入的数据是无法带有合法的 $$typeof 字段的。eact 在渲染的时候加上对 $$typeof 合法性的验证即可防止恶意代码的插入

XSS攻击

黑客往我们的web页面插入恶意html标签或者js代码 获取我们用户的信息比如cookie

需要对我们用户输入的地方和url参数进行一个黑名单的校验 例如把半角字符改成全角字符 

对输出的内容进行一个编码 把输出的内容转为html实体 这样黑客就没法运行脚本了 

例如 空格 为&nbsp;>为lt

在setcookie 的httponly字段中设置false 不允许js脚本读取我们的cookie

什么是CSRF攻击?
跟XSS攻击一样xss时获取了用的信息,攻击者盗用了你的身份,以用户的身份发送恶意请求

在HTTP协议中,每一个异步请求都会携带两个Header

验证 HTTP Referer 字段

瑞福ruer
根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP 请求的来源地址

请求统一增加一个拦截器来检查 Referer 的值就可以 验证是不是我们要 请求的来源地址

,在HTTP头中有一个字段叫Referer,记录了该HTTP请求的来源地址。 对于Ajax请求,图片和script等资源请求,Referer为发起请求的页面地址。对于页面跳转,Referer为打开页面历史记录的前一个页面地址。因此我们使用Referer中链接的Origin部分可以得知请求的来源域名。

csrf token

服务端返回给浏览器token,提交时token不能在放在cookie里了,放在服务器的session里,页面加载的时候使用js遍历整个dom 在一些a标签或者form 一些会发起请求的标签 后加入token 服务端来根据传过来的token进行比对

双重cookie 

浏览器访问页面的时候像请求域名注入一个cookie 为随机字符串  像后端发起请求的时候取出这个cookie 后端验证这个cookie是否与域名中的cookie是否一致

大多数情况是用 Promise.then微任务 实现,还有就是 nextTick 并不是一个一个单独执行的。首先,它会把代码中所有的 nextTick 收集起来,放到数组 callbacks(相当于队列) 中,然后通过对应环境下的微任务方法执行 flushCallbacks 方法,即遍历 calllhacks 数组中的每一个方法,然后清空 callbacks 数组。

data-属性的好处

1.自定义属性,可以被js很好的操作 解决自定义属性混乱无管理的现状

2.H5的新属性

attribute和property的区别么

attribute是dom元素作为html标签拥有的属性 property是dom元素作为js对象拥有的属性 getproperty获取 setproperty设置

h5之前实现视频的使用emabled标签实现的

v-if和v-show

 v-if是根据判断条件来动态的进行增删DOM元素,v-show是根据判断条件来动态的进行显示和隐藏元素 -if有更高的切换开销,v-show有更高的初始渲染开销 

数组reduce方法

必需。用于执行每个数组元素的函数。
函数参数:
参数描述
total必需。初始值, 或者计算结束后的返回值。
currentValue必需。当前元素
currentIndex可选。当前元素的索引
arr可选。当前元素所属的数组对象。
initialValue可选。传递给函数的初始值

settimeout实际延迟时间

分场景,谷歌默认最小1ms,如果settimeout嵌套层级多,会是4ms

css实现三栏布局

flex布局

父元素设置flex  左边宽度设置300 右边设置300

float布局

左边float left 右边float right 中间左边距300右边距300

定位布局

左设置绝对定位 left 0 右边设置绝对定位 right 0 中间设置绝对定位 left300 right 300

vue的虚拟dom

其实就是一个js对象,模拟了真实dom的结构,当数据发生改变创建了一个新的dom树,将新树和老树进行对比,只找出改变的那一部分拿出来渲染

css

行内元素设置margin left right  padding left right 有效 但是 top bottom无效

自我介绍

你好!我叫***  熟悉js基础和http网络相关知识 了解模块化和webpack 熟悉的技术栈是react

在上家公司主要是负责一些功能模块的开发 以及和后端 测试人员进行一个协调  自己的性格很活泼 平时早会的组织和团建地方的选址都是我来负责的 最近自己是想要学习python 和调研低代码

低代码的调研

业务应用的快速交付和开发成本 

项目亮点  创新!!!!

项目用到的新技术   和过往项目的不同

代码的规范  eslint的校验   

测试了下谷歌翻译

像我之前开发项目的话主要就是负责开发一些功能模块 我更愿意介绍一些我前段时间开发的一个静态网站  自己从0到1开发的也有很多的收获

1考虑到了安全防护 react  输入内容

1 自己当时是从0到1完成了一个静态网站的开发 首先技术选型上并没有选择vue 框架 选择了react框架  主要一个是为了和之前项目的架构保持一致 我们自己的项目基本不用vue    还有一个是之前看react源码时  react渲染jsx转为真实dom时 有一个$$typeof 这个属性解决了xxs攻击  然后印象挺深的 

还有就是当时开发这个虽然是个pc端的静态网站 但是用户可能会缩小屏幕大小 当时自己是用的flex布局 单位的话一些大型盒子用的多是百分比 加了个媒体查询 指定的宽度适应不同的样式

防止xss xsrf攻击 自己写代码的时候会有意的做一个黑名单的校验 

还有就是这个静态网站有大量的大型图片 之前写项目的时候 都是以svg格式上传 但是我是吧他以png的格式上传  因为我的想法是它是一个官网 然后这么多大型图片加载速度很慢的话 会很影响体验感 png的格式很小加载速度会快一点  svg格式比较复杂  虽然他支持压缩  但是我做的是一个官网宣传页 不需要考虑图片压缩的问题 而要把图片加载速度放在首选

之前提交代码的时候不是很重视commit的规范  自己之前用的提交关键字基本上是 feat  fix

但其实自己平时更改一些代码的格式 应该使用style  一些  代码的重构可以使用refactor  而像是

因为之前写项目时候 进行打包和编译的时候总会有格式的错误 就会很浪费时间 所以在这个项目中每个文件每次写完代码都会格式化下文件

css方面使用了bem规范 预处理器

还有一个我比较重视的是 之前支持别的项目组项目时候 因为项目不同 他在安装依赖的时候会经常发生nodesass 报错 和gyp error的错误 其实主要是因为 node版本过高 或者过低  然后自己是下载了个nvm  在刚开发项目时候 会去项目的开发文档中先看下有没有指定node版本号 然后进行一个切换node 版本 再执行依赖   

 我自己测试下了页面翻译成英文的场景  发现了一个问题 谷歌翻译 

包括自己在开发我们的主项目时 会经常性的使用一些新技术 和新特性 http并发 promise.all

以及我们自己的表单库 当时自己在使用的时候遇到了一个场景 form组件  ui组件

页面的导航有个二级菜单 自己在开发别的项目中也会经常遇到这个功能,当时是跟组长商量了下,我把它拆分打包 组长来负责私有库的一个部署 

webpack打包 优化CiCD 

gif打点请求文件资源不会跨域  文件体积比较小
主要有以下几个方面吧 

1. 涉及金钱方面的业务  计算不能有容差 会遇到一些数字精度丢失的问题   封装了一个公用的处理这个问题得方法 核心是要明确用户消费支出多少钱 所以前端配置一些指标 点击 滞留 花费 提现等 但是因为经济的服务主要给业务方去用 所以业务方提出的问题会很多 功能变化也会很多 从前端的角度处理这个问题 是对这些指标做了一个配置化   做经济服务时 涉及到金钱 所以说需要考虑时效 遇到线上问题 要及时处理  业务需求也比较紧急 优化了下CICd 

2. webpack优化

3.开发流程文档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值