閱讀理由:經驗之談,從理論到實踐。javascript
網站優化是前端開發的重中之重,可是優化細節卻十分繁雜,沒有好的思路,優化很難高效的開展。css
本文將以實際網站來作參考,手把手教你如何一步步作好網站優化。html
這不是一篇 基礎網站優化 文章,繼續下文前,請肯定已經作了以下基本優化:前端
iframe
使用src
爲空HTTP
請求數咱們能夠從兩個角度來看這個問題:java
網站優化可以讓頁面加載得更快,響應更加及時,極大提高用戶體驗。react
優化會減小頁面資源請求數,減少請求資源所佔帶寬大小,從而節省可觀的帶寬資源。webpack
網站優化的目標是:減小網站加載時間,提升響應速度。
那麼網站加載速度和用戶體驗又有着怎樣的關係呢?咱們來看下面這張圖:nginx
Google 和亞馬遜的研究代表,Google 頁面加載的時間從 0.4
秒提高到 0.9
秒致使丟失了 20%
流量和廣告收入,對於亞馬遜,頁面加載時間每增長 100ms
就意味着 1%
的銷售額損失。git
可見,頁面的加載速度對於用戶有着相當重要的影響。
一個好的交互效果多是這樣的:github
. ├── favicon.ico ├── index.html ├── manifest.json ├── static │ ├── DIN-Medium.1bbe3460.otf │ ├── DIN-Regular.799221d7.otf │ └── logo.c57d38d0.png ├── umi.css ├── umi.css.map ├── umi.js └── umi.js.map
須要注意:生產環境不要開啓 SOURCEMAP
Waterfall
TTFB
全稱 Time To First Byte
:是指網絡請求被髮起到從服務器接收到第一個字節的這段時間,它包含了 TCP
鏈接時間、發送 HTTP
請求時間和得到響應消息第一個字節的時間。
Content Download:即下載內容所須要的時間。
頁面一接口狀況:
頁面二接口狀況:
用戶下載內容所須要的時間,受限於服務器的資源、資源的大小以及用戶的網絡速度。所以,咱們暫時不討論這方面的內容。
經過 webpack
打包,分析一下大文件構成。
YSlow
或者 PageSpeed
咱們能夠經過 Google PageSpeed Insights API Extension
來對網站總體性能 作一下評估,按照建議去作一些高效優化。
加載時間概況:
影響網站加載因素:
緩存策略問題:
DOM 節點:
關鍵路徑:
主線程狀況:
eruda
,線上環境是不須要的 ✓svg
✓建議使用 webpack-spritesmith
,簡單使用以下:
plugins: [ new SpritesmithPlugin({ src: { cwd: path.resolve(__dirname, 'src/ico'), glob: '*.png' }, target: { image: path.resolve(__dirname, 'src/spritesmith-generated/jartto.png'), css: path.resolve(__dirname, 'src/spritesmith-generated/jartto.styl') }, apiOptions: { cssImageRef: "~jartto.png" } }) ]
從上圖分析得出,大文件主要包含:dist.js
、lottie.js
、lodash.js
、loading.json
等文件。因此咱們從這幾個文件入手,逐個優化:
moment.js
- 配置 moment
忽略本地化,可減小 70kb
ignoreMomentLocale: true
dist.js
- 在給單頁應用作按需加載優化時,通常採用如下原則:
Chunk
,按需加載對應的 Chunk
。Chunk
中,以下降用戶能感知的網頁加載時間。Chart.js
去畫圖表、依賴 flv.js
去播放視頻的功能點,可再對其進行按需加載。lottie.js
- 分離減小 60kb
externals: { lottie : 'react-lottie', }
lodash.js
externals: { lodash : { commonjs: 'lodash', amd: 'lodash', root: '_' // indicates global variable } }
動態導入以及文件拆分
dynamicImport: { webpackChunkName: true, loadingComponent: './components/Loading/jartto.js', }
按照上面咱們一步步處理後,從新打包分析一下文件構成:
這裏爲何沒有繼續拆分 dist.js
,是由於目前階段沒有好的方案,須要對代碼作不少調整,因此暫且保留。相關信息能夠在 Ant-Design Issuse
Svg icons make bunlde size too large 中查看解決方案。
CDN
loading.json
大小54kb ✓svg
替換 2
倍圖 ✓TTFB
DNS
查詢CDN
Flush
css
預加載 preload
<link rel="preload">
異步加載第三方資源
<script async src="https://cdn.jartto.wang/fastclick.js"></script>
沒有 async
屬性,script
將當即獲取(下載)並執行,期間阻塞了瀏覽器的後續處理。
若是有 async
屬性,那麼 script
將被異步下載並執行,同時瀏覽器繼續後續的處理。
利用 font-display
這項 CSS
功能,確保文本在網頁字體加載期間始終對用戶可見。
@font-face { font-family: 'Arvo'; font-display: auto; src:local('Arvo'),url(https://fonts.jartto.wang/fonts/temp.woff2)format('woff2'); }
延長緩存期限可加快重訪網頁的速度。
DNS TTL(Time-To-Live)
簡單的說:它表示一條域名解析記錄在 DNS
服務器上的緩存時間。
DNS
服務器接受到解析請求時,就會向域名指定的 DNS
服務器發出解析請求從而得到解析記錄。DNS
服務器中保存一段時間,這段時間內若是再接到這個域名的解析請求,DNS
服務器將再也不向 DNS
服務器發出請求,而是直接返回剛纔得到的記錄。這個記錄在DNS
服務器上保留的時間,就是TTL
值。
因此通常更新域名解析的步驟以下:
TTL
值。TTL
值爲可設定的最小值,建議爲 60
秒。DNS
服務器緩存都過時並更新了記錄。DNS
解析到新的記錄,這個時候各地的 DNS
就能以最快的速度更新到新的記錄。DNS
已經更新完成後,再 TTL
值設置成經常使用的值(如: TTL=86400
)。以下圖,TTL
值設置的最佳實踐,可供參考:
後文咱們會詳細介紹
DNS
相關內容,歡迎各位童鞋關注。
DOM
規模過大DOM
節點最好少於 1500
個左右。32
個元素,且少於 60
個子/父元素。DOM
可能會增長內存使用量、致使樣式計算用時延長併產生高昂的佈局重排費用。
關鍵請求鏈
顯示了以高優先級加載的資源。
咱們能夠經過:縮短鏈長、縮減資源的下載文件大小,或者推遲下載沒必要要的資源,從而提升網頁加載速度。
當 HTML
解析過程當中遇到一個 script
標記時,它會暫停 DOM
構建,將控制權移交給 JavaScript
引擎,等 JavaScript
引擎運行完畢,瀏覽器再從中斷的地方恢復 DOM
構建。
也就是說,執行內聯的 JavaScript 會阻塞頁面的首次渲染。
在關鍵渲染路徑中,咱們一般要關注三個點:
Roundtrip
)。咱們的策略也很是簡單,就是減小關鍵資源數量,下降資源大小,減小關鍵路徑的往返次數。
優化關鍵渲染路徑的常規步驟以下:
更多詳情,請參考前端性能優化—關鍵渲染路徑。
考慮減小爲解析、編譯和執行 JS
而花費的時間。咱們能夠提供較小的 JS
負載來實現此目標。
nginx
gzip
配置gzip on; gzip_min_length 1k; gzip_buffers 4 8k; gzip_http_version 1.1; gzip_comp_level 4; gzip_types text/plain text/css application/json image/png image/x-icon application/javascript application/x-javascript text/javascript text/xml application/xml application/xml+rss text/cache-manifest application/octet-stream; gzip_vary on;
nginx
開啓緩存若是你對瀏覽器緩存還不太清楚,歡迎移步聊一聊瀏覽器緩存機制。
location ~.*\.(html|htm|js|css|gif|jpg|jpeg|png|bmp|swf|ico|json|otf)$ { root /var/www/jartto_web/; index index.html; expires 1d; }
Nginx
能很是有效地直接處理靜態內容。在靜態文件和Nginx
在同一主機的狀況下,這種特性尤其有用。
優化前:網站評分 27 ,首次內容繪製 6.9 秒
網站評分:
加載概況:
優化後:網站評分 70 ,首次內容繪製 1.6 秒
網站評分:
加載概況:
固然,優化還能夠作更多,咱們儘可能讓網站的評分接近 100 分,譬如:
網站評分:
加載概況:
咱們從頭優化下來,作了很多代碼改動,也達到了不錯的效果。可是有幾點仍是須要注意:
骨架圖解決 webview
加載頁面過長的白屏過程。
TTFB
服務端接口也須要同步優化,而不要僅僅依賴前端單方面優化。
css
預加載font
預加載js
預加載DNS
和 CDN
DNS
預解析網站優化歷來不是一蹴而就,須要不斷的去優化細節,不斷的摸索嘗試。從個人角度來看,其實優化更像是在網站性能和加載速度之間找到一個平衡點。譬如,文中咱們爲了優化文件打包大小,進行了大文件拆分。隨之而來的問題就是拆分後的文件可能還會對某些文件有依賴,那麼就影響到了關鍵渲染路徑。
因此,優化不存在什麼奇技淫巧,不斷的去嘗試,找到這個最佳優化點,這纔是根本。
轉載自: Jartto's blog
做者:jartto