一、项目中遇到过什么问题?
1.兼容性方面
下文
2.业务逻辑方面
-1.单点登录的时候如何解决多系统之间用户登录
单点登录用token来校验。或者可以说有专门负责项目安全的人员。或者说花钱买服务。
环境安全:初期通过购买云服务
程序安全;token +签名
-2.信息同步以及用户信息共享;
-3.登录需要发送短信验证码的时候如何保证消息到达率是100%;
-4.如何实现redis与数据库信息同步;
-5.开发环境程序正常,生产环境程序bug
3.前后端通讯方面
-1.跨域
当地址里的端口、域名、协议三者有一个不同时,我们就需要跨域去请求数据
跨域的方式有以下几种:jsonp,postMessage,Websocket,CORS等
最常用的是jsonp
jsonp通过script的特性src可以天然跨域实现跨域
使用:向页面添加script标签src里填我们需要获取数据的地址后接和后台约定的属性
属性等于一个函数方法,然后服务端通过这个函数方法把数据传过来,我们可以在函数里接收获取到的数据
jsonp的缺点是只能访问get方法
vue通过使用http-proxy-middleware代理解决跨域问题
-2.联调,统一字段
前后端字节不统一,确定不是前端的问题后跟后端协商,进行联调然后统一字段
-3.安全性
对传参进行加密 md5、hash哈希加密
防止攻击:
xss:脚本攻击。
将脚本通过评论等渠道提交,被存到数据库,当再通过数据库取数据时,浏览器直接运行脚本
,造成脚本攻击
解决方法:
1、编码,就是转义用户的输入,把用户的输入解读为数据而不是代码
2、校验,对用户的输入及请求都进行过滤检查,如对特殊字符进行过滤,设置输入域的匹配规则等。
CSRF:跨站请求伪造。
用户登录访问受信任网站A,浏览器带上服务器返回的cookie,在A访问不受信任B时,cookie被
B网站获取,用cookie冒充用户在A网站进行操作
解决方法:1.验证 HTTP Referer 字段;2.在请求地址中添加 token 并验证
-4.数据格式
JSON格式:
json是用于存储和传输数据的格式,常用于服务端向网页传递数据;
stringfy转成json文本的字符串
parse 将json字符串转成javascript对象
4.优化方面
-1.页面优化
防抖:两次操作的间隔不能超过规定值才执行
节流:一段时间只执行一次,期间操作不触发执行
seo:<meta keywords>标签:关键词,列举出几个页面的重要关键字即可
懒加载:
路由懒加载:使用impote引入路由或组件
图片懒加载:监听页面,使用一个自定义属性先保存src的路径,当到页面达到一定值的时候把
属性替换成src,实现图片懒加载
二、兼容性
1.pc端兼容
-1.浏览器兼容
浏览器显示不同情况下的标签,在样式里添加前缀
ajax里核心浏览器对象的匹配
ie6.0横向margin加倍 -> display:inline
两个块元素,竖向的margin值不增加,会重叠,其间距为最大margin值 -> BFC
使用重置样式
*{margin:0;padding:0;}
hack
2.浏览器前缀
CSS3前缀-webkit-webkit渲染引擎chrome/safari
-moz-gecko渲染引擎firefox
-ms-trident渲染引擎IE
-o- opeck渲染引擎 opera
动画、过渡、background-size 都需要加前缀
2.移动端兼容
-1.300ms问题
300ms延迟解决方案:
(1) 禁用缩放,在html文档头部加meta标签如下:
<meta name=”viewport” content=”user-scalable=no”/>
(2) 更改默认的视口宽度 (响应式布局,消除了站点上可能存在的双击绽放的请求)
<meta name=”viewport” content=”width=device-width”/>
(3) Css touch-action
touch-action:none;在该元素上的操作不会触发用户代理的任何行为,无需进行3000ms延迟判断。
(4) FastClick为解决移动端浏览器300毫秒延迟开发的一个轻量级的库
点击穿透解决方案:
(1)只用touch
(2)只用click
(3)tap后延迟350ms再隐藏mask
(4)pointer-events
三、优化
1.html优化
1.尝试使用 AMP HTML
2.w3c标准规范代码
2.css优化
1.避免过度约束
2.避免后代选择符
3.避免链式选择符
4.使用紧凑的语法
5.避免不必要的命名空间
6.避免不必要的重复
7.最好使用表示语义的名字。一个好的类名应该是描述他是什么而不是像什么
8.避免!important,可以选择其他选择器
9.尽可能的精简规则,你可以合并不同类里的重复规则
3.js优化
代码重用
避免全局变量(命名空间,封闭空间,模块化mvc..)
拆分函数避免函数过于臃肿
(1) 减少http请求次数:CSS Sprites, JS、CSS源码压缩、图片大小控制合适;网页Gzip,
CDN托管,data缓存 ,图片服务器。
(2) 前端模板 JS+数据,减少由于HTML标签导致的带宽浪费,前端用变量保存AJAX请求结果,每次
操作本地变量,不用请求,减少请求次数
(3) 用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能。
(4) 当需要设置的样式很多时设置className而不是直接操作style。
(5) 少用全局变量、缓存DOM节点查找的结果。减少IO读取操作。
(6) 避免使用CSS Expression(css表达式)又称Dynamic properties(动态属性)。
(7) 图片预加载,将样式表放在顶部,将脚本放在底部 加上时间戳。
(8) 避免在页面的主体布局中使用table,table要等其中的内容完全下载之后才会显示出来,显示
比div+css布局慢。
4.页面优化
减少http请求数量
CSS Sprites CSS精灵 雪碧图
合并CSS和JS文件 打包工具 webpack,gulp
采用lazyload 懒加载
控制资源文件加载优先级 一般css提前js在后
尽量外链CSS和JS(结构、表现和行为的分离),保证网页代码的整洁,也有利于日后维护
利用浏览器缓存
减少重排(Reflow) 如果需要在DOM操作时添加样式,尽量使用 增加class属性,而不是通过style操作样式。
减少 DOM 操作
图标使用IconFont替换
不使用CSS表达式,会影响效率
使用CDN网络缓存,加快用户访问速度,减轻服务器压力
启用GZIP压缩,浏览速度变快,搜索引擎的蜘蛛抓取信息量也会增大
伪静态设置
图片使用svg
5.浏览器优化
1.首屏数据请求提前,避免 JavaScript 文件加载后才请求数据
2.首屏加载和按需加载,非首屏内容滚屏加载,保证首屏内容最小化
3.模块化资源并行下载
4.meta dns prefetch 设置 DNS 预解析
5.资源预加载
6.合理利用 MTU 策略
7.合理利用浏览器缓存
8.
6.性能优化
代码层面:避免使用css表达式,避免使用高级选择器,通配选择器。
缓存利用:缓存Ajax,使用CDN,使用外部js和css文件以便缓存,添加Expires头,服务端配置Etag,减少DNS查找等
请求数量:合并样式和脚本,使用css图片精灵,初始首屏之外的图片资源按需加载,静态资源延迟加载
请求带宽:压缩文件,开启GZIP,
代码层面的优化
用hash-table来优化查找
少用全局变量
用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能
用setTimeout来避免页面失去响应
缓存DOM节点查找的结果
避免使用CSS Expression
避免全局查询
避免使用with(with会创建自己的作用域,会增加作用域链长度)
多个变量声明合并
避免图片和iFrame等的空Src。空Src会重新加载当前页面,影响速度和效率
尽量避免写在HTML标签中写Style属性
移动端性能优化
尽量使用css3动画,开启硬件加速。
适当使用touch事件代替click事件。
避免使用css3渐变阴影效果。
可以用transform: translateZ(0)来开启硬件加速。
不滥用Float。Float在渲染时计算量比较大,尽量减少使用
不滥用Web字体。Web字体需要下载,解析,重绘当前页面,尽量减少使用。
合理使用requestAnimationFrame动画代替setTimeout
CSS中的属性(CSS3 transitions、CSS3 3D transforms、Opacity、Canvas、WebGL、Video)会触发GPU渲染,请合理使用。过渡使用会引发手机过耗电增加
PC端的在移动端同样适用
减少页面的重绘重排
7.SEO优化
seo搜索引擎,做seo优化的目的是为了让我们所做的项目更容易被搜索引擎爬虫发现,进而提高访问量
seo优化:
网站结构布局优化:尽量简单、开门见山,提倡扁平化结构
控制首页链接数量:首页的链接数量要多
扁平化的目录层次:目录简单一些,方便爬虫用最少的次数就能到达网站的任何一个网页
利用布局,把重要内容HTML代码放在最前
控制页面的大小,减少http请求,提高网站的加载速度。
<meta keywords>标签:关键词,列举出几个页面的重要关键字即可,切记过分堆砌。
<meta description>标签:网页描述,需要高度概括网页内容,切记不能太长,过分堆砌关键词,
每个页面也要有所不同。
语义化书写HTML代码,符合W3C标准
<a>标签:页内链接,要加 “title” 属性加以说明,让访客和 “蜘蛛”
知道。而外部链接,链接到其他网站的,则需要加上 el="nofollow" 属性, 告诉 “蜘蛛”
不要爬,因为一旦“蜘蛛”爬了外部链接之后,就不会再回来了。
<img>应使用 "alt" 属性加以说明
尽量少使用iframe框架,因为“蜘蛛”一般不会读取其中的内容。
谨慎使用 display:none
:对于不想显示的文字内容,应当设置z-index或缩进设置成足够大的负数偏离出浏览器之外。因为
搜索引擎会过滤掉display:none其中的内容。
8.SPA首屏优化
- 将公用的JS库通过script标签外部引入,减小app.bundel的大小,让浏览器并行下载资源文件,
提高下载速度;
- 在配置 路由时,页面和组件使用懒加载的方式引入,进一步缩小 app.bundel
的体积,在调用某个组件时再加载对应的js文件; components:()=>impotent("@/文件路径")
- 加一个首屏 loading 图,提升用户体验;
###四、框架思想
1.MVC
View 传送指令到 Controller
Controller 完成业务逻辑后,要求 Model 改变状态
Model 将新的数据发送到 View,用户得到反馈
所有通信都是单向的。
2.MVVVM
-1.简介
组成部分Model、View、ViewModel
View:UI界面
ViewModel:它是View的抽象,负责View与Model之间信息转换,将View的Command传送到Model;
Model:数据访问层
View的变动,自动反映在 ViewModel,反之亦然
-2.双向绑定的原理:
vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个
属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.de
fineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应
监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue
将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到
getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
vue的数据双向绑定 将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Obs
erver来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析
{{}}),最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化
—>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。
-3.虚拟DOM
它直接用JavaScript实现了DOM树(大致上)。组件的HTML结构并不会直接生成DOM,而是映射生成
虚拟的JavaScript DOM结构,React又通过在这个虚拟DOM上实现了一个 diff
算法找出最小变更,再把这些变更写入实际的DOM中。这个虚拟DOM以JS结构的形式存在,计算性能
会比较好,而且由于减少了实际DOM操作次数,性能会有较大提升
3.模块化
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。
CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。
AMD 是提前执行,CMD 是延迟执行。
AMD推荐的风格通过返回一个对象做为模块对象,CommonJS的风格通过对module.exports或exports的属性赋值来达到暴露模块对象的目的。
CMD模块方式
define(function(require, exports,module) {
// 模块代码
});
4.组件化
解释:前端组件化开发,就是将页面的某一部分独立出来,将这一部分的
数据层(M)、视图层(V)和
控制层(C)用黑盒的形式全部封装到一个组件内,暴露出一些开箱即用的函数和属性供外部组件调
用。
作用:一个前端组件,包含了
HTML、CSS、JavaScript,包含了组件的模板、样式和交互等内容,基本上涵盖了组件的所有的内容
,外部只要按照组件设定的属性、函数及事件处理等进行调用即可,完全不用考虑组件的内部实现
逻辑,对外部来说,组件是一个完全的黑盒。
好处:降低系统各个功能的耦合性,并且提高了功能内部的聚合性,耦合性的降低,提高了系统的
伸展性,降低了开发的复杂度,提升开发效率,降低开发成本。
5.路由实现
hash模式 和 history模式
hash模式:**在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取;
特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,ha
sh不会重加载页面。
history模式:**history采用HTML5的新特性;且提供了两个新方法:pushState(),replaceStat
e()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。