【高并发】的前端面试题汇总及解析—(I)

720 阅读11分钟

       废话不多说,直接奔主题

一、 图片优化

项目中图片处理相关的优化,项目中用到的优化方案,图片大小达到多少的时候选择处理?

1. 首先了解在web开发中常见的图片有那些格式。

JPG 通常使用的背景图片,照片图片,商品图片等等。这一类型的图片都属于大尺寸图片或较大尺寸图片一般使用的是这种格式。

PNG 这种格式的又分为两种 一种PNG-8 一种 PNG-24

PNG-8格式不支持半透明,也是IE6兼容的图片存储方式。

PNG-24图片质量要求较高的半透明或全透明背景,保存成PNG-24更合适(为了兼容IE6可以试用js插件pngfix)一般是背景图标中试用的多。

GIF 这种格式显而易见的是在需要gif动画的时候试用了。

2.优化方案

l 样式代替图片

例如:半透明、圆角、阴影、高光、渐变等。这些效果主流的浏览器都能够完美支持,而对于那些低端浏览器,我们并不会完全抛弃他们,“渐进增强”则是一个很好的解决方案。

l 精灵图

CSS Sprites,将同类型的图标或按钮等背景图合到一张大图中,减少页面请求。

l 字体图标

Icon Font,将图标做成字体文件。优点是图标支持多个尺寸,兼容所有浏览器,减少页面请求等。美中不足的是只支持纯色的icon。SVG,对于绝大多数图案、图标等,矢量图更小,且可缩放而无需生成多套图。现在主流浏览器都支持SVG了,所以可放心使用!

l Base64

将图片转化为base64编码格式,资源内嵌于CSS或HTML中,不必单独请求。

Base64格式

data:[][;charset=][;base64],

Base64 在CSS中的使用

.demoImg{ background-image: url("data:image/jpg;base64,/9j/4QMZRXhpZgAASUkqAAgAAAAL...."); }

Base64 在HTML中的使用

<img width="40"
height="30" src="data:image/jpg;base64,/9j/4QMZRXhpZgAASUkqAAgAAAAL...."
/>

l 图片响应式

通常图片加载都是可以通过lazy加载的形式来的,那么可以在加载的时候来判断屏幕的尺寸来达到加载大图还是小图的目的来达到优化。

二、 提高网站的性能

你知道有哪些方法可以提高网站的性能?

我们从两个方面来讲:

1. 资源加载

CSS顶部, JS底部

CSS JS文件压缩

尽量使用图片使用精灵图,字体图标

图片加载可通过懒加载的方式。

总之就是减少资源体积减少资源请求次数。

2. 代码性能

CSS:

使用CSS缩写,减少代码量;

减少查询层级:如.header .logo要好过.header .top .logo;

减少查询范围:如.header>li要好过.header li;

避免tag标签与class或id并存:如a.top、button#submit;

删除重复的CSS;

….

html:

减少DOM节点:加速页面渲染;

正确的闭合标签:如避免使用<div/>,浏览器会多一个将它解析成<div\></div\>的过程;

减少页面重绘。比如 给图片加上正确的宽高值:这可以减少页面重绘,

……

js:

尽量少用全局变量;

使用事件代理绑定事件,如将事件绑定在body上进行代理;

避免频繁操作DOM节点;

减少对象查找,如a.b.c.d这种查找方式非常耗性能,尽可能把它定义在变量里;

….

三、 z-index

说说z-index的工作原理及适用范围?

原理:

z-index 这个属性控制着元素在z轴上的表现形式。

该属性仅适用于定位元素。即拥有 relative , absolute , fixed 属性的position 元素。

堆叠顺序(Stacking Level)

堆叠顺序是当前元素位于 z 轴上的值。数值越大表明元素的堆叠顺序越高,越靠近屏幕。

未定义时 后来居上

如果未指定 z-index 的属性,元素的堆叠顺序基于它所在的文档树。默认情况下,文档中后来声明的元素具有更高的堆叠顺序

当父元素的堆叠顺序被设置的时候,这也意味着,它的子元素的堆叠顺序不能高于或低于这一顺序 (相对于父元素的堆叠上下文)。。

适用范围:

1.网页两侧浮动窗口(播放器,置顶按钮,浮动广告,功能按钮等)
2.导航栏浮动置顶。
3.隐藏div实现弹窗功能(通过设置div的定位和z-index控制div的位置和出现隐藏)

四、响应式开发

能否简述一下如何使一套设计方案,适应不同的分辨率,有哪些方法可以实现?

流式布局:

使用非固定像素来定义网页内容,也就是百分比布局,通过盒子的宽度设置成百分比来根据屏幕的宽度来进行伸缩,不受固定像素的限制,内容向两侧填充。

这样的布局方式 就是移动web开发使用的常用布局方式

这样的布局可以适配移动端不同的分辨率设备。

响应式开发:

那么Ethan Marcotte在2010年5月份提出的一个概念,简而言之,就是一个网站能够兼容多个终端。

越来越多的设计师也采用了这种设计。

• CSS3中的Media Query(媒介查询)

• 通过查询screen的宽度来指定某个宽度区间的网页布局。

• 超小屏幕(移动设备) 768px以下

• 小屏设备 768px-992px

• 中等屏幕 992px-1200px

• 宽屏设备 1200px以上

由于响应式开发显得繁琐些,一般使用第三方响应式框架来完成,比如bootstrap来完成一部分工作,当然也可以自己写响应式。

五、事件封装和自定义

如何实现事件的封装、如何实现自定义事件?

什么是事件:

JavaScript 使我们有能力创建动态页面。事件是可以被 JavaScript 侦测到的行为。

网页中的每个元素都可以产生某些可以触发 JavaScript 函数的事件。比方说,我们可以在用户点击某按钮时产生一个 onClick 事件来触发某个函数。事件在 HTML 页面中定义。

事件的封装:

function addEvent(dom,type,callback){
    if(dom.addEventListener){
        dom.addEventListener(type,callback,false);
    }else if(dom.attachEvent){
        dom.attachEvent('on'+type,callback);
    }
};
function removeEvent(dom,type,callback){
    if(dom.removeEventListener){
        dom.removeEventListener(type);
    }else if(dom.detachEvent){
        dom.detachEvent('on'+type);
    }
};

事件封装:

比如zepto中的touch事件都是自定义事件。

六、渐进坚强、优雅降级

你能描述一下渐进增强和优雅降级之间的不同吗?

优雅降级和渐进增强印象中是随着css3流出来的一个概念。由于低级浏览器不支持css3,但css3的效果又太优秀不忍放弃,所以在高级浏览中使用css3而低级浏览器只保证最基本的功能。咋一看两个概念差不多,都是在关注不同浏览器下的不同体验,关键的区别是他们所侧重的内容,以及这种不同造成的工作流程的差异。

举个例子:

a{

    display: block;

    width: 200px;

    height: 100px;

    background:aquamarine;

    /*我就是要用这个新css属性*/

    transition: all 1s ease 0s;

    /*可是发现了一些低版本浏览器不支持怎么吧*/

    /*往下兼容*/

    -webkit-transition:all 1s ease 0s;

    -moz-transition:all 1s ease 0s;

    -o-transition: all 1s ease 0s;

    /*那么通常这样考虑的和这样的侧重点出发的css就是优雅降级*/

}

a:hover{

    height: 200px;

}

/*那如果我们的产品要求我们要重低版本的浏览器兼容开始*/

a{

    /*优先考虑低版本的*/

    -webkit-transition:all 1s ease 0s;

    -moz-transition:all 1s ease 0s;

    -o-transition: all 1s ease 0s;

    /*高版本的就肯定是渐进渐强*/

    transition: all 1s ease 0s;

}

“优雅降级”观点认为应该针对那些最高级、最完善的浏览器来设计网站。

“渐进增强”观点则认为应关注于内容本身。

七、 客户端数据存储

请描述一下cookies,sessionStorage和localStorage的区别?

cookies兼容所有的浏览器,Html5提供的storage存储方式。

Document.cookie


Window.localstorage


Window.sessionstorage

cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。

存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。

数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。

作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。

八、重置浏览器的CSS默认属性

描述一个”reset”的CSS文件并如何使用它。知道normalize.css吗?你了解他们的不同之处?

因为浏览器的品种很多,每个浏览器的默认样式也是不同的,比如<button>标签,在IE浏览器、Firefox浏览器以及Safari浏览器中的样式都是不同的,所以,通过重置button标签的CSS属性,然后再将它统一定义,就可以产生相同的显示效果。

你可能会用Normalize来代替你的重置样式文件。它没有重置所有的样式风格,但仅提供了一套合理的默认样式值。既能让众多浏览器达到一致和合理,但又不扰乱其他的东西(如粗体的标题)。

九、 IE和DOM事件流的区别

首先我们得搞懂 IE和DOM 是指的啥?

这里主要问的是 你IE浏览器和DOM兼容的浏览器也就是非IE浏览器或IE的高版本浏览器的事件方面的兼容性问题。

然后要搞明白的是 什么是事件流

IE5.5顺序是div --body--document.
在IE6中div-body--html--document.
mozilla的顺序是div--body- -html--document--window.

在IE中只有冒泡事件类型的事件流。

而在DOM兼容的浏览器中还有事件捕获

首先window--document--body--div--click.
然后click--div--body--document--window.

处理函数的区别

在IE 中,每个元素和window对象都有2个方法:attachEvent()和detachEvent();attachEvent用来给一个事件附加事件处理函数.

dom中对应的方法是addEventListener()和removeEventListener ,这两个方法有3个参数,事件名称,要分配的函数和处理函数是用于冒泡阶段还是捕获阶段.如果事件处理函数是用在捕获阶段,第三个参数为true

<div>

    <a href="javascript:;">dddd</a>

</div>

<script>

    window.onload = function(){

        document.getElementsByTagName('a')[0].addEventListener('click',function(e){

            console.log('a');

        },true);

        /*处理函数在捕获阶段执行*/

       
document.getElementsByTagName('div')[0].addEventListener('click',function(e){

            console.log('div');

            /*在捕获的时候  禁止冒泡*/

            e.stopPropagation();

        },true);

        /*处理函数在捕获阶段执行*/

    }

</script>

十、 call和apply的区别

Javascript的每个Function对象中有一个apply方法:

1

function.apply([thisObj[,argArray]])

还有一个类似功能的call方法:

1

function.call([thisObj[,arg1[, arg2[, [,.argN]]]]])

它们各自的定义:

apply:应用某一对象的一个方法,用另一个对象替换当前对象。

call:调用一个对象的一个方法,以另一个对象替换当前对象。

它们的共同之处:

都“可以用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由 this 指定的新对象。”

它们的不同之处:

apply:最多只能有两个参数——新this对象和一个数组 argArray。如果给该方法传递多个参数,则把参数都写进这个数组里面,当然,即使只有一个参数,也要写进数组里面。如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。

call:则是直接的参数列表,主要用在js对象各方法互相调用的时候,使当前this实例指针保持一致,或在特殊情况下需要改变this指针。如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

更简单地说,apply和call功能一样,只是传入的参数列表形式不同:如 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3])

var func1 = function(a,b,c){

    this.name = 'func1';

    //func2.call(this,a,b,c);

    //func2.apply(this,arguments);

};

var func2 = function(){

    console.log(this.name);

    console.log(arguments);

};

func1(1,2,3);

     这次就先整理这么多了,毕竟还得劳逸结合啊,欲知更多知识,请待下次更新。