前端剑解第一天

html:前端如何高性能渲染十万条数据?有什么方法?

answer:
对于一次性插入大量数据的情况,一般有两种做法:

  1. 时间分片
  2. 虚拟列表

最粗暴的做法,一次性将大量数据插入到页面中:

<ul id="container"></ul>


// 记录任务开始时间
let now = Date.now();
// 插入十万条数据
const total = 100000;
// 获取容器
let ul = document.getElementById('container');
// 将数据插入容器中
for (let i = 0; i < total; i++) {
    let li = document.createElement('li');
    li.innerText = ~~(Math.random() * total)
    ul.appendChild(li);
}

console.log('JS运行时间:',Date.now() - now);
setTimeout(()=>{
  console.log('总运行时间:',Date.now() - now);
},0)
// print: JS运行时间: 187
// print: 总运行时间: 2844

两次console.log的结果时间差异巨大,为什么呢?

因为在 JS 的Event Loop中,当JS引擎所管理的执行栈中的事件和所有微任务事件全部执行完后,才会触发渲染线程对页面进行渲染,所以:

第一个console.log的触发时间是在页面进行渲染之前,此时得到的间隔时间为JS运行所需要的时间
第二个console.log是放到 setTimeout 中的,它的触发时间是在渲染完成,在下一次Event Loop中执行的。
对于大量数据渲染的时候,JS运算并不是性能的瓶颈,性能的瓶颈主要在于渲染阶段。

从上面的例子,我们已经知道,页面的卡顿是由于同时渲染大量DOM所引起的,所以我们考虑将渲染过程分批进行
在这里,我们使用setTimeout来实现分批渲染

<ul id="container"></ul>

//需要插入的容器
let ul = document.getElementById('container');
// 插入十万条数据
let total = 100000;
// 一次插入 20 条
let once = 20;
//总页数
let page = total/once
//每条记录的索引
let index = 0;
//循环加载数据
function loop(curTotal,curIndex){
    if(curTotal <= 0){
        return false;
    }
    //每页多少条
    let pageCount = Math.min(curTotal , once);
    setTimeout(()=>{
        for(let i = 0; i < pageCount; i++){
            let li = document.createElement('li');
            li.innerText = curIndex + i + ' : ' + ~~(Math.random() * total)
            ul.appendChild(li)
        }
        loop(curTotal - pageCount,curIndex + pageCount)
    },0)
}
loop(total,index);

虽然页面加载的时间已经非常快了,每次刷新时可以很快的看到第一屏的所有数据,但是当我们快速滚动页面的时候,会发现页面出现闪屏或白屏的现象。(人的眼睛有视觉停留效应,即前一副画面留在大脑的印象还没消失,紧接着后一副画面就跟上来了, 这中间只间隔了16.7ms(1000/60≈16.7),大多数电脑显示器的刷新频率是60Hz,大概相当于每秒钟重绘60次,FPS为60frame/s,为这个值的设定受屏幕分辨率、屏幕尺寸和显卡的影响。所以会让你误以为屏幕上的图像是静止不动的)。
原因:setTimeout的执行时间并不是确定的。在JS中,setTimeout任务被放进事件队列中,只有主线程执行完才会去检查事件队列中的任务是否需要执行,因此setTimeout的实际执行时间可能会比其设定的时间晚一些。
刷新频率受屏幕分辨率和屏幕尺寸的影响,因此不同设备的刷新频率可能会不同,而setTimeout只能设置一个固定时间间隔,这个时间不一定和屏幕的刷新时间相同。

requestAnimationFrame完成渲染:最大的优势是由系统来决定回调函数的执行时机。
如果屏幕刷新率是60Hz,那么回调函数就每16.7ms被执行一次,如果刷新率是75Hz,那么这个时间间隔就变成了1000/75=13.3ms,换句话说就是,requestAnimationFrame的步伐跟着系统的刷新步伐走。它能保证回调函数在屏幕每一次的刷新间隔中只被执行一次,这样就不会引起丢帧现象。
我们使用requestAnimationFrame来进行分批渲染:

<ul id="container"></ul>

//需要插入的容器
let ul = document.getElementById('container');
// 插入十万条数据
let total = 100000;
// 一次插入 20 条
let once = 20;
//总页数
let page = total/once
//每条记录的索引
let index = 0;
//循环加载数据
function loop(curTotal,curIndex){
    if(curTotal <= 0){
        return false;
    }
    //每页多少条
    let pageCount = Math.min(curTotal , once);
    window.requestAnimationFrame(function(){
        for(let i = 0; i < pageCount; i++){
            let li = document.createElement('li');
            li.innerText = curIndex + i + ' : ' + ~~(Math.random() * total)
            ul.appendChild(li)
        }
        loop(curTotal - pageCount,curIndex + pageCount)
    })
}
loop(total,index);

可以使用 DocumentFragment

DocumentFragment,文档片段接口,表示一个没有父级文件的最小文档对象。
它被作为一个轻量版的Document使用,
用于存储已排好版的或尚未打理好格式的XML片段。
最大的区别是因为DocumentFragment不是真实DOM树的一部分,
它的变化不会触发DOM树的(重新渲染) ,且不会导致性能等问题。
可以使用document.createDocumentFragment方法
或者构造函数来创建一个空的DocumentFragment


<ul id="container"></ul>

//需要插入的容器
let ul = document.getElementById('container');
// 插入十万条数据
let total = 100000;
// 一次插入 20 条
let once = 20;
//总页数
let page = total/once
//每条记录的索引
let index = 0;
//循环加载数据
function loop(curTotal,curIndex){
    if(curTotal <= 0){
        return false;
    }
    //每页多少条
    let pageCount = Math.min(curTotal , once);
    window.requestAnimationFrame(function(){
        let fragment = document.createDocumentFragment();
        for(let i = 0; i < pageCount; i++){
            let li = document.createElement('li');
            li.innerText = curIndex + i + ' : ' + ~~(Math.random() * total)
            fragment.appendChild(li)
        }
        ul.appendChild(fragment)
        loop(curTotal - pageCount,curIndex + pageCount)
    })
}
loop(total,index);


nodejs:知道eggjs和thinkjs吗,有什么区别?

ThinkJS / Sails / LoopBack 等属于上层框架;
Egg 是微内核 + 插件模式,为上层框架服务;
在这里插入图片描述

html:怎么样写出优雅的html结构?

1.不同类型文件进行文件夹分类,css js img 等等

2.避免重复代码,js代码和css 代码分别写到单独文件中,然后再htm中引入,注意引入的先后顺序。就是结构层、表现层、行为层拆分。

3.代码结构接近视觉顺序,块级元素另起一行。

软技能:git pull报错怎么办

git pull 命令等同于先做了git fetch ,再做了git merge, 当git merge后有可能会报错:Your local changes would be overwritten by merge. Commit, stash or revert them to proceed

报错原因是你对本地的代码进行了更改,而未对代码进行提交、存放或还原

解决方法:使用git stash先将更改的代码暂存起来。

git stash命令可以获取你工作目录的中间状态——也就是你修改过的被追踪的文件和暂存的变更——并将它保存到一个未完结变更的堆栈中,随时可以重新应用。

使用git stash将未提交的代码保存之后,现在仓库的状态是和上一次提交的内容是完全一样的

此时再进行git merge temp就不会报错了。

在这里插入图片描述

git stash 工作树模型:H是HEAD提交.I是存储单元的提交.W是工作树中的提交.

git stash常用命令:

1 git stash等同于git stash save存储的修改列表.
2 git stash list查看.
3 git stash show用于校验,
4 git stash apply用于重新存储.

html:如何适应异形屏?

margin :0 auto;
width:1000px;

麻烦的就看这个:沉浸式异形屏解决

css3:动态信封折叠效果

