1.前端项目如何找到性能瓶颈
定位问题:性能监控工具、chromedevtools查看耗时操作。
解决问题:常见问题:大量列表渲染(分页加载、递归加载。fragment片段加载,时间分片,虚拟列表)
大量图片(预加载、懒加载、图片压缩、base64)
代码中大量计算(循环、递归、内存占用过高)
组件逻辑过于复杂
资源过大(分包加载,异步加载)
2.字符串转二进制
/*
* 字符串转为二进制,空格隔开
* @param {String}
* @return {String}*/
function strToBin (str) {
var result = '';
var list = [];
for (let i=0; i<str.length; i++) {
// 将单个字符转换成二进制字符串
var charCode = str.charCodeAt(i).toString(2)
list.push(charCode)
result = list.join(' ')
}
return result
}
/*
* 二进制转换为字符串
* @param {binString}
* @result {String}*/
function binToStr (bin) {
var result = '';
var list = bin.split(' ');
for (let i=0; i<list.length; i++) {
// 将asciiCode字符串转为asciiCode
let asciiCode = parseInt(list[i],2)
// 将asciiCode转为字符串
result += String.fromCharCode(asciiCode)
}
return result
}
/*
* image画到canvas上*/
function imageToCanvas(src, cb){
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = src;
img.onload = function (){
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
cb(canvas);
};
document.body.appendChild(canvas)
}
/*
* canvas转img*/
function canvasToImage(canvas){
var img = new Image();
img.src = canvas.toDataURL('image/jpeg', 1.0);
return img;}
}
/*
* canvas转dataURL:canvas对象、转换格式、图像品质*/
function canvasToDataURL(canvas, format, quality) {
return canvas.toDataURL(format||'image/jpeg', quality||1.0);
}
// DataURL转canvas
function dataURLToCanvas(dataurl, cb){
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = function(){
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
cb(canvas);
};
img.src = dataurl;
}
// File/Blob对象转DataURL
function fileOrBlobToDataURL(obj, cb){
var a = new FileReader();
a.readAsDataURL(obj);
a.onload = function (e){
cb(e.target.result);
};
}
// DataURL转Blob对象
function dataURLToBlob(dataurl){
var arr = dataurl.split(',');
var mime = arr[0].match(/:(.*?);/)[1];
var bstr = atob(arr[1]);
var n = bstr.length;
var u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type:mime});
}
// Blob转image
function blobToImage(blob, cb){
fileOrBlobToDataURL(blob, function (dataurl){
var img = new Image();
img.src = dataurl;
cb(img);
});
}
// image转Blob
function imageToBlob(src, cb){
imageToCanvas(src, function (canvas){
cb(dataURLToBlob(canvasToDataURL(canvas)));
});
}
// canvas转Blob
function canvasToBlob(canvas, cb){
cb(dataURLToBlob(canvasToDataURL(canvas)));
}
// image转dataURL
function imageToDataURL(src, cb){
imageToCanvas(src, function (canvas){
cb(canvasToDataURL(canvas));
});
}
// dataURL转image,这个不需要转,直接给了src就能用
function dataURLToImage(dataurl){
var img = new Image();
img.src = d;
return img;
}
3.获取数组的交集
/*
* 获取数组的交集*/
function mix(...args){
// 判断参数的长度如果0,返回空数组
if(args.length == 0) return []
// 判断参数长度如果1,返回第一个参数
if(args.length == 1) return args[0]
return args.reduce((result,ele) => {
return result.filter((item) => {
return ele.includes(item)
})
})
}
4.为什么 HTTP1.1 不能实现多路复用
HTTP/1.1 不是二进制传输,而是通过文本进行传输。由于没有流的概念,在使用并行传输(多路复用)传递数据时,接收端在接收到响应后,并不能区分多个响应分别对应的请求,所以无法将多个响应的结果重新进行组装,也就实现不了多路复用。
5.谈一谈 nextTick 的原理
Vue.js中的 nextTick 函数,会传入一个 cb ,这个 cb 会被存储到一个队列中,在下一个 tick 时触发队列中的所有 cb 事件。同步修改状态,异步操作Dom。 异步优先采用微任务microTask(Promise),如果浏览器不支持则用宏任务macroTask(优先setImmediate ,不支持则用settimeout(()=> {}, 0))
6. 如何在 H5 和小程序项目中计算白屏时间和首屏时间,说说你的思路
白屏时间 = 地址栏输入网址后回车 - 浏览器出现第一个元素
1、在head标签的末尾插入script来统计时间节点作为页面开始展示时间节点
2、Timing.navigation Start-Performance Timing.dom Loading
首屏时间 = 地址栏输入网址后回车 - 浏览器第一屏渲染完成
1、最后一个元素后面内嵌js记录时间
2、图片多的页面记录最后一张图片的
7.如何实现骨架屏,说说你的思路
如何实现骨架屏,说说你的思路
1.如果是首屏可以在index.html中手写骨架屏样式
2.如果是其他页面,可以让UI做一个小的SVG图
3.可以使用组件库中的骨架屏组件
4.指令首先要有骨架效果的dom必须要有初始的width,height在刚插入的钩子函数里面去获取dom,设置css渐变动画。在有数据进来时,在update的钩子函数里面去删除骨骼动画。
4.可以使用饿了么团队开源的根据页面样式生成骨架屏的工具[还可配置生效路由],使用puppeteer获取页面,解析dom信息,渲染骨架屏
8.在一个字符串数组中有红、黄、蓝三种颜色的球,且个数不相等、顺序不一致,请为该数组排序。使得排序后数组中球的顺序为:黄、红、蓝。
例如:红蓝蓝黄红黄蓝红红黄红,排序后为:黄黄黄红红红红红蓝蓝蓝。
function sortBalls (str) {
var tempArr = str.split('')
// 设置排序规则
var sortRules = {
'黄': 0,
'红': 1,
'蓝': 2
}
// 进行排序
tempArr = tempArr.sort((a,b) => {
return sortRules[a]-sortRules[b]
})
return tempArr.join('')
}