又到了金三銀四的找工做季啦 ✿✿ヽ(°▽°)ノ✿。我是一個入行一年多的前端菜鳥,去年夏天開始考慮換工做,陸續面試了幾家中小公司。面試過程我通常會錄音,方便結束後進行復盤。整理了幾回面試覆盤的筆記,但願對類似狀況的小夥伴有所幫助「😝 也是方便本身之後回憶」,願你們都能找到心儀的工做。❤️php
說明:問題末尾的數字表明對本身當時回答的打分,✔ 表明後面有關於該問題的從新整理。css
相同點:html
不一樣點:前端
level1: vue2.0中,響應式實現的核心就是 ES5的Object.defineProperty(obj, prop, descriptor). 經過Object.defineProperty()劫持data和props各個屬性的getter和setter,getter作依賴收集,setter派發更新。總體來講是一個 數據劫持 + 發佈-訂閱者模式。vue
level2: 具體來講, ① vue初始化階段(beforeCreate以後create以前),遍歷data/props,調用Object.defineProperty給每一個屬性加上getter、setter。② 每一個組件、每一個computed都會實例化一個watcher(固然也包括每一個自定義watcher),訂閱渲染/計算所用到的所用data/props/computed,一旦數據發生變化,setter被調用,會通知渲染watcher從新計算、更新組件。node
level1: props+events 父子組件通訊( children),vuex 任何組件通訊,事件中心 on 任何組件的通訊, listeners 後代通訊(provide / inject)。react
level2: vuex運行機制:vuex的state做爲一個倉庫,提供數據驅動vue component渲染。視圖經過dispach派發actions,actions中能夠作一些異步操做。actions或者視圖經過commit提交給mutations,mutation去改變state。webpack
level3: 源碼分析:vuex實際上是一個Vue.js插件,插件都須要提供一個install方法,install方法調用會將Vue做爲參數傳入。Vue.user(plugin)安裝插件,也就是執行插件的install方法。會在全局混入一個beforeCreate鉤子函數,把示例化的Store保存到全部組件的this.$store中。git
level4: mutation改變state, 會觸發視圖改變的緣由?經過vue實現的,[實例化vue,把state做爲一個data屬性。] ↔️ 核心github
let Vue
function install(_Vue) {
Vue = _Vue
function vuexInit() {
const options = this.$options
console.log('vuexInit -> this.$options', this.$options)
if (options.store) {
// // 根實例 this --> Vue
this.$store =
typeof options.store === 'function' ? options.store() : options.store
} else if (options.parent && options.parent.$store) {
// 組件實例 this --> VueComponent, 如 APP, Home, About...
this.$store = options.parent.$store
}
}
Vue.mixin({ beforeCreate: vuexInit })
}
class Store {
constructor(options = {}) {
const { state = {}, mutations = {}, getters = {} } = options
this._mutations = mutations
// getter實現原理
const computed = {}
this.getters = {}
for (let [key, fn] of Object.entries(getters)) {
computed[key] = () => fn(this.state)
Object.defineProperty(this.getters, key, {
get: () => this._vm[key]
})
}
this._vm = new Vue({
data: { $$state: state }, // 核心原理
computed
})
}
commit(type, payload) {
if (this._mutations[type]) {
this._mutations[type](this.state, payload)
}
}
get state() {
return this._vm._data.$$state
}
}
export default { Store, install }
複製代碼
level1: 推斷節點是否爲用戶可見,以及多少比例可見,交叉觀察器。web API中也有。
level2: 小程序中的IntersectionObserver在Web的基礎上,作了一些封裝,經過createIntersectionObserver返回一個IntersectionObserver實例。實例方法包括relativeTo、relativeToViewPort、observer、disconnect。relativeTo和relativeToViewPort,相對指定元素或視口的指定位置。observer(selector, cb),觀察指定節點,可見性發生變化時觸發回調。
level3: Web API, new IntersectionObserver(cb, options)。options裏root、rootMargin的配置,可實現小程序中relativeTo、relativeToViewPort方法的效果。另外 thresholds 屬性也蠻有趣的,在指定的幾個相交比例時觸發回調。
// babel.config.js配置以下:
plugins: ['equire']
// echarts.js
const echarts = equire(['line', 'tooltip', 'legend', 'dataZoom', 'grid']);
export default echarts;
複製代碼
先後端數據交換方面,推進項目組使用藍湖、接口文檔,與後端同窗協商,規範後臺數據返回。
雅虎軍規提到的,避免css表達式、濾鏡,較少DOM操做,優化圖片、精靈圖,避免圖片空連接等。
性能問題:頁面加載性能、動畫性能、操做性能。Performance API,記錄性能數據。
winter重學前端 優化技術方案:
loader
對模塊的源代碼進行轉換,將不一樣的語言轉換爲JS,或將內聯圖像轉換爲data url。如:文件,url-loader、file-loader。轉換編譯,babel-loader、ts-loader。模板,html-loader。樣式,style-loader、css-loader、less-loader。清理,eslint-loader。框架,vue-loader。
plugin
解決loader沒法實現的其餘事兒。好比 HtmlWebpackPlugin、CleanWebpackPlugin、webpack-bundle-analyzer、DllPlugin、HotModuleReplacementPlugin。
tree shaking
消除無用的js代碼(剔除模塊中沒有導出或引用的部分)。僅支持ES Module靜態引入方式,不支持require運行時動態引入方式。
ES6模塊引入是靜態分析的,故而可在編譯時正確判斷加載哪些代碼。
可剔除的內容有限。webpack配合uglifyJS打包文件,只能shaking部分代碼,像模塊代碼存在反作用,當即執行函數等都不能shaking。uglifyJS不進行程序流分析,只簡單判斷變量後續是否被引用、修改,不去排除有可能有反作用的代碼。(rollup會)還有,好比項目中router.js引用了頁面組件,可是在路由渲染中沒有用到,也沒法shaking掉。
webpack-deep-scope-analysis-plugin:利用webpack解析出來模塊的AST,利用scoped分析工具解析引用關係,排除掉沒有用到的模塊。
1. babel.config.js 配置,分析文件模塊依賴關係,生成AST時,保持ES6不動。
{
"presets": [ ["env", { "modules": false }] ]
}
2. 方式1,import {Button} from 'antd';
方式2,import {Buttion} from 'antd/lib/button';
import 'antd/lib/style';
這兩種方式,tree-shaking效果差異很大。(反作用範圍不一樣)
babel-plugin-import-fix 插件,遍歷AST找出相似import {Button} from 'antd'的結構,進行轉換從新生成代碼。
3. CSS tree-shaking <https://juejin.cn/post/6844903808397475847>
方式1:mini-css-extract-plugin + purifycss-webpack
方式2:webpack-css-treeshaking-plugin。
利用postCSS提供的解析器,將CSS解析成AST,遍歷獲取選擇器與js、html代碼匹配,刪除匹配不到的,返回AST,從新生成代碼。
複製代碼
考點,vue-router實現原理。
level1:
level2: 實現的三種方式,location.hash + hashChange(),HTML5規範的pushState(IE10) + popState事件監聽,abstract nodejs默認值。
**level3:**源碼分析。路由安裝,利用mixin給每一個組件注入beforeCreated和destory鉤子函數,在Vue原型上定義 router,並進行響應式處理,定義全局的roter-link和router-view組件。根據路由配置建立映射關係。根據傳入路徑計算出新的路徑,在路勁切換過程當中,執行一系列的導航守衛函數,更改Url,渲染對應組件。
html文件也會緩存。項目中使用index.php,後端返回html內容,不會被緩存。
瀏覽器緩存策略:
強制緩存:(在指定時間內,瀏覽器直接使用強緩存的內容)
Expires:Thu.21 Jan 2019 23:59:59 GMT; (HTTP1.0)
Cache-Control:max-age=3600(HTTP1.1,優先級更高)
【緩存指令:no-cache須要協商緩存來驗證是否過時;no-store不緩存;public客戶端代理服務器均可以緩存;private客戶端可緩存】
協商緩存:(與服務器協商,肯定資源是否更新)
Last-Modified(服務器下發時間):Thu.21 Jan 2018 23:59:59 GMT;(HTTP1.0)
If-Modified-Since(瀏覽器詢問) 【可能時間變了,內容沒變】
Etag(服務器下發); (HTTP1.1)
If-None-Match(瀏覽器詢問)
CDN,內容分發網絡,是創建再承載網基礎上的虛擬分佈式網絡,可以將源站內容緩存到全國或全球的節點服務器上。用戶就近獲取內容,提升了資源的訪問速度,分擔源站壓力。
使用DNS域名解析引導用戶來訪問cache服務器。
封裝IM類,在IM類上定義建立SDK實例,登陸/退出,羣組加入/退出,IM事件監聽和移除。
sentry錯誤日誌經過https發送到sentry的web站點。使用cors實現跨域。
**request headers:**
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross site
**response headers:**
access-control-allow-origin: <http://localhost:8080>
access-control-expose-headers: x-sentry-error, retry-after, x-sentry-rate-limits
複製代碼