-? 二、熱跟新原理
-? 三、實例剖析
-? 四、總結
websocket簡介
在h5推出之前,瀏覽器應用跟服務器端通信的機制只有http協議,http是一種無狀態的網絡協議,前端向服務器發起一個請求,服務器給出一次應答,服務器無法主動向客戶端發起通信,這種設計主要是為了節省帶寬資源,客戶端和服務器端不需要維持長連接
早期要實現一個瀏覽器即使通信工具(如webqq),由于服務器端不能主動向客戶端發起通信,只能客戶端設置一個定時器,定時向服務器端發起請求拉取消息,很顯然,這種輪詢的方式對性能來說是一把殺豬刀
h5很應景的推出了websocket,這給了web開發者另一種選擇去應付紛繁復雜的場景。WebSocket 是一個獨立的基于TCP的協議,前端和服務器端可以建立起一個長連接,客戶端可以向服務器端推送消息,服務器也可以主動向客戶端推送消息
本文不對websocket做太深入的說明,有興趣可留下你的評論
熱跟新原理

瀏覽器的網頁通過websocket協議與服務器建立起一個長連接,當服務器的css/js/html進行了修改的時候,服務器會向前端發送一個更新的消息,如果是css或者html發生了改變,網頁執行js直接操作dom,局部刷新,如果是js發生了改變,只好刷新整個頁面
js發生改變的時候,不太可能判斷出對dom的局部影響,只能全局刷新
為何沒有提到圖片的更新,如果是在html或者css里修改了圖片路徑,那么更新html和css,只要圖片路徑沒有錯,那么就已經達到了更新圖片的路徑。如果是相同路徑的圖片進行了替換,這往往需要重啟下服務
在簡單的網頁應用中,這一個過程可能僅僅是節省了手動刷新瀏覽器的繁瑣,但是在負責的應用中,如果你在調試的部分需要從頁面入口操作好幾步才到達,例如:登錄->列表->詳情->彈出窗口
,那么局部刷新將大大提高調試效率
實例剖析
如果你使用gulp構建的前端開發工作環境,想必對browserSync不會陌生,你明白它的工作方式么?
browserSync易于使用:
var bs = browserSync({port: 5000, //服務端口notify: false,logPrefix: 'PSK',server: {baseDir: '_dev', //服務路徑,也就是頁面資源存放的路徑directory: true},open: false //需不需要自動打開瀏覽器}, function() {//啟動后的回調});
很容易想到,這開啟了一個http服務,在瀏覽器輸入localhost:5000/path就可以訪問到頁面,不知道有沒有細心的觀眾在查看頁面源碼的時候發現多了點什么不是你寫的東西

沒錯,browser-sync-client.2.9.6.js并不是你引入的,這個是browserSync在創建的時候,為你的html自動注入的(baseDir目錄下),部分代碼:
.........___browserSync___.io = window.io;window.io = window.___browserSync___oldSocketIo;window.___browserSync___oldSocketIo=undefined;___browserSync___.socketConfig = {"reconnectionAttempts":50,"path":"/browser-sync/socket.io"};___browserSync___.socket = ___browserSync___.io('' + location.host + '/browser-sync', ___browserSync___.socketConfig);"use strict";(function (window, document, bs, undefined) {var socket = bs.socket;var uiOptions = {bs: {}};..........
原諒我并未仔細研讀過次文件代碼,因為實在太多太凌亂,但是從上面這幾行代碼,以及文件名,就基本可以確定這是websocket-client的代碼
讀過的同學求抱大腿
下面再來做一個實驗來確認下,control+c 把服務器關閉,再來看看剛才那網頁的控制臺:

控制臺一直在報錯,why? 因為服務器關閉了之后,連接斷開,客戶端一直在嘗試對服務器發起重連
再來看看webpack是怎么做的,webpack可以使用webpack-dev-server來搭建熱跟新的開發環境,webpack-dev-server是基于express的輕量級服務器,作用有點類似于上述的browserSync,你需要在webpack.config.js中的entry配置里增加的點東西
var config = {entry: ['webpack/hot/dev-server', './app/main.js'], output: {path: path.resolve(__dirname, './build'),filename: 'bundle.js'},module: {loaders: [{test: /\.js$/,// Use the property "loaders" instead of "loader" and // add "react-hot" in front of your existing "jsx" loader// 使用 "loaders" 屬性代替 "loader"// 然后在 "jsx" 加載器之前添加 "react-hot" loaders: ['react-hot', 'babel']}]}};
配置中增加了webpack/hot/dev-server實體,跟main.js一起打包成bundle.js,這個就可以類比到上面的browser-sync-client.2.9.6.js
如果自己搭建express,還可以使用webpack的熱跟新中間件
總結
知其然并知其所以然是很重要的,不要求搞清楚每一個細節,但要懂得實現原理
打賞就不需要了,如果對你有幫助,給個贊吧~~