css:body, div, h1, h2, form, fieldset, input, textarea, footer, p { margin: 0; padding: 0; border: 0; outline: none; } @font-face { font-family: 'YanoneKaffeesatzRegular'; src: url('yanonekaffeesatz-regular-webfont.eot'); src: url('yanonekaffeesatz-regular-webfont.eot?#iefix') format('embedded-opentype'), url('yanonekaffeesatz-regular-webfont.woff') format('woff'), url('yanonekaffeesatz-regular-webfont.ttf') format('truetype'), url('yanonekaffeesatz-regular-webfont.svg#YanoneKaffeesatzRegular') format('svg'); font-weight: normal; font-style: normal; } body { background: #ccc url('../images/bg_out.png'); color: #7c7873; font-family: 'YanoneKaffeesatzRegular'; } p { text-shadow:0 1px 0 #fff; font-size:24px; } #wrap { width:530px; margin:20px auto 0; height:1000px; } h1 { margin-bottom:20px; text-align:center; font-size:48px; text-shadow:0 1px 0 #ede8d9; } #form_wrap { overflow:hidden; height:446px; position:relative; top:0px; -webkit-transition: all 1s ease-in-out .3s; -moz-transition: all 1s ease-in-out .3s; -o-transition: all 1s ease-in-out .3s; transition: all 1s ease-in-out .3s; } #form_wrap:before { content:""; position:absolute; bottom:128px; left:0px; background:url('../images/before.png'); width:530px; height: 316px; } #form_wrap:after { content:""; position:absolute; bottom:0px; left:0; background:url('../images/after.png'); width:530px; height: 260px; } #form_wrap.hide:after, #form_wrap.hide:before { display:none; } #form_wrap:hover { height:776px; top:-200px; } form { background:#f7f2ec url('../images/letter_bg.png'); position:relative; top:200px; overflow:hidden; height:200px; width:400px; margin:0px auto; padding:20px; border: 1px solid #fff; border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; box-shadow: 0px 0px 3px #9d9d9d, inset 0px 0px 27px #fff; -moz-box-shadow: 0px 0px 3px #9d9d9d, inset 0px 0px 14px #fff; -webkit-box-shadow: 0px 0px 3px #9d9d9d, inset 0px 0px 27px #fff; -webkit-transition: all 1s ease-in-out .3s; -moz-transition: all 1s ease-in-out .3s; -o-transition: all 1s ease-in-out .3s; transition: all 1s ease-in-out .3s; } #form_wrap:hover form { height:530px; } label { margin: 11px 20px 0 0; font-size: 16px; color: #b3aba1; text-transform: uppercase; text-shadow: 0px 1px 0px #fff; } input[type=text], textarea { font: 14px normal normal uppercase helvetica, arial, serif; color: #7c7873; background:none; width: 380px; height: 36px; padding: 0px 10px; margin: 0 0 10px 0; border:1px solid #f8f5f1; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; -moz-box-shadow: inset 0px 0px 1px #726959; -webkit-box-shadow: inset 0px 0px 1px #b3a895; box-shadow: inset 0px 0px 1px #b3a895; } textarea { height: 80px; padding-top:14px; } textarea:focus, input[type=text]:focus { background:rgba(255, 255, 255, .35); } #form_wrap input[type=submit] { position:relative; font-family: 'YanoneKaffeesatzRegular'; font-size:24px; color: #7c7873; text-shadow:0 1px 0 #fff; width:100%; text-align:center; opacity:0; background:none; cursor: pointer; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; -webkit-transition: opacity .6s ease-in-out 0s; -moz-transition: opacity .6s ease-in-out 0s; -o-transition: opacity .6s ease-in-out 0s; transition: opacity .6s ease-in-out 0s; } #form_wrap:hover input[type=submit] { z-index:1; opacity:1; -webkit-transition: opacity .5s ease-in-out 1.3s; -moz-transition: opacity .5s ease-in-out 1.3s; -o-transition: opacity .5s ease-in-out 1.3s; transition: opacity .5s ease-in-out 1.3s; } #form_wrap:hover input:hover[type=submit] { color:#435c70; }

html:

`<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CSS3实现动态信封折叠留言样式</title>
	<script  src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>
	<!--[if IE]><script>
	$(document).ready(function() { 

$("#form_wrap").addClass('hide');

})

</script><![endif]-->
<link href="css/lanrenzhijia.css" type="text/css" rel="stylesheet" />
</head>
<body>
<div id="wrap">
		<h1>Send a message</h1>
		<div id='form_wrap'>
			<form>
				<p>Hello Joe,</p>
				<label for="email">Your Message : </label>
				<textarea  name="message" value="Your Message" id="message" ></textarea>
				<p>Best,</p>	
				<label for="name">Name: </label>
				<input type="text" name="name" value="" id="name" />
				<label for="email">Email: </label>
				<input type="text" name="email" value="" id="email" />
				<input type="submit" name ="submit" value="Now, I send, thanks!" />
			</form>
		</div>
	</div>
</body>
</html>

(已经校招去赛意了,武汉公司,希望有一个好结果吧!)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值