国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

前端20個靈魂拷問 徹底搞明白你就是中級前端工程師 【下篇】

fireflow / 1982人閱讀

摘要:安裝后已經(jīng)完成了安裝,并且等待其他的線程被關(guān)閉。激活后在這個狀態(tài)會處理事件回調(diào)提供了更新緩存策略的機會。并可以處理功能性的事件請求后臺同步推送。廢棄狀態(tài)這個狀態(tài)表示一個的生命周期結(jié)束。

不知不覺,已經(jīng)來到了最后的下篇 其實我寫的東西你如果認(rèn)真去看,跟著去寫,應(yīng)該能有不少的收獲。

最近一些跨平臺技術(shù),React-nativeflutter之類的,比較火。但是,我還是不準(zhǔn)備把它們放進(jìn)來,因為那是為做App而生,我想把Electron這個桌面端跨平臺的技術(shù)放進(jìn)來。理由是什么,后面說

這是上篇和中篇,如果你是第一次看這個系列文章,歡迎去從頭開始學(xué)習(xí):

前端20個靈魂拷問 徹底搞明白你就是中級前端工程師 【上篇】
前端20個靈魂拷問 徹底搞明白你就是中級前端工程師 【中篇】

以及一些比較不錯的文章:

從零編寫一個React框架

我們?yōu)槭裁匆煜み@些通信協(xié)議

單頁面應(yīng)用SPA原理

9102年:手寫一個React腳手架 【優(yōu)化極致版】

性能優(yōu)化不完全手冊

Electron跨平臺入門系列

上面的文章,gitHub上,都有對應(yīng)的源碼。
進(jìn)入正題 一千個人眼里有一千個哈姆雷特,我們做不到完美

每個人評判的標(biāo)準(zhǔn)不一樣,我們唯有拿出碾壓這個層級的能力的時候,才能堵住質(zhì)疑者的嘴。當(dāng)然,我們不做技術(shù)杠精,技術(shù)本身沒有好壞。不喜歡就不理會

最后問題,我準(zhǔn)備如下內(nèi)容: 前端的性能優(yōu)化方向 從傳輸層面去優(yōu)化的方向

預(yù)解析地址 首次請求解析地址如果沒有緩存 那么可能消耗60-120ms

性能優(yōu)化不完全手冊這里面有介紹

preload預(yù)請求必要內(nèi)容,prefetch預(yù)請求可能需要內(nèi)容

這種請求方式不會阻塞瀏覽器的解析,而且能將預(yù)請求的資源緩存起來,而且可以設(shè)置crossorgin進(jìn)行跨域資源的緩存,不會推遲首屏的渲染時間,還會加快后面的加載時間,因為后面的本身需要的資源會直接從緩存中讀取,而不會走網(wǎng)絡(luò)請求。

使用 preload 前,在遇到資源依賴時進(jìn)行加載:

使用 preload 后,不管資源是否使用都將提前加載:

可以看到,preload 的資源加載順序?qū)⒈惶崆埃?/p>


使用 preload 后,Chrome 會有一個警告:


preload 和 prefetch 混用的話,并不會復(fù)用資源,而是會重復(fù)加載。
若不確定資源是必定會加載的,則不要錯誤使用 preload,以免本末倒置,給頁面帶來更沉重的負(fù)擔(dān)。

preload 加載頁面必需的資源如 CDN 上的字體文件,與 prefetch 預(yù)測加載下一屏數(shù)據(jù),興許是個不錯的組合。

preload和prefetch詳解 這篇文章寫得很棒 感謝作者

減少傳輸次數(shù)

部分圖片base64處理,然后使用雪碧圖。多張圖拼成一張傳輸

當(dāng)然base64這個東西慎用,實際開發(fā)中它表現(xiàn)并那么好

減少傳輸體積

例如后端返回數(shù)據(jù):“該用戶沒有擁有權(quán)限”

可以改成:0

約定優(yōu)于配置的思想一定要有

使用probbuffer協(xié)議

ProtoBuffer是由谷歌研發(fā)的對象序列化和反序列化的開源工具

它的本質(zhì)就是將一段數(shù)據(jù)序列化,轉(zhuǎn)變成二進(jìn)制形式傳輸

然后另外的服務(wù)器端或者客戶端接受到之后 反序列化,轉(zhuǎn)換成對應(yīng)的數(shù)據(jù)格式(json

好像還有人沒有聽說這個傳輸協(xié)議 其實它傳輸過程就是2進(jìn)制流的形式

用得最多的是和GRPC配合Go語言或者服務(wù)器之間傳輸數(shù)據(jù)

例如IM應(yīng)用,每個IM應(yīng)用都是一個服務(wù)端 也是一個客戶端

那么對于這種頻繁傳輸數(shù)據(jù)的時候,可以使用protobuffer傳輸協(xié)議

protobuffer下載

protobuffer有幾個優(yōu)點:

1.平臺無關(guān),語言無關(guān),可擴展;
2.提供了友好的動態(tài)庫,使用簡單;
3.解析速度快,比對應(yīng)的XML快約20-100倍;
4.序列化數(shù)據(jù)非常簡潔、緊湊,與XML相比,其序列化之后的數(shù)據(jù)量約為1/3到1/10。

protobuffer.js - 我們可以使用這個庫來解析

protobuf.js 提供了幾種方式來處理proto

直接解析,如protobuf.load("awesome.proto", function(err, root) {...})

轉(zhuǎn)化為JSONjs后使用,如protobuf.load("awesome.json", function(err, root) {...})

當(dāng)然我們一般轉(zhuǎn)換成.js后使用

vue使用protobuffer 我這里不做大篇介紹,因為有人完全用不到

代碼層次優(yōu)化:
封裝數(shù)據(jù)對象

可以用對象進(jìn)行大數(shù)據(jù)封裝,盡量用對象key-value形式封裝

如果需要對象遍歷 其實也有很多種方法可以做到

用對象有個好處 就是數(shù)據(jù)量大起來但是需要查找的時候會非常快

避免書寫耗時的同步代碼

不管前端怎么發(fā)展,js主線程是單線程,并且與GUI渲染線程互斥還是沒有變

為什么?

因為js可以進(jìn)行dom操作 為了防止在渲染過程出現(xiàn)dom操作而造成不可預(yù)見后果

現(xiàn)代框架的底層其實還是dom操作  并且直接的dom操作比數(shù)據(jù)驅(qū)動要快多!

例如:

for(let i=0; i< 100000; i++){
    console.log(i)
}

console.log(1)

for循環(huán)其實很快,但是走完這100000次循環(huán)的耗時,到打印出1,有可能超過100ms

那么如果這個打印輸出1是一個用戶交互操作 就會讓用戶有了延遲卡頓的現(xiàn)象

所謂的卡,并不是電腦或者手機帶不動我們的代碼,而是js線程和GUI渲染互斥造成的假象。(大部分是這情況,也有配置特別低的)

如果非要同步代碼的場景?

那么我建議ES6的異步方案,或者改變實現(xiàn)方案,因為大部分性能方案優(yōu)化是卡在這個點。

手機端白屏,持久化存儲等解決網(wǎng)絡(luò)傳輸慢等方案

淘寶等task-slice 方案

淘寶task-slice方案

先不說這篇文章實現(xiàn)最終效果怎樣,但是這種思想在前端里是可以大量使用的,Go語言里就有切片

渲染任務(wù)分割后打開性能調(diào)試面板

可以看到是一點點渲染出來的 也算是加快了首屏渲染吧!

切片隊列的核心代碼:

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框架編寫的每幀清空渲染隊列有點類似:

/**
 * 隊列   先進(jìn)先出 后進(jìn)后出 ~
 * @param {Array:Object} setStateQueue  抽象隊列 每個元素都是一個key-value對象 key:對應(yīng)的stateChange value:對應(yīng)的組件
 * @param {Array:Component} renderQueue  抽象需要更新的組件隊列 每個元素都是Component
 */
const setStateQueue = [];
const renderQueue = [];


function defer(fn) {
  //requestIdleCallback的兼容性不好,對于用戶交互頻繁多次合并更新來說,requestAnimation更有及時性高優(yōu)先級,requestIdleCallback則適合處理可以延遲渲染的任務(wù)~
  //   if (window.requestIdleCallback) {
  //     console.log("requestIdleCallback");
  //     return requestIdleCallback(fn);
  //   }
  //高優(yōu)先級任務(wù)
  return requestAnimationFrame(fn);
}

export function enqueueSetState(stateChange, component) {
  if (setStateQueue.length === 0) {
    //清空隊列的辦法是異步執(zhí)行,下面都是同步執(zhí)行的一些計算
    defer(flush);
  }


...//dosomething 

}

從零編寫一個react框架

數(shù)據(jù)持久化存儲

PWA,漸進(jìn)式web應(yīng)用

將數(shù)據(jù)資源儲存在緩存中,每次請求前判斷是否在Service Worker中,如果沒有再請求網(wǎng)絡(luò)資源

PWA 的主要特點包括下面三點:

可靠 - 即使在不穩(wěn)定的網(wǎng)絡(luò)環(huán)境下,也能瞬間加載并展現(xiàn)
體驗 - 快速響應(yīng),并且有平滑的動畫響應(yīng)用戶的操作
粘性 - 像設(shè)備上的原生應(yīng)用,具有沉浸式的用戶體驗,用戶可以添加到桌面

當(dāng)用戶打開我們站點時(從桌面 icon 或者從瀏覽器),通過 Service Worker 能夠讓用戶在網(wǎng)絡(luò)條件很差的情況下也能瞬間加載并且展現(xiàn)。

Service Worker 是用 JavaScript 編寫的 JS 文件,能夠代理請求,并且能夠操作瀏覽器緩存,通過將緩存的內(nèi)容直接返回,讓請求能夠瞬間完成。開發(fā)者可以預(yù)存儲關(guān)鍵文件,可以淘汰過期的文件等等,給用戶提供可靠的體驗。

如果站點加載時間超過 3s,53% 的用戶會放棄等待。頁面展現(xiàn)之后,用戶期望有平滑的體驗,過渡動畫和快速響應(yīng)。

為了保證首屏的加載,我們需要從設(shè)計上考慮,在內(nèi)容請求完成之前,可以優(yōu)先保證 App Shell 的渲染,做到和 Native App 一樣的體驗,App Shell 是 PWA 界面展現(xiàn)所需的最小資源。

文檔寫得最好的,還是百度的lavas

Service Worker生命周期分為這么幾個狀態(tài) 安裝中, 安裝后, 激活中, 激活后, 廢棄

安裝( installing ):這個狀態(tài)發(fā)生在 Service Worker 注冊之后,表示開始安裝,觸發(fā) install 事件回調(diào)指定一些靜態(tài)資源進(jìn)行離線緩存。

安裝后( installed ):Service Worker 已經(jīng)完成了安裝,并且等待其他的 Service Worker 線程被關(guān)閉。

激活( activating ):在這個狀態(tài)下沒有被其他的 Service Worker 控制的客戶端,允許當(dāng)前的 worker 完成安裝,并且清除了其他的 worker 以及關(guān)聯(lián)緩存的舊緩存資源,等待新的 Service Worker 線程被激活。

激活后( activated ):在這個狀態(tài)會處理 activate 事件回調(diào) (提供了更新緩存策略的機會)。并可以處理功能性的事件 fetch (請求)、sync (后臺同步)、push (推送)。

廢棄狀態(tài) ( redundant ):這個狀態(tài)表示一個 Service Worker 的生命周期結(jié)束。

Service Worker本質(zhì),可以看成另外一個線程啟動,做為一個中間件在發(fā)揮作用。

緩存的資源都是可以在這里看到

Service Worker只能在localhost調(diào)試中或者https中使用,因為它的權(quán)限過于強大,可以攔截請求等。所以要確保安全,目前PWA并不成熟,瀏覽器兼容性還是不那么好,但是它用起來是真的很舒服

另外一種持久化存儲方案:

localStorage

瀏覽器APIlocalStorage.getItem等...

有類似將js文件緩存寫入localStorage 然后通過與服務(wù)端對比版本號再決定是否更新js文件

還有在進(jìn)入首頁時,將詳情頁的模版先存入localStorage 當(dāng)進(jìn)入詳情頁時候直接取出,然后發(fā)請求,把請求回來的一小部分內(nèi)容(比如圖片,渲染上去)

當(dāng)然,還有種種的應(yīng)用,騷操作。

最后是框架,現(xiàn)在的單頁面框架,其實很簡單。 每次更新頁面,diff對比差異后,更新差異部分。

精細(xì)化拆分組件 , 經(jīng)常變和不經(jīng)常變的分拆

精細(xì)化定制數(shù)據(jù)來源,最好做到單向數(shù)據(jù)流,只有一個數(shù)據(jù)改變可以影響重新渲染

并不是所有的都需要在shouldComponentUpdate中對比然后決定是否要更新

實踐證明 復(fù)用1000個組件渲染在頁面中

immutable去生成不可變數(shù)據(jù)對比

跟用PureComponent淺比較 后者會快很多很多

永遠(yuǎn)別忘了js主線程和GUI渲染線程互斥。

合理手段減少重復(fù)渲染次數(shù)

如何優(yōu)化你的超大型React應(yīng)用
前端性能優(yōu)化不完全手冊 - 很早前寫的文章

發(fā)現(xiàn)性能優(yōu)化其實要寫的太多太多,但是,核心點在上面和文章里了,特別是我的那個清空渲染隊列的代碼,我決定能解決很大部分的性能瓶頸。
負(fù)載均衡,Nginxpm2配置

在理解Nginx的用途之前先了解正向代理、反向代理的概念:

正向代理:是一個位于客戶端和原始服務(wù)器(origin server)之間的服務(wù)器,為了從原始服務(wù)器取得內(nèi)容,客戶端向代理發(fā)送一個請求并指定目標(biāo)(原始服務(wù)器),然后代理向原始服務(wù)器轉(zhuǎn)交請求并將獲得的內(nèi)容返回給客戶端。

反向代理:在計算機網(wǎng)絡(luò)中,反向代理是代理服務(wù)器的一種。它根據(jù)客戶端的請求,從后端的服務(wù)器上獲取資源,然后再將這些資源返回給客戶端。與正向代理不同,正向代理作為一個媒介將互聯(lián)網(wǎng)上獲取的資源返回給相關(guān)聯(lián)的客戶端,而反向代理是在服務(wù)器端作為代理使用,而不是客戶端。

PM2是一款非常好用的Node.js服務(wù)啟動容器。它可以讓你保持應(yīng)用程序永遠(yuǎn)運行,要重新加載它們無需停機(我是這么理解的:PM2是一個監(jiān)控工具)。

nginx是一款輕量化的web服務(wù)器。相較于Apache具有占有內(nèi)存少,并發(fā)高等優(yōu)勢。使用epoll模型,nginx的效率很高。并且可以熱升級。

Nginx與PM2的區(qū)別:

pm2是在應(yīng)用層面單機的負(fù)載,nginx是多用于多機集群的負(fù)載PM2 Cluster 是對單臺服務(wù)器而言的,而 nginx 是對多臺服務(wù)器而言的,它們可以很好的結(jié)合在一起。全篇看下來會發(fā)現(xiàn),其實Nginx與PM2完全是不一樣的,兩者之間沒有很大的相同點讓人混淆。換一種更容易理解的說法是:nginx配置多站點(域名),pm2管理nodejs后臺進(jìn)程

使用PM2永動機啟動Node.js項目,再使用nginx做反向代理,簡直完美。

因為node.js程序監(jiān)聽的是服務(wù)器端口,使用nginx做反向代理,就可以任意配置你的二級域名來訪問你的程序

這里我們主要介紹nginx的負(fù)載模塊

HTTP負(fù)載均衡模塊(HTTP Upstream)

這個模塊為后端的服務(wù)器提供簡單的負(fù)載均衡(輪詢(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的負(fù)載均衡算法:

1.round robin(默認(rèn))
輪詢方式,依次將請求分配到各個后臺服務(wù)器中,默認(rèn)的負(fù)載均衡方式。
適用于后臺機器性能一致的情況。
掛掉的機器可以自動從服務(wù)列表中剔除。

2.weight
根據(jù)權(quán)重來分發(fā)請求到不同的機器中,指定輪詢幾率,weight和訪問比率成正比,用于后端服務(wù)器性能不均的情況。

例如:

upstream bakend {    
server 192.168.0.14 weight=10;    
server 192.168.0.15 weight=10;    
}  

3.IP_hash
根據(jù)請求者ip的hash值將請求發(fā)送到后臺服務(wù)器中,可以保證來自同一ip的請求被打到固定的機器上,可以解決session問題。

例如:

upstream bakend {    
ip_hash;    
server 192.168.0.14:88;    
server 192.168.0.15:80;    
}   

4.fair
根據(jù)后臺響應(yīng)時間來分發(fā)請求,響應(yīng)時間短的分發(fā)的請求多。

例如:

upstream backend {
server server1;
server server2;
fair;
}

5.url_hash
根據(jù)請求的urlhash值將請求分到不同的機器中,當(dāng)后臺服務(wù)器為緩存的時候效率高。

例如:

在upstream中加入hash語句,server語句中不能寫入weight等其他的參數(shù),hash_method是使用的hash算法

upstream backend {    
server squid1:3128;    
server squid2:3128;    
hash $request_uri;    
hash_method crc32;    
}  

常見的負(fù)載均衡算法
使用pm2:

npm install pm2 -g 


pm2 start app.js

PM2 的主要特性

內(nèi)建負(fù)載均衡(使用 Node cluster 集群模塊)
后臺運行
0 秒停機重載,我理解大概意思是維護(hù)升級的時候不需要停機.
具有 Ubuntu 和 CentOS 的啟動腳本
停止不穩(wěn)定的進(jìn)程(避免無限循環(huán))
控制臺檢測
提供 HTTP API
遠(yuǎn)程控制和實時的接口 API ( Nodejs 模塊,允許和 PM2 進(jìn)程管理器交互 )


pm2常用命令

pm2的使用,讓我們避開了自己配置負(fù)載均衡,守護(hù)進(jìn)程等一系列。但是高并發(fā)場景,Nginx和內(nèi)置的負(fù)載均衡,僅僅只講到了皮毛,這里只是入個門。

還剩下最后三個問題,我想寫得質(zhì)量高一些,如果感覺寫得不錯可以點個贊,關(guān)注下。gitHub倉庫也歡迎去star~哦

歡迎加入我們的segmentFault前端交流群,因為群里人數(shù)比較多了,加我的個人微信:CALASFxiaotan 我會拉你進(jìn)群

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/116359.html

相關(guān)文章

  • 前端20靈魂拷問 徹底明白就是中級前端程師 【中篇】

    摘要:前端個靈魂拷問,徹底搞明白你就是中級前端工程師上篇感覺大家比較喜歡看這種類型的文章,以后會多一些。所有依賴這個模塊的語句,都定義在一個回調(diào)函數(shù)中,等到加載完成之后,這個回調(diào)函數(shù)才會運行。此規(guī)范其實是在推廣過程中產(chǎn)生的。 showImg(https://segmentfault.com/img/bVbwAMU?w=700&h=394); 前端20個靈魂拷問,徹底搞明白你就是中級前端工程師...

    MartinDai 評論0 收藏0
  • 前端20靈魂拷問 徹底明白就是中級前端程師 【中篇】

    摘要:前端個靈魂拷問,徹底搞明白你就是中級前端工程師上篇感覺大家比較喜歡看這種類型的文章,以后會多一些。所有依賴這個模塊的語句,都定義在一個回調(diào)函數(shù)中,等到加載完成之后,這個回調(diào)函數(shù)才會運行。此規(guī)范其實是在推廣過程中產(chǎn)生的。 showImg(https://segmentfault.com/img/bVbwAMU?w=700&h=394); 前端20個靈魂拷問,徹底搞明白你就是中級前端工程師...

    coolpail 評論0 收藏0
  • 前端20真正靈魂拷問,吃透這些就是中級前端程師 【上篇】

    摘要:還是老規(guī)矩,從易到難吧傳統(tǒng)的定時器,異步編程等。分配對象時,先是在空間中進(jìn)行分配。內(nèi)存泄漏內(nèi)存泄漏是指程序中己動態(tài)分配的堆內(nèi)存由于某種原因程序未釋放或無法釋放,造成系統(tǒng)內(nèi)存的浪費,導(dǎo)致程序運行速度減慢甚至系統(tǒng)崩潰等嚴(yán)重后果。 showImg(https://segmentfault.com/img/bVbwkad?w=1286&h=876); 網(wǎng)上參差不棄的面試題,本文由淺入深,讓你在...

    mdluo 評論0 收藏0
  • 前端20真正靈魂拷問,吃透這些就是中級前端程師 【上篇】

    摘要:還是老規(guī)矩,從易到難吧傳統(tǒng)的定時器,異步編程等。分配對象時,先是在空間中進(jìn)行分配。內(nèi)存泄漏內(nèi)存泄漏是指程序中己動態(tài)分配的堆內(nèi)存由于某種原因程序未釋放或無法釋放,造成系統(tǒng)內(nèi)存的浪費,導(dǎo)致程序運行速度減慢甚至系統(tǒng)崩潰等嚴(yán)重后果。 showImg(https://segmentfault.com/img/bVbwkad?w=1286&h=876); 網(wǎng)上參差不棄的面試題,本文由淺入深,讓你在...

    leap_frog 評論0 收藏0
  • [靈魂拷問]MySQL面試高頻100問(程師方向)

    摘要:黑客技術(shù)點擊右側(cè)關(guān)注,了解黑客的世界開發(fā)進(jìn)階點擊右側(cè)關(guān)注,掌握進(jìn)階之路開發(fā)點擊右側(cè)關(guān)注,探討技術(shù)話題作者丨呼延十排版丨團長前言本文主要受眾為開發(fā)人員所以不涉及到的服務(wù)部署等操作且內(nèi)容較多大家準(zhǔn)備好耐心和瓜子礦泉水前一陣系統(tǒng)的學(xué)習(xí)了一下也有 ...

    gyl_coder 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<