JSbridge原理, js和native是如何通信的?
4.1.1 JavaScript 调用 Native
JavaScript 调用 Native 的方式,主要有两种:注入 API 和 拦截 URL SCHEME。
4.2 JSBridge 接口实现
JSBridge 的接口主要功能有两个:调用 Native(给 Native 发消息)和接被 Native 调用(接收 Native 消息)。
react和vue的比较 ?
React Diff 算法 ?
观察者模式实现 ?
面向对象如何实现? 需要复用的变量 怎么处理 ?
主流框架的数据单向/双向绑定实现原理 ?
IFF算法为什么是O(n)复杂度而不是O(n^3)
http报文头部有哪些字段? 有什么意义 ? http 请求包含哪些字段 分别是什么意思?
第一部分:请求行,用来说明请求类型,要访问的资源以及所使用的HTTP版本。
GET /http://www.sohu.com HTTP/1.1 请求行,只不过这里被分开了,请求的方式 URL 版本
第二部分:请求头部,紧接着请求行(即第一行)之后的部分,用来说明服务器要使用的附加信息。
1)Host:主机名 www.solu.com
2)User-Agent:使用什么代理服务器,这里就是FireFox,也就是火狐
3)Accept:能接收的数据类型有哪些
4)Accept-Language:表示用户希望优先想得到的版本,一次排列下去,先是中文,再是英文
5)Accept-Encoding:通知服务端可以发送的数据压缩格式
6)Cookie:浏览器端的一个技术,在服务器上记录用户信息,但是也会在浏览器中保存一份。
7)Connection:连接的方式,有两种,非持续连接和持续连接,非持续连接,一次请求/响应就对应一个TCP连接,接到了响应该连接就关闭,然后在发送请求就在建立TCP连接,持续连接就相反,这里使用的是持续连接
8)Upgrade-Insecure-Requests:该指令用于让浏览器自动升级请求从http到https,用于大量包含http资源的http网页直接升级到https而不会报错.简洁的来讲,就相当于在http和https之间起的一个过渡作用。
第三部分:空行,请求头部后面的空行是必须的
即使第四部分的请求数据为空,也必须有空行。
第四部分:请求数据也叫主体,可以添加任意的其他数据。
使用GET方式请求时请求数据为空。
由于一般请求报文都不会有请求数据的,所以在9后面就没有内容了,一般如果想要发送数据过去度会通过在域名后面加?然后将数据创送过去
移动端rem布局如何实现? 简述原理?
移动端高清方案如何解决 ?
宽度可以随屏幕适应,但高度不能,宽屏下会被拉伸:
flex
百分比
无法完全适配Android设备各种屏幕,无法保证显示的一致性
媒体查询
rem
屏幕根据dpr的值进行了相应的缩放
很好的还原了1px在高清屏真实度
图片使用了750下的两倍图,并没有做按dpr的值加载不同的图片
px转rem需要使用工具转换
- 1px细线问题
1、使用box-shadow
-webkit-box-shadow:0 1px 1px -1px rgba(0, 0, 0, 0.5);
2、使用background-image
background-image:
linear-gradient(180deg, red, red 50%, transparent 50%),
linear-gradient(270deg, red, red 50%, transparent 50%),
linear-gradient(0deg, red, red 50%, transparent 50%),
linear-gradient(90deg, red, red 50%, transparent 50%);
background-size: 100% 1px,1px 100% ,100% 1px, 1px 100%;
background-repeat: no-repeat;
background-position: top, right top, bottom, left top;
缺点:不能实现圆角1px效果,css需要做兼容处理
*** 3、使用border-image***
border-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAECAYAAABP2FU6AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAB5JREFUeNpiPnH8zH/G////MzAxAAHTyRNn/wMEGABpvQm9g9TJ1QAAAABJRU5ErkJggg==") 2 0 stretch;
border-width:0px 0px 1px;
缺点:边框颜色不便修改
4、伪类:after & transform: scale(0.5)
.box4
position relative
&:after
content ''
display block
position absolute
top -50%
left -50%
bottom -50%
right -50%
border 1px solid red
-webkit-transform scale(0.5)
transform scale(0.5)
缺点:占用了伪类,容易和原样式冲突
使用0.5px适配ios8以上的iPhone机型
2倍图
webpack的原理, loader 和 plugin 是干什么的? 有自己手写过么 ?
webpack的原理, loader 和 plugin
loader是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中
对于loader,它就是一个转换器,将A文件进行编译形成B文件,这里操作的是文件,比如将A.scss或A.less转变为B.css,单纯的文件转换过程
- 处理一个文件可以使用多个loader,loader的执行顺序是和本身的顺序是相反的,即最后一个loader最先执行,第一个loader最后执行。
- 第一个执行的loader接收源文件内容作为参数,其他loader接收前一个执行的loader的返回值作为参数。最后执行的loader会返回此模块的JavaScript源码
module.exports = {
entry: {
index: './src/js/index.js'
},
plugins: [...],
optimization: {...},
output: {...},
module: {
rules: [
...,
{
test: /\.txt$/,
use: [
'./loader/uppercase-loader.js',
'./loader/reverse-loader.js'
]
}
]
}
}
plugin是一个扩展器,它丰富了wepack本身,针对是loader结束后,webpack打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听webpack打包过程中的某些节点,执行广泛的任务。
CssPathTransfor.js
class CssPathTransfor {
apply (compiler) {
compiler.plugin('emit', (compilation, callback) => {
console.log('--CssPathTransfor emit')
// 遍历所有资源文件
for (var filePathName in compilation.assets) {
// 查看对应的文件是否符合指定目录下的文件
if (/static\/css\/pages/i.test(filePathName)) {
// 引入路径正则
const reg = /\/static\/css\/vendor\.wxss/i
// 需要替换的最终字符串
const finalStr = '/subPages/enjoy_given/static/css/vendor.wxss'
// 获取文件内容
let content = compilation.assets[filePathName].source() || ''
content = content.replace(reg, finalStr)
// 重写指定输出模块内容
compilation.assets[filePathName] = {
source () {
return content;
},
size () {
return content.length;
}
}
}
}
callback()
})
}
}
module.exports = CssPathTransfor
复制代码看着挺多,实际就是遍历compilation.assets模块。对符合要求的文件进行正则替换。
2)修改webpack配置
var baseWebpackConfig = require('./webpack.base.conf')
var CssPathTransfor = require('../plugins/CssPathTransfor.js')
var webpackConfig = merge(baseWebpackConfig, {
module: {...},
devtool: config.build.productionSourceMap ? '#source-map' : false,
output: {...},
plugins: [
...,
// 配置插件
new CssPathTransfor(),
]
})
SSR 和 客户端渲染有什么区别 , vue是如何实现绑定事件的 ?
SPA(single page application) 单页面应用,是前后端分离时提出的一种解决方案。
优点:页面之间切换快;减少了服务器压力;
缺点:首屏打开速度慢,不利于 SEO 搜索引擎优。
关于SSR你需要关注:
- 首次重要的绘制。单靠SSR并不能保证良好的效果,还需要关键的CSS和靠近客户端。
- 支持SEO,支持Twitter和Facebook等其他机器人
- 优雅的退化。这样能确保你的服务在没有JS的情况下也是可用
SSR (server side rendering)服务端渲染,SSR 的出现一定程度上解决了 SPA 首屏慢的问题,又极大的减少了普通 SPA 对于 SEO 的不利影响。
优点:
更快的响应时间,不用等待所有 js 都下载完成,浏览器便能显示比较完整的页面;
更好的 SSR,我们可以将 SEO 关键信息直接在后台就渲染成 html,从而保证搜索引擎都能爬取到关键数据。
缺点:
占用更多的 CUP 和内存资源;
一些常用的浏览器的 api 可能无法正常使用,比如 window,document,alert等,如果使用的话需要对运行环境加以判断。
浏览器事件有哪些过程? 为什么一般在冒泡阶段, 而不是在捕获阶段注册监听? addEventListener 参数分别是什么 ?
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
console.log("You clicked me!");
}, false);
移除事件监听
在为某个元素绑定了一个事件后,如果想接触绑定,则需要用到 removeEventListener 方法。看如下例子:
const handler = function() {
// handler logic
}
const btn = document.getElementById("btn");
btn.addEventListener("click", handler);
btn.removeEventListener("click", handler);
需要注意的是,绑定事件的回调函数不能是匿名函数,必须是一个已经被声明的函数,因为解除事件绑定时需要传递这个回调函数的引用。
第三个参数useCapture
现在再看 addEventListener(eventName, handler, useCapture) 函数。第三个参数是 useCapture,代表是否在捕获阶段进行事件处理, 如果是 false, 则在冒泡阶段进行事件处理,如果是 true,在捕获阶段进行事件处理,默认是 false。这么设计的主要原因是当年微软和 netscape 之间的浏览器战争打得火热,netscape 主张捕获方式,微软主张冒泡方式,W3C 采用了折中的方式,即先捕获再冒泡。
事件委托是事件冒泡的一个应用,但有时候我们并不希望事件冒泡。比如下面的例子
const ele = document.getElementById("ele");
ele.addEventListener("click", function(e) {
console.log("ele-click");
e.stopPropagation(); // 阻止事件冒泡
}, false);
document.addEventListener("click", function(e) {
console.log("document-click");
}, false);
preventDefault(): 通知浏览器不要执行与事件关联的默认动作;
stopPropagation(): 阻止冒泡;
http code码?
HTTP: Status 1xx (临时响应)->表示临时响应并需要请求者继续执行操作的状态代码
HTTP: Status 200 – 服务器成功返回网页
HTTP Status 203 (非授权信息)-> 服务器已成功处理了请求,但返回的信息可能来自另一来源。
HTTP Status 204 (无内容)-> 服务器成功处理了请求,但没有返回任何内容。
HTTP Status 403 (禁止)-> 服务器拒绝请求。
HTTP: Status 404 – 请求的网页不存在
HTTP Status 5xx (服务器错误)->这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
HTTP: Status 503 – 服务不可用
TCP三次握手的过程, get post请求的区别 ?
GET请求不安全
GET提交的数据会放在URL之后
GET提交的数据大小有限制(因为浏览器对URL的长度有限制)
对URL的最大限制为2083个字符,若超出这个数字,提交按钮没有任何反应。
POST相对安全
POST方法是把提交的数据放在HTTP包的Body中
静态文件的浏览器缓存如何实现?
前端跨域方案
一、 通过jsonp跨域
1.)原生实现:
服务端返回如下(返回时即执行全局函数):
handleCallback({"status": true, "user": "admin"})
二、 document.domain + iframe跨域
此方案仅限主域相同,子域不同的跨域应用场景。
实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。
三、 location.hash + iframe跨域
四、 window.name + iframe跨域
五、代理
六、 跨域资源共享(CORS)
普通跨域请求:只服务端设置Access-Control-Allow-Origin即可,前端无须设置,若要带cookie请求:前后端都需要设置。
简述从网页输入url到网页展示的过程发生了哪些事情 ?
domain => ip => send request => response => dom tree => css tree => rendering tree
if Javascript stop render to load exec Javascript until done , continue render
reflow(回流)和repaint(重绘)
移动端如何优化首页白屏时间过长 ?
第一步,分析你的网站渲染状况
我们以Google为例,通过Chrome的Performance工具查看页面渲染情况,如下图,你应该可以清晰的看到图中有四条竖线,他们分别是什么含义呢?
第二步,分析关键渲染路径
在关键渲染路径中,我们通常要关注三个点:
页面首次渲染需要的关键资源数量
关键资源的大小
关键渲染路径的往返次数(Roundtrip)
1、减少关键资源的大小
我们首先从最简单也是最直接的减少关键资源的大小开始:
对于所有的资源(HTML,JavaScript,CSS,Image等),你都应该用上三大绝招:Minify,Compression和Cache,这里不过多的赘述里面的细节。
2、延迟JavaScript非阻塞资源加载
方式一:即阻塞的JavaScript,HTML解析过程中遇到script标签,发出网络请求获取script.js,在网络请求返回后,解析并执行script.js,然后浏览器继续HTML解析。
方式二:async,完全的异步操作,HTML解析遇到该标签后,发出网络请求,但不阻止HTML解析和其后面的渲染操作,当JavaScript请求返回后立刻执行,且不等待HTML解析或其他操作的完成。所以,如果脚本中有DOM操作,就并不适合。比较适合的场景是Google Analytics。
方式三:defer,HTML的解析和对JavaScript资源的网络请求是并行的,但它会等待HTML解析完成之后,才执行脚本。
3、尽早和按需的加载CSS
4、内联CSS来提高渲染性能
5、一个神奇的数字14kb
在最开始我们提到,要减小关键资源的大小,那么多小比较合适呢?(废话,当然是越小越好)。
其实,有一个神奇的数字14kb,它是怎么来?
HTTP的传输层协议是TCP,TCP协议有一个慢启动的过程,即它在第一次传递数据时,只能同时传递14kb的数据块,所以当数据超多14kb时,TCP协议传递数据实际是多次的往返(roundtrip)。如果能够将渲染所需要的资源控制在14kb之内,那么就能TCP协议启动时,一次完成数据的传递。
ajax原理
1.创建Ajax核心对象XMLHttpRequest(记得考虑兼容性)
2.向服务器发送请求
xmlhttp.open(method,url,async);
xmlhttp.send();
我们的实例在 open() 的第三个参数中使用了 "true"。
该参数规定请求是否异步处理。
True 表示脚本会在 send() 方法之后继续执行,而不等待来自服务器的响应。
注意:post请求一定要设置请求头的格式内容
xmlhttp.open("POST","ajax_test.html",true);
xmlhttp.setRequestHeader("content-type","application/x-www-form-urlencoded");
xmlhttp.send("fname=Herry&lname=Ford");
3.服务器响应处理(区分同步跟异步两种情况)
responseText 获得字符串形式的响应数据。responseXML 获得XML 形式的响应数据。
3.1 同步处理
xmlhttp.open("GET","http://www.runoob.com/try/ajax/demo_get.php",false);
xmlhttp.send();
document.getElementById("mydiv").innerHTML=xmlhttp.responseText;
直接在send()后面处理返回来的数据。
3.2 异步处理
异步处理相对比较麻烦,要在请求状态改变事件中处理
xmlhttp.onreadystatechange=function () {//接收到服务端响应时触发
if(xmlhttp.readyState==4&&xmlhttp.status==200){
document.getElementById("mydiv").innerHTML=xmlhttp.responseText;
}
}
移动端300ms延时的原因? 如何处理?
重点:由于移动端会有双击缩放的这个操作,因此浏览器在click之后要等待300ms,看用户有没有下一次点击,也就是这次操作是不是双击。
方案一:禁用缩放
当HTML文档头部包含如下meta标签时:
方案二:更改默认的视口宽度
方案三:CSS touch-action
touch-action这个CSS属性。这个属性指定了相应元素上能够触发的用户代理(也就是浏览器)的默认行为。如果将该属性值设置为touch-action: none,那么表示在该元素上的操作不会触发用户代理的任何默认行为,就无需进行300ms的延迟判断。
方案二:FastClick
简述公司node架构中容灾的实现 ?
ES6 generator函数简述
数组去重实现?
js浮点数运算不精确 如何解决?
js 有哪些数据类型 如何判断? null 和 undefined区别 应用场景?
new String('a') 和 'a' 是一样的么?
移动端如何实现下拉到底部 跟随移动 结束后回弹的动画?