标签:rod 文件的 不可 dirname 箭头 负载 括号 外部 重载
针对面试中出镜率比较高的重难点知识梳理。
本篇为系列文章:
基本语法:
module.exports = value
或exports.xxx = value
require(xxx)
,如果是第三方模块,xxx为模块名;如果是自定义模块,xxx为模块文件路径加载某个模块,其实是加载该模块的module.exports属性。 require命令用于加载模块文件。require命令的基本功能是,读入并执行一个JavaScript文件,然后返回该模块的exports对象。如果没有发现指定模块,会报错。 CommonJS模块的加载机制是,输入的是被输出的值的拷贝。也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。这点与ES6模块化有重大差异。
export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。
/** 定义模块 math.js **/
var basicNum = 0;
var add = function (a, b) {
return a + b;
};
export { basicNum, add };
/** 引用模块 **/
import { basicNum, add } from ‘./math‘;
function test(ele) {
ele.textContent = add(99 + basicNum);
}
也可以用 export default
// export-default.js
export default function () {
console.log(‘foo‘);
}
// import-default.js
import customName from ‘./export-default‘;
customName(); // ‘foo‘
它们有两个重大差异:
添加 header
//创建 axios 实例
let instance = axios.create({timeout: 1000 * 12});
//设置post请求头
instance.defaults.headers.post[‘Content-Type‘] = ‘application/x-www-form-urlencoded‘;
instance.defaults.withCredentials=true; //让ajax携带cookie
在 api 方法中添加 header
postJson(url, params) {
return axios.post(`${base}${url}`, params, {
headers: {‘content-type‘: ‘application/json;charset=UTF-8‘}
})
},
//基本的get方法
get(url, params) {
return axios.get(`${base}${url}`, {params: params})
},
//基本的post方法
post(url, params) {
return axios.post(`${base}${url}`, JSON.stringify(params))
},
性能优化几乎是必问的,最好把下面五种方式都说出来。
第二、三点会延伸了问,小括号里是一般延伸的方向。详细的解释参见 十二、页面性能
目标:加快界面展示速度,减少数据请求次数。
提升页面性能的方法有哪些?
//强制打开 <a> 标签的 dns 解析
<meta http-equiv="x-dns-prefetch-controller" content="on">
//DNS预解析
<link rel="dns-prefetch" href="//host_name_to_prefetch.com">
缓存策略的分类:
缓存策略都是通过设置 HTTP Header 来实现的。 浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识。 浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中。
强缓存:不会向服务器发送请求,直接从缓存中读取资源,在chrome控制台的Network选项中可以看到该请求返回200的状态码,并且Size显示from disk cache或from memory cache。强缓存可以通过设置两种 HTTP Header 实现:Expires 和 Cache-Control。
缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点。也就是说,Expires=max-age + 请求时间,需要和Last-modified结合使用。Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。 Expires 是 HTTP/1 的产物,受限于本地时间,如果修改了本地时间,可能会造成缓存失效。Expires: Wed, 22 Oct 2018 08:41:00 GMT
表示资源会在 Wed, 22 Oct 2018 08:41:00 GMT 后过期,需要再次请求。
在HTTP/1.1中,Cache-Control是最重要的规则,主要用于控制网页缓存。比如当Cache-Control:max-age=300
时,则代表在这个请求正确返回时间(浏览器也会记录下来)的5分钟内再次加载资源,就会命中强缓存。 Cache-Control 可以在请求头或者响应头中设置,并且可以组合使用多种指令:
其实这两者差别不大,区别就在于 Expires 是http1.0的产物,Cache-Control是http1.1的产物,两者同时存在的话,Cache-Control优先级高于Expires;在某些不支持HTTP1.1的环境下,Expires就会发挥用处。所以Expires其实是过时的产物,现阶段它的存在只是一种兼容性的写法。 强缓存判断是否缓存的依据来自于是否超出某个时间或者某个时间段,而不关心服务器端文件是否已经更新,这可能会导致加载文件不是服务器端最新的内容,那我们如何获知服务器端内容是否已经发生了更新呢?此时我们需要用到协商缓存策略。
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程,主要有以下两种情况:
协商缓存可以通过设置两种 HTTP Header 实现:Last-Modified 和 ETag 。
浏览器在第一次访问资源时,服务器返回资源的同时,在response header中添加 Last-Modified 的header,值是这个资源在服务器上的最后修改时间,浏览器接收后缓存文件和 header;
Last-Modified: Fri, 22 Jul 2016 01:47:00 GMT
浏览器下一次请求这个资源,浏览器检测到有 Last-Modified这个header,于是添加If-Modified-Since这个header,值就是Last-Modified中的值;服务器再次收到这个资源请求,会根据 If-Modified-Since 中的值与服务器中这个资源的最后修改时间对比,如果没有变化,返回304和空的响应体,直接从缓存读取,如果If-Modified-Since的时间小于服务器中这个资源的最后修改时间,说明文件有更新,于是返回新的资源文件和200。 但是 Last-Modified 存在一些弊端:
既然根据文件修改时间来决定是否缓存尚有不足,能否可以直接根据文件内容是否修改来决定缓存策略?所以在 HTTP / 1.1 出现了 ETag
和If-None-Match
Etag 是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成),只要资源有变化,Etag就会重新生成。浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到request header里的If-None-Match里,服务器只需要比较客户端传来的If-None-Match跟自己服务器上该资源的ETag是否一致,就能很好地判断资源相对客户端而言是否被修改过了。如果服务器发现ETag匹配不上,那么直接以常规GET 200回包形式将新的资源(当然也包括了新的ETag)发给客户端;如果ETag是一致的,则直接返回304知会客户端直接使用本地缓存即可。
Last-Modified的时间单位是秒,如果某个文件在1秒内改变了多次,那么他们的Last-Modified其实并没有体 现出来修改,但是Etag每次都会改变确保了精度;如果是负载均衡的服务器,各个服务器生成的Last- Modified也有可能不一致。
强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match),协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,返回200,重新返回资源和缓存标识,再存入浏览器缓存中;生效则返回304,继续使用缓存。
强缓存与协商缓存的区别可以用下表来表示:
缓存类型 | 获取资源形式 | 状态码 | 发送请求到服务器 |
---|---|---|---|
强缓存 | 从缓存取 | 200(from cache) | 否,直接从缓存取 |
协商缓存 | 从缓存取 | 304(Not Modified) | 是,通过服务器来告知缓存是否可用 |
用户行为对缓存的影响
用户操作 | Expires/Cache-Control | Last-Modied/Etag | |
---|---|---|---|
地址栏回车 | 有效 | 有效 | |
页面链接跳转 | 有效 | 有效 | |
新开窗口 | 有效 | 有效 | |
前进回退 | 有效 | 有效 | |
F5刷新 | 无效 | 有效 | |
Ctrl+F5强制刷新 | 无效 | 无效 |
在chrome浏览器中的控制台Network中size栏通常会有三种状态
三种的区别:
状态 | 类型 | 说明 |
---|---|---|
200 | form memory cache | 不请求网络资源,资源在内存当中,一般脚本、字体、图片会存在内存当中。 |
200 | form disk ceche | 不请求网络资源,在磁盘当中,一般非脚本会存在内存当中,如css等。 |
200 | 资源大小数值 | 资源大小数值 从服务器下载最新资源。 |
304 | 报文大小 | 请求服务端发现资源没有更新,使用本地资源,即命中协商缓存。 |
面试高级前端开发的话肯定会问 webpack,稍微准备一下总比啥都不知道强
webpack 的默认配置文件是 webpack.config.js
。
webpack 默认只能处理 js 文件,如果想处理图片等其他文件,则需要用到相应的 loader。比如 file-loader
、 url-loader
、 css-loader
、 style-loader
,如果用 sass 的话会用到 sass-loader
。
其他几个重要的概念是:
[name]
表示。配置方法
const path = require(‘path‘);
const HtmlWebpackPlugin = require(‘html-webpack-plugin‘);
const {CleanWebpackPlugin} = require(‘clean-webpack-plugin‘);
//添加这行
const webpack = require(‘webpack‘);
module.exports = {
mode: ‘development‘,
devtool: ‘cheap-module-eval-source-map‘,
entry: {
main: ‘./src/index.js‘,
},
output: {
filename: ‘[name].js‘,
path: path.resolve(__dirname, ‘dist‘)
},
devServer: {
contentBase: ‘./dist‘,
open: true,
port: 9090,
//添加下面两行
hot: true,
hotOnly: true
},
plugins: [
new HtmlWebpackPlugin({
template: "src/index.html"
}),
new CleanWebpackPlugin(),
//添加这行
new webpack.HotModuleReplacementPlugin(),
],
module: {
rules: [
{
test: /\.(png|jpg|gif|jpeg)/,
use: {
loader: ‘file-loader‘,
options: {
name: ‘[name]_[hash].[ext]‘,
outputPath: ‘images/‘
}
}
}, {
test: /\.(eot|woff|svg|ttf)/,
use: {
loader: ‘file-loader‘,
}
}, {
test: /\.(css|scss)/,
use: [
‘style-loader‘,
{
loader: ‘css-loader‘,
options: {
importLoaders: 2,
// modules: true
}
},
‘sass-loader‘,
‘postcss-loader‘
]
}
]
}
}
CSS热重载 style-loader 和 css-loader 已经帮我们实现了。
JS热重载
//判断是否开启了热更新
if (module.hot){
//监听 hotTest.js 文件,当文件有变动时执行箭头函数里的方法
module.hot.accept(‘./hotTest.js‘, () => {
//文件变动时执行的操作
hotTest();
})
}
目前最成熟的JavaScript代码压缩工具是UglifyJS,它会分析JavaScript代码语法树,理解代码含义,从而能做到诸如去掉无效代码、去掉日志输出代码、缩短变量名等优化。
要在Webpack中接入UglifyJS需要通过插件的形式,目前有两个成熟的插件,分别是:
压缩图片使用 image-webpack-loader
开启 gzip 也可显著压缩大小。
好了,今天先分享这么多,更多内容下期分享。
进大厂没有想象的那么难,关键还是技术。
机会是留给有准备的人,了解岗位要求后,早准备,做足准备,可以少走弯路,网上各种面经笔经,学习课程应有尽有。
下面分享给大家一份我整理的《前端开发工程师必备资料包》。
269页前端大厂面试宝典
前端面试题汇总
JavaScript
性能
linux
jQurey
小程序相关
前端资料汇总
无论做什么,不止前端,都应该要有自己的想法和思考,这样子才能把事情做好,做得更深。否则这就像一场梦,醒来还是很感动。希望各位读者,看上面的题目并不是背答案,而是理解它,并能活用,以后做类似的事情,有参考的思路。如果遇到和我同一个面试官,题目当然是不完全一样的,此时需要临场发挥自己的积累和灵活运用了。
最后再补充一点,如果你见过了普遍情况,了解到了普遍现象,那要是什么都和人家一样,最后不就是也成为普遍水平了吗?如果想脱离当前现状,实现突破,那么目标应该是成为有个性、有特色的、有区分度的人,成为一名不一样的前端,不一样的人。
标签:rod 文件的 不可 dirname 箭头 负载 括号 外部 重载
原文地址:https://www.cnblogs.com/qianduanpiaoge/p/14876539.html