PWA
Vue-SSR
http
請求的過程及潛在的性能優化點減小http請求數量
和減小請求資源大小
兩個優化要點壓縮
與合併
的原理在線網站
和fis3
兩種實現壓縮與合併的方法動態的加載靜態的資源javascript
dns
是否能夠經過緩存減小dns
查詢時間http
請求大小http
請求數量http
請求的數量html
壓縮HTML
代碼壓縮就是壓縮這些在文本文件中有意義,可是在HTML
中不顯示的字符,包括空格
,製表符
,換行符
等,還有一些其餘意義的字符,如HTML
註釋也能夠被壓縮
意義
html
的壓縮node.js
提供了html-minifier
工具模板引擎渲染壓縮
css
及js
壓縮css
的壓縮無效代碼刪除php
css
語義合併css
壓縮的方式html-minifier
對html
中的css
進行壓縮clean-css
對css
進行壓縮js
的壓縮語混亂無效字符的刪除css
代碼語意的縮減和優化html
a
,b
)等代碼保護前端
js
壓縮的方式html-minifier
對html
中的js
進行壓縮uglifyjs2
對js
進行壓縮N-1
個網絡延遲首屏渲染問題vue
js
變大,若是首頁的渲染依賴這個js
的話,整個頁面的渲染要等js
請求完才能執行a.js
,只要等a.js
完成後就可執行js
緩存失效問題java
js
`md5`戳js
,任何一個改動都會致使大面積的緩存失效不一樣頁面的合併node
js
單獨打包nodejs
進行文件合併JPG
的解析過程jpg
有損壓縮:雖然損失一些信息,可是肉眼可見影響並不大android
png8
/png24
/png32
之間的區別png8
----256色
+ 支持透明png24
----2^24
+ 不支持透明png32
---2^24
+支持透明文件大小
+ 色彩豐富程度
webpack
png32
是在png24
上支持了透明,針對不一樣的業務場景選擇不一樣的圖片格式很重要
jpg
有損壓縮,壓縮率高,不支持透明png
支持透明,瀏覽器兼容性好webp
壓縮程度更好,在ios webview
中有兼容性問題svg
矢量圖,代碼內嵌,相對較小,圖片樣式相對簡單的場景(儘可能使用,繪製能力有限,圖片簡單用的比較多)jpg
:大部分不須要透明圖片的業務場景png
:大部分須要透明圖片的業務場景webp
:android
所有(解碼速度和壓縮率高於jpg
和png
,可是ios
safari
還沒支持)svg
:圖片樣式相對簡單的業務場景CSS雪碧圖
:把你的網站用到的一些圖片整合到一張單獨的圖片中
HTTP
請求的數量(經過backgroundPosition
定位所需圖片)facebook
官網任然在用,主要pc
用的比較多,相對性能比較強Image-inline
:將圖片的內容嵌到html
中(減小網站的HTTP
請求)
base64信息
,減小網站的HTTP請求,若是圖片比較小比較多,時間損耗主要在請求的骨幹網絡使用矢量圖
SVG
進行矢量圖的繪製icon-font
解決icon
問題在android下使用webp
webp
的優點主要體如今它具備更優的圖像數據壓縮算法,能帶來更小的圖片體積,並且擁有肉眼識別無差別的圖像質量;Alpha
透明以及動畫的特性,在JPEG
和PNG
上的轉化效果都很是優秀、穩定和統一css
和js
的裝載與執行順序執行,併發加載
詞法分析:從上到下依次解析
HTML
生成Token對象
(當前節點的全部子節點生成後,纔會經過next token
獲取到當前節點的兄弟節點),最終生成Dom Tree
併發上限
Chrome
爲例,併發上限爲6個是否阻塞
css
阻塞
css
在head
中經過link
引入會阻塞頁面的渲染
css
代碼放在head
中去引入的話,那麼咱們整個頁面的渲染實際上就會等待head
中css
加載並生成css樹
,最終和DOM
整合生成RanderTree
以後纔會進行渲染避免某些狀況,如:假設你放在頁面最底部,用戶打開頁面時,有可能出現,頁面先是顯示一大堆文字或圖片,自上而下,絲毫沒有排版和樣式可言。最後,頁面又恢復所要的效果
- `css`不阻塞`js`的加載,但阻塞`js`的執行 - `css`不阻塞外部腳步的加載(`webkit preloader 預資源加載器`) - `js`阻塞 - 直接經過`<script src>`引入會阻塞後面節點的渲染 - `html parse`認爲`js`會動態修改文檔結構(`document.write`等方式),沒有進行後面文檔的變化 - `async`、`defer`(`async`放棄了依賴關係) - `defer`屬性(`<script src="" defer></script>`)
(這是延遲執行引入的js
腳本(即腳本加載是不會致使解析中止,等到document
所有解析完畢後,defer-script
也加載完畢後,在執行全部的defer-script
加載的js
代碼,再觸發Domcontentloaded
)
- `async`屬性(`<script src="" async></script>`) - 這是異步執行引入的`js`腳本文件 - 與`defer`的區別是`async`會在加載完成後就執行,可是不會影響阻塞到解析和渲染。可是仍是會阻塞`load`事件,因此`async-script`會可能在`DOMcontentloaded`觸發前或後執行,可是必定會在`load`事件前觸發。
img src
被設置以後,webkit
解析到以後纔去請求這個資源。因此咱們但願圖片到達可視區域以後,img src
纔會被設置進來,沒有到達可視區域前並不現實真正的src
,而是相似一個1px
的佔位符。
場景:電商圖片
場景:抽獎
js
和zepto.lazyload
原理
先將img
標籤中的src
連接設爲同一張圖片(空白圖片),將其真正的圖片地址存儲再img
標籤的自定義屬性中(好比data-src
)。當js
監聽到該圖片元素進入可視窗口時,即將自定義屬性中的地址存儲到src
屬性中,達到懶加載的效果。
注意問題:
var viewheight = document.documentElement.clientHeight //可視區域高度 function lazyload(){ var eles = document.querySelectorAll('img[data-original][lazyload]') Array.prototype.forEach.call(eles,function(item,index){ var rect; if(item.dataset.original === '') return; rect = item.getBoundingClientRect(); //返回元素的大小及其相對於視口的 if(rect.bottom >= 0 && rect.top < viewheight){ !function(){ var img = new Image(); img.src = item.dataset.url; img.onload = function(){ item.src = img.src } item.removeAttribute('data-original'); item.removeAttribute('lazyload'); }() } }) } lazyload() document.addEventListener('scroll',lazyload)
js
和preloadJS
實現<img src="https://user-gold-cdn.xitu.io/2019/2/21/1690d1b216cbfa18" style="display: none"/> <img src="https://user-gold-cdn.xitu.io/2019/2/21/1690d1b21b70c8d2" style="display: none"/> <img src="https://user-gold-cdn.xitu.io/2019/2/21/1690d1b216e17e26" style="display: none"/> <img src="https://user-gold-cdn.xitu.io/2019/2/21/1690d1b217b3ae59" style="display: none"/>
image
對象var image = new Image(); image.src = "www.pic26.com/dafdafd/safdas.jpg";
第三種方式:xmlhttprequest
var xmlhttprequest = new XMLHttpRequest(); xmlhttprequest.onreadystatechange = callback; xmlhttprequest.onprogress = progressCallback; xmlhttprequest.open("GET","http:www.xxx.com",true); xmlhttprequest.send(); function callback(){ if(xmlhttprequest.readyState == 4 && xmlhttprequest.status == 200){ var responseText = xmlhttprequest.responseText; }else{ console.log("Request was unsuccessful:" + xmlhttprequest.status); } } function progressCallback(){ e = e || event; if(e.lengthComputable){ console.log("Received"+e.loaded+"of"+e.total+"bytes") } }
PreloadJS模塊
css
性能讓javascript
變慢要把css
相關的外部文件引入放進head
中,加載css
時,整個頁面的渲染是阻塞的,一樣的執行javascript
代碼的時候也是阻塞的,例如javascript
死循環。
一個線程 => javascript解析 一個線程 => UI渲染
這兩個線程是互斥的,當UI
渲染的時候,javascript
的代碼被終止。當javascript
代碼執行,UI
線程被凍結。因此css
的性能讓javascript
變慢。
頻繁觸發重繪與迴流,會致使UI頻繁渲染,最終致使js變慢
render tree
中的一部分(或所有)由於元素的規模尺寸
,佈局
,隱藏
等改變而須要從新構建
。這就成爲迴流(reflow
)頁面布
局和幾何屬性
改變時,就須要迴流
render tree
中的一些元素須要更新屬性,而這些屬性只是影響元素的外觀
,風格
,而不影響佈局,好比background-color
。就稱重繪用到chrome
分析 performance
迴流必將引發重繪,可是重繪不必定會引發迴流
盒子模型相關屬性會觸發重佈局
width
height
padding
margin
display
border-width
border
min-height
定位屬性及浮動也會觸發重佈局
top
bottom
left
right
position
float
clear
text-align
overflow-y
font-weight
overflow
font-family
line-height
vertical-align
white-space
font-size
優化點:使用不觸發迴流的方案替代觸發迴流的方案
color
border-style
、border-radius
visibility
text-decoration
background
、background-image
、background-position
、background-repeat
、background-size
outline
、outline-color
、outline-style
、outline-width
box-shadow
DOM
後分割爲多個圖層Recalculate style
樣式重計算)Layout
迴流和重佈局)Paint Setup
和Paint
重繪
)gpu
Composite Layers
圖層重組)DOM
的過程是這樣子的:layer
),將每一個層獨立地繪製進位圖(bitmap
)中texture
)上傳至 GPU
,複合(composite
)多個層來生成最終的屏幕圖像left/top/margin
之類的屬性會影響到元素在文檔中的佈局,當對佈局(layout
)進行動畫時,該元素的佈局改變可能會影響到其餘元素在文檔中的位置,就致使了全部被影響到的元素都要進行從新佈局,瀏覽器須要爲整個層進行重繪並從新上傳到 GPU
,形成了極大的性能開銷。transform
屬於合成屬性(composite property
),對合成屬性進行 transition/animation
動畫將會建立一個合成層(composite layer
),這使得被動畫元素在一個獨立的層中進行動畫。texture
)上傳到 GPU
,只要該層的內容不發生改變,就不必進行重繪(repaint
),瀏覽器會經過從新複合(recomposite
)來造成一個新的幀。chrome
建立圖層的條件將頻繁重繪迴流的DOM元素單獨做爲一個獨立圖層,那麼這個DOM元素的重繪和迴流的影響只會在這個圖層中
3D
或透視變換CSS
屬性使用加速視頻解碼的 <video>
元素3D
(WebGL
) 上下文或加速的2D
上下文的 <canvas>
元素Flash
)opacity/transform
動畫的元素擁有加速CSS filters
的元素元素有一個包含複合層的後代節點(換句話說,就是一個元素擁有一個子元素,該子元素在本身的層裏)z-index
較低且包含一個複合層的兄弟元素(換句話說就是該元素在複合層上面渲染)
總結:對佈局屬性進行動畫,瀏覽器須要爲每一幀進行重繪並上傳到
GPU
中對合成屬性進行動畫,瀏覽器會爲元素建立一個獨立的複合層,當元素內容沒有發生改變,該層就不會被重繪,瀏覽器會經過從新複合來建立動畫幀
gif圖
迴流
、重繪
的CSS
屬性重繪
、迴流
的影響範圍限制在單獨的圖層(layers
)以內用translate
替代top
屬性
top
會觸發layout
,但translate
不會用opacity
代替visibility
opacity
不會觸發重繪也不會觸發迴流,只是改變圖層alpha
值,可是必需要將這個圖片獨立出一個圖層visibility
會觸發重繪DOM
的樣式,預先定義好class
,而後修改DOM
的className
把DOM
離線後修改,好比:先把DOM
給display:none
(有一次reflow
),而後你修改100次,而後再把它顯示出來不要把DOM
節點的屬性值放在一個循環裏當成循環的變量
offsetHeight
、offsetWidth
每次都要刷新緩衝區,緩衝機制被破壞不要使用table
佈局,可能很小的一個小改動會形成整個table
的從新佈局
div
只會影響後續樣式的佈局動畫實現的速度的選擇
performance
量化性能優化對於動畫新建圖層
啓用gpu
硬件加速(並行運算),gpu加速
意味着數據須要從cpu
走總線到gpu
傳輸,須要考慮傳輸損耗.
transform:translateZ(0)
transform:translate3D(0)
cookies
http
請求無狀態,因此須要cookie
去維持客戶端狀態cookie
的生成方式:
http
-->response header
-->set-cookie
js
中能夠經過document.cookie
能夠讀寫cookie
cookie
的使用用處:
expire
:過時時間cookie
的限制:
4kb
左右expire
httponly
不支持js
讀寫(防止收到模擬請求攻擊)優化點:cookie
中在相關域名下面
cdn
的流量損耗cdn
的域名和主站域名要分開localStorage
localstorage
HTML5
設計出來專門用於瀏覽器存儲的5M
左右sessionstorage
5M
左右indexedDB
IndexedDB
是一種低級API
,用於客戶端存儲大量結構化數據。該API
使用索引來實現對該數據的高性能搜索。雖然Web
Storage
對於存儲叫少許的數據很管用,但對於存儲更大量的結構化數據來講,這種方法不太有用。IndexedDB
提供了一個解決方案。爲應用建立離線版本
cdn
域名不要帶cookie
localstorage
存庫、圖片cookie
種在主站下,二級域名也會攜帶這個域名,形成流量的浪費
Service Worker
產生的意義PWA
與Service Worker
PWA
(Progressive Web Apps
)是一種Web App
新模型,並非具體指某一種前言的技術或者某一個單一的知識點,咱們從英文縮寫來看就能看出來,這是一個漸進式的Web App
,是經過一系列新的Web特性
,配合優秀的UI
交互設計,逐步加強Web App
的用戶體驗PWA
與Service worker
chrome
插件 lighthouse
檢測是否是一個漸進式
web app
特色
Engaging
):應用能夠被增長到手機桌面,而且和普通應用同樣有全屏、推送等特性service worker
service worker
是一個腳本,瀏覽器獨立於當前頁面,將其在後臺運行,爲實現一些不依賴頁面的或者用戶交互的特性打開了一扇大門。在將來這些特性將包括消息推送,背景後臺同步,geofencing
(地理圍欄定位),但他將推出的第一個首要的特性,就是攔截和處理網絡請求的能力,包括以編程方式來管理被緩存的響應。
chrome://serviceworker-internals/
chrome://inspect/#service-worker/
service worker
網絡攔截能力,存儲Cache Storage
,實現離線應用
indexedDB
callback && callback()寫法 至關於 if(callback){ callback(); }
cookie
、session
、localStorage
、sessionStorage
基本操做indexedDB
基本操做object store:對象存儲 自己就是結構化存儲
function openDB(name, callback) { //創建打開indexdb indexedDB.open var request = window.indexedDB.open(name) request.onerror = function(e) { console.log('on indexedDB error') } request.onsuccess = function(e) { myDB.db = e.target.result callback && callback() } //from no database to first version,first version to second version... request.onupgradeneeded = function() { console.log('created') var store = request.result.createObjectStore('books', { keyPath: 'isbn' }) console.log(store) var titleIndex = store.createIndex('by_title', 'title', { unique: true }) var authorIndex = store.createIndex('by_author', 'author') store.put({ title: 'quarry memories', author: 'fred', isbn: 123456 }) store.put({ title: 'dafd memories', author: 'frdfaded', isbn: 12345 }) store.put({ title: 'dafd medafdadmories', author: 'frdfdsafdafded', isbn: 12345434 }) } } var myDB = { name: 'tesDB', version: '2.0.1', db: null } function addData(db, storeName) { } openDB(myDB.name, function() { // myDB.db = e.target.result // window.indexedDB.deleteDatabase(myDB.name) }); //刪除indexedDB
indexDB
事務transcation
與 object store
創建關聯關係來操做object store
創建之初能夠配置
var transcation = db.transcation('books', 'readwrite') var store = transcation.objectStore('books') var data =store.get(34314) store.delete(2334) store.add({ title: 'dafd medafdadmories', author: 'frdfdsafdafded', isbn: 12345434 })
Service Worker
離線應用serviceworker
須要https
協議
ServiceWorker
與主頁面之間的通訊指望大規模數據能自動化緩存,而不是手動進行緩存,須要瀏覽器端和服務器端協商一種緩存機制
- Cache-Control所控制的緩存策略
- last-modified 和 etage以及整個服務端瀏覽器端的緩存流程
- 基於node實踐以上緩存方式
httpheader
可緩存性
public
:代表響應能夠被任何對象(包括:發送請求的客戶端,代理服務器,等等)緩存。private
:代表響應只能被單個用戶緩存,不能做爲共享緩存(即代理服務器不能緩存它)。no-cache
:強制全部緩存了該響應的緩存用戶,在使用已存儲的緩存數據前,發送帶驗證器的請求到原始服務器only-if-cached
:代表若是緩存存在,只使用緩存,不管原始服務器數據是否有更新到期
max-age=<seconds>
:設置緩存存儲的最大週期,超過這個時間緩存被認爲過時(單位秒)。與 Expires
相反,時間是相對於請求的時間。s-maxage=<seconds>
:覆蓋max-age
或者 Expires
頭,可是僅適用於共享緩存(好比各個代理),而且私有緩存中它被忽略。cdn
緩存max-stale[=<seconds>]
代表客戶端願意接收一個已通過期的資源。 可選的設置一個時間(單位秒),表示響應不能超過的過期時間。
min-fresh=<seconds>
表示客戶端但願在指定的時間內獲取最新的響應。
從新驗證
和從新加載
從新驗證
must-revalidate
:緩存必須在使用以前驗證舊資源的狀態,而且不可以使用過時資源。proxy-revalidate
:與must-revalidate
做用相同,但它僅適用於共享緩存(例如代理),並被私有緩存忽略。immutable
:表示響應正文不會隨時間而改變。資源(若是未過時)在服務器上不發生改變,所以客戶端不該發送從新驗證請求頭(例如If-None-Match
或If-Modified-Since
)來檢查更新,即便用戶顯式地刷新頁面。在Firefox
中,immutable
只能被用在 https:// transactions
.從新加載
no-store
:緩存不該存儲有關客戶端請求或服務器響應的任何內容。no-transform
:不得對資源進行轉換或轉變。Content-Encoding
, Content-Range
, Content-Type
等HTTP
頭不能由代理修改。例如,非透明代理能夠對圖像格式進行轉換,以便節省緩存空間或者減小緩慢鏈路上的流量。 no-transform
指令不容許這樣作。Expires
expires
是http1.0
的時候的http1.1
時候,咱們希望cache
的管理統一進行,max-age
優先級高於expires
,當有max-age
在的時候expires
可能就會被忽略。cache-control
時候會使用expires
Last-modified
和If-Modified-since
last-modified
--> response header
if-modified-since
--> request header
cache-control
共同使用
last-modified
有什麼缺點?
Etag
和 If-none-match
etag
-->reponse header
if-none-match
-->request header
cache-control
共同使用好處:
if-modified-since
更加準確etage
更高服務端用的node.js由於和前端用的同一種語言,能夠利用服務端運算能力來進行相關的運算而減小前端的運算
vue
渲染遇到的問題vue-ssr
和原理和引用先加載vue.js => 執行vue.js代碼 => 生成html
之前沒有前端框架時,
jsp/php
在服務端進行數據的填充,發送給客戶端就是已經
填充好數據`的htmljQuery
異步加載數據使用React
和Vue
前端框架
runtime
,compile
拆開,構建層作模板編譯工做。webpack
構建時候,統一,直接編譯成runtime
能夠執行的代碼prerender
的方式