摘要:安裝后已經完成了安裝,并且等待其他的線程被關閉。激活后在這個狀態會處理事件回調提供了更新緩存策略的機會。并可以處理功能性的事件請求后臺同步推送。廢棄狀態這個狀態表示一個的生命周期結束。
不知不覺,已經來到了最后的下篇 其實我寫的東西你如果認真去看,跟著去寫,應該能有不少的收獲。
最近一些跨平臺技術,React-native和flutter之類的,比較火。但是,我還是不準備把它們放進來,因為那是為做App而生,我想把Electron這個桌面端跨平臺的技術放進來。理由是什么,后面說
這是上篇和中篇,如果你是第一次看這個系列文章,歡迎去從頭開始學習:
前端20個靈魂拷問 徹底搞明白你就是中級前端工程師 【上篇】
前端20個靈魂拷問 徹底搞明白你就是中級前端工程師 【中篇】
以及一些比較不錯的文章:
從零編寫一個React框架
我們為什么要熟悉這些通信協議
單頁面應用SPA原理
9102年:手寫一個React腳手架 【優化極致版】
性能優化不完全手冊
Electron跨平臺入門系列
上面的文章,gitHub上,都有對應的源碼。進入正題 一千個人眼里有一千個哈姆雷特,我們做不到完美
每個人評判的標準不一樣,我們唯有拿出碾壓這個層級的能力的時候,才能堵住質疑者的嘴。當然,我們不做技術杠精,技術本身沒有好壞。不喜歡就不理會
最后問題,我準備如下內容: 前端的性能優化方向 從傳輸層面去優化的方向預解析地址 首次請求解析地址如果沒有緩存 那么可能消耗60-120ms
性能優化不完全手冊這里面有介紹
preload預請求必要內容,prefetch預請求可能需要內容
這種請求方式不會阻塞瀏覽器的解析,而且能將預請求的資源緩存起來,而且可以設置crossorgin進行跨域資源的緩存,不會推遲首屏的渲染時間,還會加快后面的加載時間,因為后面的本身需要的資源會直接從緩存中讀取,而不會走網絡請求。
使用 preload 前,在遇到資源依賴時進行加載:
使用 preload 后,不管資源是否使用都將提前加載:
可以看到,preload 的資源加載順序將被提前:
使用 preload 后,Chrome 會有一個警告:
preload 和 prefetch 混用的話,并不會復用資源,而是會重復加載。
若不確定資源是必定會加載的,則不要錯誤使用 preload,以免本末倒置,給頁面帶來更沉重的負擔。
preload 加載頁面必需的資源如 CDN 上的字體文件,與 prefetch 預測加載下一屏數據,興許是個不錯的組合。
preload和prefetch詳解 這篇文章寫得很棒 感謝作者
減少傳輸次數部分圖片base64處理,然后使用雪碧圖。多張圖拼成一張傳輸
當然base64這個東西慎用,實際開發中它表現并那么好
減少傳輸體積例如后端返回數據:“該用戶沒有擁有權限”
可以改成:0
約定優于配置的思想一定要有
使用probbuffer協議ProtoBuffer是由谷歌研發的對象序列化和反序列化的開源工具
它的本質就是將一段數據序列化,轉變成二進制形式傳輸
然后另外的服務器端或者客戶端接受到之后 反序列化,轉換成對應的數據格式(json)
好像還有人沒有聽說這個傳輸協議 其實它傳輸過程就是2進制流的形式
用得最多的是和GRPC配合Go語言或者服務器之間傳輸數據
例如IM應用,每個IM應用都是一個服務端 也是一個客戶端
那么對于這種頻繁傳輸數據的時候,可以使用protobuffer傳輸協議
protobuffer下載
protobuffer有幾個優點:
1.平臺無關,語言無關,可擴展;
2.提供了友好的動態庫,使用簡單;
3.解析速度快,比對應的XML快約20-100倍;
4.序列化數據非常簡潔、緊湊,與XML相比,其序列化之后的數據量約為1/3到1/10。
protobuffer.js - 我們可以使用這個庫來解析
protobuf.js 提供了幾種方式來處理proto。
直接解析,如protobuf.load("awesome.proto", function(err, root) {...})
轉化為JSON或js后使用,如protobuf.load("awesome.json", function(err, root) {...})
當然我們一般轉換成.js后使用
vue使用protobuffer 我這里不做大篇介紹,因為有人完全用不到
代碼層次優化:可以用對象進行大數據封裝,盡量用對象key-value形式封裝
如果需要對象遍歷 其實也有很多種方法可以做到
用對象有個好處 就是數據量大起來但是需要查找的時候會非常快
不管前端怎么發展,js主線程是單線程,并且與GUI渲染線程互斥還是沒有變
為什么?
因為js可以進行dom操作 為了防止在渲染過程出現dom操作而造成不可預見后果
現代框架的底層其實還是dom操作 并且直接的dom操作比數據驅動要快多!
例如:
for(let i=0; i< 100000; i++){ console.log(i) } console.log(1)
for循環其實很快,但是走完這100000次循環的耗時,到打印出1,有可能超過100ms
那么如果這個打印輸出1是一個用戶交互操作 就會讓用戶有了延遲卡頓的現象
所謂的卡,并不是電腦或者手機帶不動我們的代碼,而是js線程和GUI渲染互斥造成的假象。(大部分是這情況,也有配置特別低的)
如果非要同步代碼的場景?
那么我建議ES6的異步方案,或者改變實現方案,因為大部分性能方案優化是卡在這個點。
手機端白屏,持久化存儲等解決網絡傳輸慢等方案淘寶等task-slice 方案
淘寶task-slice方案
先不說這篇文章實現最終效果怎樣,但是這種思想在前端里是可以大量使用的,Go語言里就有切片
渲染任務分割后打開性能調試面板
可以看到是一點點渲染出來的 也算是加快了首屏渲染吧!
切片隊列的核心代碼:
function* sliceQueue({ sliceList, callback }) { let listOrNum = (isNum(sliceList) && sliceList) || (isArray(sliceList) && sliceList.length); for (let i = 0; i < listOrNum; ++i) { const start = performance.now(); callback(i); while (performance.now() - start < 16.7) { yield; } } }
跟我的React框架編寫的每幀清空渲染隊列有點類似:
/** * 隊列 先進先出 后進后出 ~ * @param {Array:Object} setStateQueue 抽象隊列 每個元素都是一個key-value對象 key:對應的stateChange value:對應的組件 * @param {Array:Component} renderQueue 抽象需要更新的組件隊列 每個元素都是Component */ const setStateQueue = []; const renderQueue = []; function defer(fn) { //requestIdleCallback的兼容性不好,對于用戶交互頻繁多次合并更新來說,requestAnimation更有及時性高優先級,requestIdleCallback則適合處理可以延遲渲染的任務~ // if (window.requestIdleCallback) { // console.log("requestIdleCallback"); // return requestIdleCallback(fn); // } //高優先級任務 return requestAnimationFrame(fn); } export function enqueueSetState(stateChange, component) { if (setStateQueue.length === 0) { //清空隊列的辦法是異步執行,下面都是同步執行的一些計算 defer(flush); } ...//dosomething }
從零編寫一個react框架
數據持久化存儲
PWA,漸進式web應用
將數據資源儲存在緩存中,每次請求前判斷是否在Service Worker中,如果沒有再請求網絡資源
PWA 的主要特點包括下面三點:
可靠 - 即使在不穩定的網絡環境下,也能瞬間加載并展現
體驗 - 快速響應,并且有平滑的動畫響應用戶的操作
粘性 - 像設備上的原生應用,具有沉浸式的用戶體驗,用戶可以添加到桌面
當用戶打開我們站點時(從桌面 icon 或者從瀏覽器),通過 Service Worker 能夠讓用戶在網絡條件很差的情況下也能瞬間加載并且展現。
Service Worker 是用 JavaScript 編寫的 JS 文件,能夠代理請求,并且能夠操作瀏覽器緩存,通過將緩存的內容直接返回,讓請求能夠瞬間完成。開發者可以預存儲關鍵文件,可以淘汰過期的文件等等,給用戶提供可靠的體驗。
如果站點加載時間超過 3s,53% 的用戶會放棄等待。頁面展現之后,用戶期望有平滑的體驗,過渡動畫和快速響應。
為了保證首屏的加載,我們需要從設計上考慮,在內容請求完成之前,可以優先保證 App Shell 的渲染,做到和 Native App 一樣的體驗,App Shell 是 PWA 界面展現所需的最小資源。
文檔寫得最好的,還是百度的lavas
Service Worker生命周期分為這么幾個狀態 安裝中, 安裝后, 激活中, 激活后, 廢棄
安裝( installing ):這個狀態發生在 Service Worker 注冊之后,表示開始安裝,觸發 install 事件回調指定一些靜態資源進行離線緩存。
安裝后( installed ):Service Worker 已經完成了安裝,并且等待其他的 Service Worker 線程被關閉。
激活( activating ):在這個狀態下沒有被其他的 Service Worker 控制的客戶端,允許當前的 worker 完成安裝,并且清除了其他的 worker 以及關聯緩存的舊緩存資源,等待新的 Service Worker 線程被激活。
激活后( activated ):在這個狀態會處理 activate 事件回調 (提供了更新緩存策略的機會)。并可以處理功能性的事件 fetch (請求)、sync (后臺同步)、push (推送)。
廢棄狀態 ( redundant ):這個狀態表示一個 Service Worker 的生命周期結束。
Service Worker本質,可以看成另外一個線程啟動,做為一個中間件在發揮作用。
緩存的資源都是可以在這里看到
Service Worker只能在localhost調試中或者https中使用,因為它的權限過于強大,可以攔截請求等。所以要確保安全,目前PWA并不成熟,瀏覽器兼容性還是不那么好,但是它用起來是真的很舒服
另外一種持久化存儲方案:
localStorage
瀏覽器API有localStorage.getItem等...
有類似將js文件緩存寫入localStorage 然后通過與服務端對比版本號再決定是否更新js文件
還有在進入首頁時,將詳情頁的模版先存入localStorage 當進入詳情頁時候直接取出,然后發請求,把請求回來的一小部分內容(比如圖片,渲染上去)
當然,還有種種的應用,騷操作。
最后是框架,現在的單頁面框架,其實很簡單。 每次更新頁面,diff對比差異后,更新差異部分。
精細化拆分組件 , 經常變和不經常變的分拆
精細化定制數據來源,最好做到單向數據流,只有一個數據改變可以影響重新渲染
并不是所有的都需要在shouldComponentUpdate中對比然后決定是否要更新
實踐證明 復用1000個組件渲染在頁面中
用immutable去生成不可變數據對比
跟用PureComponent淺比較 后者會快很多很多
永遠別忘了js主線程和GUI渲染線程互斥。
合理手段減少重復渲染次數
如何優化你的超大型React應用
前端性能優化不完全手冊 - 很早前寫的文章
發現性能優化其實要寫的太多太多,但是,核心點在上面和文章里了,特別是我的那個清空渲染隊列的代碼,我決定能解決很大部分的性能瓶頸。負載均衡,Nginx和pm2配置
在理解Nginx的用途之前先了解正向代理、反向代理的概念:
正向代理:是一個位于客戶端和原始服務器(origin server)之間的服務器,為了從原始服務器取得內容,客戶端向代理發送一個請求并指定目標(原始服務器),然后代理向原始服務器轉交請求并將獲得的內容返回給客戶端。
反向代理:在計算機網絡中,反向代理是代理服務器的一種。它根據客戶端的請求,從后端的服務器上獲取資源,然后再將這些資源返回給客戶端。與正向代理不同,正向代理作為一個媒介將互聯網上獲取的資源返回給相關聯的客戶端,而反向代理是在服務器端作為代理使用,而不是客戶端。
PM2是一款非常好用的Node.js服務啟動容器。它可以讓你保持應用程序永遠運行,要重新加載它們無需停機(我是這么理解的:PM2是一個監控工具)。
nginx是一款輕量化的web服務器。相較于Apache具有占有內存少,并發高等優勢。使用epoll模型,nginx的效率很高。并且可以熱升級。
Nginx與PM2的區別:
pm2是在應用層面單機的負載,nginx是多用于多機集群的負載PM2 Cluster 是對單臺服務器而言的,而 nginx 是對多臺服務器而言的,它們可以很好的結合在一起。全篇看下來會發現,其實Nginx與PM2完全是不一樣的,兩者之間沒有很大的相同點讓人混淆。換一種更容易理解的說法是:nginx配置多站點(域名),pm2管理nodejs后臺進程
使用PM2永動機啟動Node.js項目,再使用nginx做反向代理,簡直完美。
因為node.js程序監聽的是服務器端口,使用nginx做反向代理,就可以任意配置你的二級域名來訪問你的程序
這里我們主要介紹nginx的負載模塊
HTTP負載均衡模塊(HTTP Upstream)
這個模塊為后端的服務器提供簡單的負載均衡(輪詢(round-robin)和連接IP(client IP))
如下例:
upstream backend { server backend1.example.com weight=5; server backend2.example.com:8080; server unix:/tmp/backend3; } server { location / { proxy_pass http://backend; } }
Nginx的負載均衡算法:
1.round robin(默認)
輪詢方式,依次將請求分配到各個后臺服務器中,默認的負載均衡方式。
適用于后臺機器性能一致的情況。
掛掉的機器可以自動從服務列表中剔除。
2.weight
根據權重來分發請求到不同的機器中,指定輪詢幾率,weight和訪問比率成正比,用于后端服務器性能不均的情況。
例如:
upstream bakend { server 192.168.0.14 weight=10; server 192.168.0.15 weight=10; }
3.IP_hash
根據請求者ip的hash值將請求發送到后臺服務器中,可以保證來自同一ip的請求被打到固定的機器上,可以解決session問題。
例如:
upstream bakend { ip_hash; server 192.168.0.14:88; server 192.168.0.15:80; }
4.fair
根據后臺響應時間來分發請求,響應時間短的分發的請求多。
例如:
upstream backend {
server server1;
server server2;
fair;
}
5.url_hash
根據請求的url的hash值將請求分到不同的機器中,當后臺服務器為緩存的時候效率高。
例如:
在upstream中加入hash語句,server語句中不能寫入weight等其他的參數,hash_method是使用的hash算法
upstream backend { server squid1:3128; server squid2:3128; hash $request_uri; hash_method crc32; }
常見的負載均衡算法
使用pm2:
npm install pm2 -g pm2 start app.js
PM2 的主要特性
內建負載均衡(使用 Node cluster 集群模塊) 后臺運行 0 秒停機重載,我理解大概意思是維護升級的時候不需要停機. 具有 Ubuntu 和 CentOS 的啟動腳本 停止不穩定的進程(避免無限循環) 控制臺檢測 提供 HTTP API 遠程控制和實時的接口 API ( Nodejs 模塊,允許和 PM2 進程管理器交互 )
pm2常用命令
pm2的使用,讓我們避開了自己配置負載均衡,守護進程等一系列。但是高并發場景,Nginx和內置的負載均衡,僅僅只講到了皮毛,這里只是入個門。
還剩下最后三個問題,我想寫得質量高一些,如果感覺寫得不錯可以點個贊,關注下。gitHub倉庫也歡迎去star~哦
歡迎加入我們的segmentFault前端交流群,因為群里人數比較多了,加我的個人微信:CALASFxiaotan 我會拉你進群
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/116359.html
摘要:前端個靈魂拷問,徹底搞明白你就是中級前端工程師上篇感覺大家比較喜歡看這種類型的文章,以后會多一些。所有依賴這個模塊的語句,都定義在一個回調函數中,等到加載完成之后,這個回調函數才會運行。此規范其實是在推廣過程中產生的。 showImg(https://segmentfault.com/img/bVbwAMU?w=700&h=394); 前端20個靈魂拷問,徹底搞明白你就是中級前端工程師...
摘要:前端個靈魂拷問,徹底搞明白你就是中級前端工程師上篇感覺大家比較喜歡看這種類型的文章,以后會多一些。所有依賴這個模塊的語句,都定義在一個回調函數中,等到加載完成之后,這個回調函數才會運行。此規范其實是在推廣過程中產生的。 showImg(https://segmentfault.com/img/bVbwAMU?w=700&h=394); 前端20個靈魂拷問,徹底搞明白你就是中級前端工程師...
摘要:還是老規矩,從易到難吧傳統的定時器,異步編程等。分配對象時,先是在空間中進行分配。內存泄漏內存泄漏是指程序中己動態分配的堆內存由于某種原因程序未釋放或無法釋放,造成系統內存的浪費,導致程序運行速度減慢甚至系統崩潰等嚴重后果。 showImg(https://segmentfault.com/img/bVbwkad?w=1286&h=876); 網上參差不棄的面試題,本文由淺入深,讓你在...
摘要:還是老規矩,從易到難吧傳統的定時器,異步編程等。分配對象時,先是在空間中進行分配。內存泄漏內存泄漏是指程序中己動態分配的堆內存由于某種原因程序未釋放或無法釋放,造成系統內存的浪費,導致程序運行速度減慢甚至系統崩潰等嚴重后果。 showImg(https://segmentfault.com/img/bVbwkad?w=1286&h=876); 網上參差不棄的面試題,本文由淺入深,讓你在...
摘要:黑客技術點擊右側關注,了解黑客的世界開發進階點擊右側關注,掌握進階之路開發點擊右側關注,探討技術話題作者丨呼延十排版丨團長前言本文主要受眾為開發人員所以不涉及到的服務部署等操作且內容較多大家準備好耐心和瓜子礦泉水前一陣系統的學習了一下也有 ...
閱讀 2655·2021-09-13 10:26
閱讀 1915·2021-09-03 10:28
閱讀 1986·2019-08-30 15:44
閱讀 804·2019-08-29 14:07
閱讀 392·2019-08-29 13:12
閱讀 2149·2019-08-26 11:44
閱讀 2343·2019-08-26 11:36
閱讀 2012·2019-08-26 10:19