1. 谈谈你对 webpack 的看法(webpack 的特点)
答案:WebPack 是一个模块打包工具,你可以使用 WebPack 管理你的模块依赖,并编绎输出模块们所需的静态文件。它能够很好地管理、打包 Web 开发中所用到的 HTML、JavaScript、CSS 以及各种静态文件(图片、字体等),让开发过程更加高效。对于不同类型的资源,webpack 有对应的模块加载器。webpack 模块打包器会分析模块间的依赖关系,最后 生成了优化且合并后的静态资源。
webpack 的两大特色:
- code splitting(可以自动完成)
- loader 可以处理各种类型的静态文件,并且支持串联操作
webpack 是以 commonJS 的形式来书写脚本滴,但对 AMD/CMD 的支持也很全面,方便旧项目进行代码迁移。
webpack 具有 requireJs 和 browserify 的功能,但仍有很多自己的新特性:
- 对 CommonJS 、 AMD 、ES6 的语法做了兼容
- 对 js、css、图片等资源文件都支持打包
- 串联式模块加载器以及插件机制,让其具有更好的灵活性和扩展性,例如提供对 CoffeeScript、ES6 的支持
- 有独立的配置文件 webpack.config.js
- 可以将代码切割成不同的 chunk,实现按需加载,降低了初始化时间
- 支持 SourceUrls 和 SourceMaps,易于调试
- 具有强大的 Plugin 接口,大多是内部插件,使用起来比较灵活
- webpack 使用异步 IO 并具有多级缓存。这使得 webpack 很快且在增量编译上更加快
3.webpack plugin/loader 的区别
答案:
const webpack = require("webpack");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 入口文件
entry: {
app: path.join(__dirname, "../src/js/index.js")
},
// 输出文件
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
publicPath: "/"
},
// loader配置
module: {
rules: [
{
test: /\.scss/,
use: [
"style-loader",
"css-loader"
]
}
......
]
},
// plugins配置
plugins: [
// 重新创建html文件
new HtmlWebpackPlugin({
title: "首页",
filename: "index.html",
template: path.resolve(__dirname, "../src/index.html")
})
......
]
}
- 识别入口文件
- 通过逐层识别模块依赖(Commonjs、amd或者es6的import,webpack都会对其进行分析,来获取代码的依赖)
- webpack做的就是分析代码,转换代码,编译代码,输出代码
- 最终形成打包后的代码
loader是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中
- 处理一个文件可以使用多个loader,loader的执行顺序和配置中的顺序是相反的,即最后一个loader最先执行,第一个loader最后执行
- 第一个执行的loader接收源文件内容作为参数,其它loader接收前一个执行的loader的返回值作为参数,最后执行的loader会返回此模块的JavaScript源码
在webpack运行的生命周期中会广播出许多事件,plugin可以监听这些事件,在合适的时机通过webpack提供的API改变输出结果。
对于loader,它是一个转换器,将A文件进行编译形成B文件,这里操作的是文件,比如将A.scss转换为A.css,单纯的文件转换过程
plugin是一个扩展器,它丰富了webpack本身,针对是loader结束后,webpack打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听webpack打包过程中的某些节点,执行广泛的任务
class MyPlugin{
constructor(options){
console.log("MyPlugin constructor:", options);
}
apply(compiler){
compiler.plugin("compilation", compilation => {
console.log("MyPlugin");
});
}
}
module.exports = MyPlugin;
webpack.config.js配置:
module.exports = {
...
plugins: [
new MyPlugin({param: "my plugin"})
]
}
使用该plugin后,执行的顺序:
- webpack启动后,在读取配置的过程中会执行new MyPlugin(options)初始化一个MyPlugin获取其实例
- 在初始化compiler对象后,就会通过compiler.plugin(事件名称,回调函数)监听到webpack广播出来的事件
- 并且可以通过compiler对象去操作webpack
8.网站性能优化
答案:
样本一
- 减少 http 请求次数:CSS Sprites, JS、CSS 源码压缩、图片大小控制合适;网页 Gzip,CDN 托管,data 缓存 ,图片服务器。
- 前端模板 JS+数据,减少由于 HTML 标签导致的带宽浪费,前端用变量保存 AJAX 请求结果,每次操作本地变量,不用请求,减少请求次数
- 用 innerHTML 代替 DOM 操作,减少 DOM 操作次数,优化 javascript 性能。
- 当需要设置的样式很多时设置 className 而不是直接操作 style。
- 少用全局变量、缓存 DOM 节点查找的结果。减少 IO 读取操作。
- 避免使用 CSS Expression(css 表达式)又称 Dynamic properties(动态属性)。
- 图片预加载,将样式表放在顶部,将脚本放在底部 加上时间戳。
- 避免在页面的主体布局中使用 table,table 要等其中的内容完全下载之后才会显示出来,显示比 div+css 布局慢。
样本二
- 减少 HTTP 请求
- 减少 DOM 操作
- 避免不必要的重绘与重排
- 优化 CSS 选择器(从右向左匹配)
- CSS/JS minify,减少文件体积
- 开启 Gzip 压缩
- 将 CSS 放到顶部,JavaScript 放到尾部
- 压缩图片以及使用 CSS Sprite
- 使用 CDN 加速,适当进行文件缓存
- 合理控制 cookie 大小(每次请求都会包含 cookie)
14.平时如何管理你的项目?
答案:
a. 先期团队必须确定好全局样式(globe.css),编码模式(utf-8) 等;
b. 编写习惯必须一致(例如都是采用继承式的写法,单样式都写成一行);
c. 标注样式编写人,各模块都及时标注(标注关键样式调用的地方);
d. 页面进行标注(例如 页面 模块 开始和结束);
e. CSS 跟 HTML 分文件夹并行存放,命名都得统一(例如 style.css);
f. JS 分文件夹存放 命名以该 JS 功能为准的英文翻译。
g. 图片采用整合的 images.png png8 格式文件使用 尽量整合在一起使用方便将来的管理
18.模块化开发怎么做?
答案:
-
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。
-
CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。
-
AMD 是提前执行,CMD 是延迟执行。
-
AMD 推荐的风格通过返回一个对象做为模块对象,CommonJS 的风格通过对 module.exports 或 exports 的属性赋值来达到暴露模块对象的目的。
CMD 模块方式
define(function(require, exports, module) {
// 模块代码
});
23.首屏、白屏时间如何计算?
答案:
Performance 接口可以获取到当前页面中与性能相关的信息。
该类型的对象可以通过调用只读属性 Window.performance 来获得。
白屏时间:
performance.timing.responseStart - performance.timing.navigationStart
首屏时间
window.onload = () => {
new Date() - performance.timing.responseStart
}
解析:参考
44.WEB 应用从服务器主动推送 Data 到客户端有那些方式?
答案:
- html5 websoket
- WebSocket 通过 Flash
- XHR 长时间连接
- XHR Multipart Streaming
- 不可见的 Iframe
<script>
标签的长时间连接(可跨域)
45.模块化怎么做?
答案:
立即执行函数,不暴露私有成员
var module1 = (function() {
var _count = 0;
var m1 = function() {
//...
};
var m2 = function() {
//...
};
return {
m1: m1,
m2: m2
};
})();
46.简述一下你对 web 性能优化的方案
答案:
1、尽量减少 HTTP 请求 2、使用浏览器缓存 3、使用压缩组件 4、图片、JS 的预载入 5、将脚本放在底部 6、将样式文件放在页面顶部 7、使用外部的 JS 和 CSS 8、精简代码
47.移动端性能优化
答案:
尽量使用 css3 动画,开启硬件加速。适当使用 touch 事件代替 click 事件。避免使用 css3 渐变阴影效果。 尽可能少的使用 box-shadow 与 gradients。box-shadow 与 gradients 往往都是页面的性能杀手
52.Ascii、GBK、UTF、Unicode
答案:
- Ascii(1 个字节 1 个字符)
- GBK 是国内的编码标准(汉字 2 个字节)
- Unicode 是国际编码标准(统一 2 个字节表示一个字符)
- UTF 是 Unicode 实现的另一个标准
unicode 同样也不完美,这里就有两个的问题,一个是,如何才能区别 unicode 和 ascii?
由于”半角”英文符号只需要用到低 8 位,所以其高 8 位永远是 0,因此这种大气的方案在保存英文文本时会多浪费一倍的空间
unicode 在很长一段时间内无法推广,直到互联网的出现,为解决 unicode 如何在网络上传输的问题,于是面向传输的众多 UTF(UCS Transfer Format)标准出现了,顾名思义,UTF-8 就是每次 8 个位传输数据,而 UTF-16 就是每次 16 个位。UTF-8 就是在互联网上使用最广的一种 unicode 的实现方式,这是为传输而设计的编码,并使编码无国界,这样就可以显示全世界上所有文化的字符了。UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用 1~4 个字节表示一个符号,根据不同的符号而变化字节长度,当字符在 ASCII 码的范围时,就用一个字节表示,保留了 ASCII 字符一个字节的编码做为它的一部分,注意的是 unicode 一个中文字符占 2 个字节,而 UTF-8 一个中文字符占 3 个字节)。从 unicode 到 utf-8 并不是直接的对应,而是要过一些算法和规则来转换。
解析:参考
53. 页面大量图片,如何优化加载,优化用户体验
答案:
图片懒加载,在页面上的未可视区域可以添加一个滚动条事件,判断图片位置与浏览器顶端的距离与页面的距离,如果前者小于后者,优先加载。
如果为幻灯片、相册等,可以使用图片预加载技术,将当前展示图片的前一张和后一张优先下载。
如果图片为 css 图片,可以使用 CSSsprite,SVGsprite,Iconfont、Base64 等技术。
如果图片过大,可以使用特殊编码的图片,加载时会先加载一张压缩的特别厉害的缩略图,以提高用户体验。
如果图片展示区域小于图片的真实大小,则因在服务器端根据业务需要先行进行图片压缩,图片压缩后大小与展示一致。
解析:参考
54.渲染优化
答案:
1、禁止使用 iframe(阻塞父文档 onload 事件);
*iframe 会阻塞主页面的 Onload 事件;
*搜索引擎的检索程序无法解读这种页面,不利于 SEO;
*iframe 和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。
使用 iframe 之前需要考虑这两个缺点。如果需要使用 iframe,最好是通过 javascript
动态给 iframe 添加 src 属性值,这样可以绕开以上两个问题。
2、禁止使用 gif 图片实现 loading 效果(降低 CPU 消耗,提升渲染性能);
3、使用 CSS3 代码代替 JS 动画(尽可能避免重绘重排以及回流)css3 平面动画开启 translateZ(0),打开浏览器 3d 加速,在一定程度可缓解卡顿。不宜多用;
4、对于一些小图标,可以使用 base64 位编码,以减少网络请求。但不建议大图使用,比较耗费 CPU;
小图标优势在于: 1.减少 HTTP 请求; 2.避免文件跨域; 3.修改及时生效;
5、页面头部的`<style></style>` 会阻塞页面;(因为 Renderer 进程中 JS 线程和渲染线程是互斥的);
6、页面头部`<script</script>` 会阻塞页面;(因为 Renderer 进程中 JS 线程和渲染线程是互斥的);
7、页面中空的 href 和 src 会阻塞页面其他资源的加载 (阻塞下载进程);
8、网页 Gzip,CDN 托管,data 缓存 ,图片服务器;
9、前端模板 JS+数据,减少由于 HTML 标签导致的带宽浪费,前端用变量保存 AJAX 请求结果,每次操作本地变量,不用请求,减少请求次数
10、用 innerHTML 代替 DOM 操作,减少 DOM 操作次数,优化 javascript 性能。
11、当需要设置的样式很多时设置 className 而不是直接操作 style。
12、少用全局变量、缓存 DOM 节点查找的结果。减少 IO 读取操作。
13、避免使用 CSS Expression(css 表达式)又称 Dynamic properties(动态属性)。
14、图片预加载,将样式表放在顶部,将脚本放在底部 加上时间戳。
15、 避免在页面的主体布局中使用 table,table 要等其中的内容完全下载之后才会显示出来,显示比 div+css 布局慢。
对普通的网站有一个统一的思路,就是尽量向前端优化、减少数据库操作、减少磁盘 IO。
向前端优化指的是,在不影响功能和体验的情况下,能在浏览器执行的不要在服务端执行,
能在缓存服务器上直接返回的不要到应用服务器,程序能直接取得的结果不要到外部取得,
本机内能取得的数据不要到远程取,内存能取到的不要到磁盘取,缓存中有的不要去数据库查询。
减少数据库操作指减少更新次数、缓存结果减少查询次数、将数据库执行的操作尽可能的让你的程序完成(例如 join 查询),
减少磁盘 IO 指尽量不使用文件系统作为缓存、减少读写文件次数等。程序优化永远要优化慢的部分,换语言是无法“优化”的。
16、通过改变 src 的情况下\*\*.MP3(不同于 mp3)在移动端有可能不能播放。
55.什么是“前端路由"?什么时候适合使用“前端路由"? “前端路由"有哪些优点和缺点?
答案:
-
什么是前端路由?
路由是根据不同的 url 地址展示不同的内容或页面
前端路由就是把不同路由对应不同的内容或页面的任务交给前端来做,之前是通过服务端根据 url 的不同返回不同的页面实现的。
-
什么时候使用前端路由?
在单页面应用,大部分页面结构不变,只改变部分内容的使用
-
前端路由有什么优点和缺点?
优点
用户体验好,不需要每次都从服务器全部获取,快速展现给用户
缺点
使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存
单页面无法记住之前滚动的位置,无法在前进,后退的时候记住滚动的位置
56.前端项目监控怎么做的
答案:
57.前后端分离的项目如何seo
答案:
58.怎么判断页面是否加载完成?
答案:
59.垃圾回收 新生代算法,老生代算法
答案:
60.介绍MVP怎么组织(宝宝树)
答案:
61.如何实现骨架屏,说说你的思路
答案:
62.如何在 H5 和小程序项目中计算白屏时间和首屏时间,说说你的思路
答案:
63.前端项目如何找出性能瓶颈(阿里)
答案:
63.为什么通常在发送数据埋点请求的时候使用的是 1x1 像素的透明 gif 图片?
答案:
64.介绍下 npm 模块安装机制,为什么输入 npm install 就可以自动安装对应的模块?
答案:
65.观察者和订阅-发布的区别,各自用在哪里(网易)
答案:
66.文件上传如何做断点续传(网易)
答案:
67.npm2和npm3 有什么区别(宝宝树)
答案:
68.移动端如何设计一个比较友好的Header组件?(携程)
答案:
答案:
答案:
答案: