2019前端面試題-框架、架構篇

yarn和npm的區別

yarn的優勢:html

  • 速度快
    • 並行安裝
    • 離線模式
  • 安裝版本統一
  • 更簡潔的輸出
  • 多註冊來源處理
  • 更好的語義化

zhuanlan.zhihu.com/p/27449990vue

yarn.lock

yarn.lock 會記錄你安裝的全部大大小小的軟件包的具體版本號。只要你不刪除 yarn.lock 文件,再次運行 yarn install 時,會根據其中記錄的版本號獲取全部依賴包。你能夠把 yarn.lock 提交到版本庫裏,這樣其餘同事簽出代碼並運行 yarn install 時,能夠保證你們安裝的依賴都是徹底一致的。react

Virtual DOM 真的比操做原生 DOM 快嗎?談談你的想法

虛擬 DOM 就是用來模擬 DOM 的一個對象,這個對象擁有一些重要屬性,而且更新 UI 主要就是經過對比(DIFF)舊的虛擬 DOM 樹 和新的虛擬 DOM 樹的區別完成的。webpack

  • innerHTML vs. Virtual DOM 的重繪性能消耗:

innerHTML: render html string O(template size) + 從新建立全部 DOM 元素 O(DOM size)web

Virtual DOM: render Virtual DOM + diff O(template size) + 必要的 DOM 更新 O(DOM change)ajax

Virtual DOM render + diff 顯然比渲染 html 字符串要慢,可是!它依然是純 js 層面的計算,比起後面的 DOM 操做來講,依然便宜了太多。能夠看到,innerHTML 的總計算量不論是 js 計算仍是 DOM 操做都是和整個界面的大小相關,但 Virtual DOM 的計算量裏面,只有 js 計算和界面大小相關,DOM 操做是和數據的變更量相關的。前面說了,和 DOM 操做比起來,js 計算是極其便宜的。這纔是爲何要有 Virtual DOM:它保證了 1)無論你的數據變化多少,每次重繪的性能均可以接受;2) 你依然能夠用相似 innerHTML 的思路去寫你的應用。算法

Virtual DOM 爲了提高小量數據更新時的性能,也須要針對性的優化,好比 shouldComponentUpdate 或是 immutable datanpm

Virtual DOM 真正的價值歷來都不是性能,而是它 1) 爲函數式的 UI 編程方式打開了大門;2) 能夠渲染到 DOM 之外的 backend,好比 ReactNative。編程

www.zhihu.com/question/31…redux

使用react的好處

  • 虛擬DOM,提高性能
  • 組件化
  • 單向數據流(數據流更清晰,組件的狀態就更可控;)

redux與缺陷

redux設計有如下幾個要點:

  • state是單例模式且不可變的,單例模式避免了不一樣store之間的數據交換的複雜性,而不可變數據提供了十分快捷的撤銷重作、「時光旅行」等功能。
  • state只能經過reducer來更新,不能夠直接修改。
  • reducer必須是純函數,形如(state,action) => newState

react-redux主要包含兩個部分。

  • Provider組件:能夠將store注入到子組件的cotext中,因此通常放在應用的最頂層。
  • connect函數: 返回一個高階函數,把context中由Provider注入的store取出來而後經過props傳遞到子組件中,這樣子組件就能順利獲取到store了。

缺點

  • 1.樣板代碼過多:
  • 2.更新效率問題:因爲使用不可變數據模式,每次更新state都須要拷貝一份完整的state形成了內存的浪費以及性能的損耗。 (用immutable解決)
  • 3.數據傳遞效率問題:因爲react-redux採用的舊版context API,context的傳遞存在着效率問題。

react hook

Hook 提供了更直接的 API:props, state,context,refs 以及生命週期

useState 會返回一對值:當前狀態和一個讓你更新它的函數

const [count, setCount] = useState(0);

useEffect 它跟 class 組件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具備相同的用途,只不過被合併成了一個 API。

// 至關於 componentDidMount 和 componentDidUpdate:
  useEffect(() => {
    // 使用瀏覽器的 API 更新頁面標題
    document.title = `You clicked ${count} times`;
  });
複製代碼

useEffect 能夠在組件渲染後實現各類不一樣的反作用。有些反作用可能須要清除,因此須要返回一個函數:

useEffect(() => {
  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }

  ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
  <!--返回-->
  return () => {
    ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
  };
});
複製代碼

規則

  • 只在最頂層使用 Hook
  • 只在 React 函數中調用 Hook

react 性能優化

  • 使用生產版本
  • webpack打包
  • showComponentUpdate
  • 使用immutable數據

react的組件生命週期

簡版

詳細版

掛載

當組件實例被建立並插入 DOM 中時,其生命週期調用順序以下:

constructor()

static getDerivedStateFromProps()

render()

componentDidMount()

更新

當組件的 props 或 state 發生變化時會觸發更新。組件更新的生命週期調用順序以下:

static getDerivedStateFromProps()

shouldComponentUpdate()

render()

getSnapshotBeforeUpdate()

componentDidUpdate()

若是 shouldComponentUpdate() 返回 false,則不會調用 render()。

卸載

componentWillUnmount()

錯誤處理

當渲染過程,生命週期,或子組件的構造函數中拋出錯誤時,會調用以下方法:

static getDerivedStateFromError() componentDidCatch()

getDerivedStateFormProps

取代componentWillReceiveProps()。這個鉤子是從props去取到state的值。

getSnapshotBeforeUpdate(prevProps,prevState)

getSnapshotBeforeUpdate() 在最近一次渲染輸出(提交到 DOM 節點)以前調用。它使得組件能在發生更改以前從 DOM 中捕獲一些信息(例如,滾動位置)。今生命週期的任何返回值將做爲參數傳遞給 componentDidUpdate()。

此用法並不常見,但它可能出如今 UI 處理中,如須要以特殊方式處理滾動位置的聊天線程等。

應返回 snapshot 的值(或 null)。

constructor()

  • state值初始化
  • super(props)不然會報錯
  • 爲事件綁定實例

react diff

React 經過制定大膽的 diff 策略,將 O(n3) 複雜度的問題轉換成 O(n) 複雜度的問題;

  • DOM 節點跨層級的移動操做特別少
  • 相同類的組件生成類似的樹形結構,不一樣類的組件生成不一樣的樹形結構
  • 同一層級的一組子節點,能夠用惟一id區分 tree diff component diff element diff

React 經過分層求異的策略,對 tree diff 進行算法優化;

React 經過相同類生成類似樹形結構,不一樣類生成不一樣樹形結構的策略,對 component diff 進行算法優化;

React 經過設置惟一 key的策略,對 element diff 進行算法優化;

建議,在開發組件時,保持穩定的 DOM 結構會有助於性能的提高;

建議,在開發過程當中,儘可能減小相似將最後一個節點移動到列表首部的操做,當節點數量過大或更新操做過於頻繁時,在必定程度上會影響 React 的渲染性能。 zhuanlan.zhihu.com/p/2034637

用webpack實現按需加載

在AntDesign出品的babel-plugin-import 安裝以上插件後,在.babelrc

react和Vue的區別

  • react是單向數據流,vue是雙向數據流
  • 在 React 應用中,當某個組件的狀態發生變化時,它會以該組件爲根,從新渲染整個組件子樹。在 Vue 應用中,組件的依賴是在渲染過程當中自動追蹤的,因此係統能精確知曉哪一個組件確實須要被重渲染。

服務端渲染,就next.js

服務端渲染:渲染過程在服務器端完成,最終的渲染結果 HTML 頁面經過 HTTP 協議發送給客戶端。對於客戶端而言,只是看到了最終的 HTML 頁面,看不到數據,也看不到模板。

  • 優勢
    • 是容易 SEO,首屏加載快,由於客戶端接收到的是完整的 HTML 頁面 -缺點
    • 耗費後端資源。費流量,即便局部頁面的變化也須要從新發送整個頁

客戶端渲染:服務器端把模板和數據發送給客戶端,渲染過程在客戶端完成。

  • 優勢
    • 節省後端資源,局部刷新頁面,多端渲染,先後端分離
  • 缺點
    • 首屏性能差,白屏,沒法(或很難)進行 SEO

服務端渲染的優勢就是客戶端渲染的缺點,服務端渲染的缺點同時也是客戶端渲染的優勢,反之亦然

Next.js 作的是同構渲染。同一套代碼既能夠在服務器端渲染,也能夠在客戶端渲染。Exciting當咱們首次訪問時,換言之當咱們訪問首屏頁面時,Next.js 使用服務器端渲染,爲咱們返回已經渲染完成的最終 HTML 頁面。這樣就同時解決了首屏白屏問題以及 SEO 問題。此後當咱們再進行交互時,則使用客戶端渲染。HTML、CSS、JS 等資源都不須要再從新請求,只須要經過 ajax/websocket 等途徑獲取數據,在客戶端完成渲染過程。

context

Context 設計目的是爲了共享那些對於一個組件樹而言是「全局」的數據,例如當前認證的用戶、主題或首選語言。Context提供了一個無需爲每層組件手動添加props,就能在組件樹間進行數據傳遞的方法。

  • provider,props的生產者
  • consumers, 消費prover提供的value
const ThemeContext = React.createContext('light');  //建立context,設置默認值
複製代碼

react-router 裏的 <Link> 標籤和 <a> 標籤有什麼區別

的「跳轉」行爲只會觸發相匹配的 對應的頁面內容更新,而不會刷新整個頁面。 而 標籤就是普通的超連接了,用於從當前頁面跳轉到 href 指向的另外一個頁面(非錨點狀況)。
相關文章
相關標籤/搜索