新聞中心
最近更新了我們的網(wǎng)站,它是經(jīng)過(guò)了設(shè)計(jì)上的全面驗(yàn)收的。但實(shí)際上,作為軟件開(kāi)發(fā)者,我們會(huì)注重很多技術(shù)相關(guān)的零碎的東西。我們的目標(biāo)是控制性能,注重性能,未來(lái)可伸展,為網(wǎng)站增添內(nèi)容是一種樂(lè)趣。接著就來(lái)告訴你,為什么我們的網(wǎng)站速度比你們的快吧(抱歉,確實(shí)是這樣的)。

目前創(chuàng)新互聯(lián)已為上千余家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)站空間、綿陽(yáng)服務(wù)器托管、企業(yè)網(wǎng)站設(shè)計(jì)、萬(wàn)柏林網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。
性能設(shè)計(jì)
在我們的項(xiàng)目中,我們每天都會(huì)和設(shè)計(jì)師和產(chǎn)品負(fù)責(zé)人討論關(guān)于平衡美觀和性能的問(wèn)題。對(duì)于我們自己的網(wǎng)站,這樣做是很簡(jiǎn)單的。簡(jiǎn)言之,我們認(rèn)為好的用戶體驗(yàn)從快速的內(nèi)容傳輸開(kāi)始,也就意味著 性能 > 美觀。
好的內(nèi)容、布局、圖片和交互是吸引用戶的重要因素。這每個(gè)因素都會(huì)影響頁(yè)面的加載時(shí)間和終端用戶體驗(yàn)。每一步我們都在探討如何在獲得好的用戶體驗(yàn)和保證設(shè)計(jì)美感的同時(shí),最小化對(duì)性能的影響。
內(nèi)容優(yōu)先
我們想要把核心內(nèi)容盡快地呈現(xiàn)給用戶,意味著我們要處理好基本的 HTML 和 CSS。每個(gè)頁(yè)面都應(yīng)該達(dá)到基本的目的:傳遞信息。JS、CSS、網(wǎng)頁(yè)字體、圖片、網(wǎng)站分析等優(yōu)化都是位居于核心內(nèi)容之下的。
可控性
給理想網(wǎng)站定義了標(biāo)準(zhǔn)后,我們總結(jié)出:要想達(dá)到預(yù)期效果,就要能對(duì)網(wǎng)站各方面的控制都游刃有余。我們選擇構(gòu)建自己的靜態(tài)站點(diǎn)生成器,包括資源傳輸,并且由我們自己操控。
靜態(tài)站點(diǎn)生成器
我們用 Node.js 實(shí)現(xiàn)了靜態(tài)站點(diǎn)生成器。它是采用帶有簡(jiǎn)短 JSON 頁(yè)面描述標(biāo)簽的 Markdown 文件來(lái)生成整個(gè)網(wǎng)站結(jié)構(gòu)和它所有的資源。為了包括特殊的頁(yè)面腳本,也可以附帶一個(gè) HTML 文件。以下是一個(gè)簡(jiǎn)單化的描述標(biāo)簽和 markdown 文件,用于博客的發(fā)布,用它來(lái)生成真正的 HTML。
- JSON 描述標(biāo)簽:
- {
- "keywords": ["performance", "critical rendering path", "static site", "..."],
- "publishDate": "2016-07-13",
- "authors": ["Declan"]
- }
markdown 文件:
- # Why our website is faster than yours
- We've recently updated our site. Yes, it has a complete...
- ## Design for performance
- In our projects we have daily discussions...
圖片傳輸
平均一個(gè) 2406kb 的網(wǎng)頁(yè)中 1535kb 是圖片。就因?yàn)閳D片在網(wǎng)站中占據(jù)了這么大的一個(gè)比例,所以它也是性能優(yōu)化的重點(diǎn)之一。
WebP格式
WebP是一種現(xiàn)代圖片格式,為網(wǎng)頁(yè)圖片提供了出色的低損耗、有損壓縮。WebP格式的圖片實(shí)質(zhì)上比其它格式的小,有時(shí)可以比同樣的 JPEG 圖片小 25%。 WebP被大多數(shù)人所忽略,也沒(méi)被經(jīng)常使用。截止到寫(xiě)這篇文章的時(shí)候,WebP 僅支持Chrome, Opera 和 Android (仍超過(guò)了我們50%的用戶),但我們可以優(yōu)雅降級(jí)為 JPG/PNG。
使用
我們使用Scott Jehl 的 picturefill 來(lái)使那些不支持
我們使用 作為那些不支持
生成
盡管圖片傳輸方式已經(jīng)確定了,我們?nèi)孕枰伎荚撛鯓佑行У貓?zhí)行。我喜歡
生成圖片
在構(gòu)建過(guò)程中,原圖片的多個(gè)實(shí)例,包括JPG, PNG和WebP格式,我們使用 gulp responsive 來(lái)生成。
最小化圖片
在markdown文件中寫(xiě)[圖片描述](image.jpg).
在構(gòu)建過(guò)程中使用自定義Markdown渲染器來(lái)為已經(jīng)完全成熟的
SVG動(dòng)畫(huà)
我們?yōu)樽约旱木W(wǎng)站選擇了特定的圖標(biāo)類(lèi)型,其中SVG插圖占了主要地位。這樣做有以下幾個(gè)原因:
- 首先,SVG的圖片比位圖更小;
- 其二,SVG圖片本身就是響應(yīng)式的,有很棒的伸縮性, 所以不需要圖片生成及
元素; - 最后也是很重要的一點(diǎn),就是我們可以通過(guò)CSS來(lái)不斷改變它,賦予它新的活力!我們所有的組合頁(yè)面都有一個(gè)自定義的動(dòng)態(tài)SVG圖, 可以被概述頁(yè)面所復(fù)用。這張圖片作為我們所有組合頁(yè)面的一種循環(huán)風(fēng)格,使得頁(yè)面設(shè)計(jì)一體化,同時(shí)又幾乎不會(huì)對(duì)性能造成影響。請(qǐng)看這張動(dòng)畫(huà),看看我們是如何用CSS來(lái)改變它的。
自定義網(wǎng)頁(yè)字體
在深入之前,這里有一個(gè)關(guān)于在瀏覽器設(shè)置自定義字體的簡(jiǎn)短介紹。當(dāng)瀏覽器發(fā)現(xiàn)CSS里面有@font-face 的定義,但是用戶的電腦并不支持該字體時(shí),它會(huì)嘗試下載該字體文件。在下載時(shí),多數(shù)瀏覽器根本不會(huì)用這種字體來(lái)展示文本。這種現(xiàn)象稱為“不可見(jiàn)文本的閃現(xiàn)” 或者 FOIT。如果你有留意,你會(huì)發(fā)現(xiàn)網(wǎng)頁(yè)上都有這種情況存在。如果你問(wèn)我,我會(huì)告訴你這會(huì)影響用戶體驗(yàn)。它延遲了用戶讀取他們所需內(nèi)容的時(shí)間。我們可以迫使瀏覽器改變這種行為,變成 “無(wú)樣式內(nèi)容閃現(xiàn)” 或者稱為 FOUT。我們告訴瀏覽器先使用普通字體,像 Arial 或者 Georgia。當(dāng)自定義的字體下載完成后,再代替標(biāo)準(zhǔn)字體并且重新渲染。這樣,即使自定義字體下載失敗,仍然不會(huì)影響內(nèi)容的可讀性。然而,有人會(huì)認(rèn)為這是一種妥協(xié)的做法,但我們認(rèn)為自定義字體只是一種優(yōu)化。盡管沒(méi)有自定義字體,網(wǎng)頁(yè)看起來(lái)也完好,也能百分百的正常運(yùn)行。勾選/不勾選復(fù)選框來(lái)切換我們的網(wǎng)頁(yè)字體,來(lái)自己體驗(yàn)一下:
切換下載的字體類(lèi)
使用自定義網(wǎng)頁(yè)字體可以改善我們的用戶體驗(yàn),只要你能夠優(yōu)化他們,并且負(fù)責(zé)任地為之服務(wù)。
字型子集設(shè)定
到目前為止,子集設(shè)定是改善網(wǎng)頁(yè)字體性能最快的方式。我將會(huì)向每個(gè)使用自定義字體的網(wǎng)頁(yè)開(kāi)發(fā)者推薦它。如果你能完全控制網(wǎng)頁(yè)內(nèi)容,并且知道它將要展示哪些特性的話,你可以完全使用子集設(shè)定。但是,即使是僅僅把字體設(shè)為西方語(yǔ)言,也會(huì)對(duì)文件大小造成很大的影響。例如,我們的 Noto Regular WOFF 字體,默認(rèn)是246KB,將其設(shè)為西方語(yǔ)言后,大小下降到31KB。我們使用 Font squirrel webfont, 這種字體真的很易用。
字體監(jiān)聽(tīng)器
Bram Stein 推出的字體監(jiān)聽(tīng)器是一個(gè)很了不起的腳本,可以幫助檢查字體是否已被加載。至于你是如何加載字體的,是通過(guò)一個(gè)網(wǎng)頁(yè)字體服務(wù),還是自己上傳就不可知了。在這個(gè)監(jiān)聽(tīng)器告訴我們所有自定義的字體已經(jīng)下載完畢后,我們就可以在 元素上添加一個(gè)字體加載完畢的類(lèi),我們的頁(yè)面就會(huì)重新用新的字體:
- html {
- font-family: Georgia, serif;
- }
- html.fonts-loaded {
- font-family: Noto, Georgia, serif;
- }
注意: 為了簡(jiǎn)短,我沒(méi)有給上面CSS中的 Noto 加上 @font-face 的聲明。
我們可以設(shè)定一個(gè)cookie來(lái)記住所有的字體已經(jīng)被加載過(guò),就可以讓他們緩存在瀏覽器里面了。我們使用這個(gè)cookie來(lái)做重復(fù)的瀏覽,這個(gè)我后續(xù)會(huì)解釋。
在不久的將來(lái),我們或許不需要 Bram Stein 的腳本來(lái)監(jiān)聽(tīng)這個(gè)行為。CSS開(kāi)發(fā)團(tuán)隊(duì)已經(jīng)提案一個(gè)新的 @font-face 描述器,也叫font-display。它的屬性值控制著一個(gè)可下載的字體是如何在還沒(méi)加載出來(lái)時(shí)就渲染頁(yè)面的。這是CSS對(duì)font-display的描述:它將帶給我們像上面方法一樣的行為效果。你可以讀讀更多關(guān)于 font-display 的屬性。
JS和CSS懶加載
一般來(lái)講,我們都是盡可能快的加載需要的資源。我們移除一些堵塞的請(qǐng)求來(lái)加快頁(yè)面渲染,優(yōu)化首屏,用瀏覽器緩存來(lái)處理重復(fù)的頁(yè)面。
JS懶加載
設(shè)計(jì)上,我們的網(wǎng)站并沒(méi)有很多JS。我們發(fā)展了一個(gè)JavaScript工作流來(lái)處理我們目前已有的js, 以及未來(lái)會(huì)用到的js資源。
JS在
塊里面渲染,這是我們想要的。JS應(yīng)該只是用來(lái)提高用戶體驗(yàn),不應(yīng)該是訪問(wèn)者需要的關(guān)鍵。處理JS堵塞渲染的簡(jiǎn)單方法就是把腳本放在頁(yè)面的尾部。這樣網(wǎng)頁(yè)就會(huì)在整個(gè)HTML 渲染完畢后才去加載JS。另一種可以把腳本放在 head 執(zhí)行的方案是在
我們把這小段腳本放在頁(yè)面頭部,來(lái)檢測(cè)瀏覽器是否支持原生JavaScript的 document.querySelector 和 window.addEventListener屬性。如果支持,我們通過(guò)
Apache 服務(wù)端邏輯看起來(lái)像一行一行的備注,一般以 如果是true的話,我們就假定這是用戶的第一次瀏覽。
第一次瀏覽我們添加了
我們添加了一個(gè)行內(nèi)的腳本來(lái)懶加載CSS,onloadCSS 回調(diào)里面可以設(shè)置cookies.
在同一份腳本里面,我們異步加載了整份CSS。
在 onloadCSS的回調(diào)里面,我們用版本號(hào)來(lái)設(shè)置cookie的值。
在這個(gè)腳本后面,我們添加了一行關(guān)鍵CSS的樣式。這個(gè)會(huì)阻塞渲染,但時(shí)間是非常短的,而且可以避免頁(yè)面展示出來(lái)只有純粹的HTML而沒(méi)有樣式的情況。
聲明(意味著 css-loaded 的cookie 已經(jīng)存在)用戶重復(fù)瀏覽。因?yàn)槲覀兛梢詮哪撤N程度上來(lái)假定,CSS文件之前已經(jīng)被加載過(guò)了,我們可以利用瀏覽器緩存來(lái)提供樣式表。這樣從緩存里面加載速度就很快了。同樣的方法也被用來(lái)在第一次異步加載字體,后續(xù)的重復(fù)瀏覽也是從緩存里面獲取字體。
這就是我們第一次和重復(fù)瀏覽時(shí),我們用來(lái)區(qū)分的cookies。
文件級(jí)緩存
由于我們?cè)谥噩F(xiàn)頁(yè)面時(shí)很大程度上依賴于瀏覽器緩存,所以我們需要確認(rèn)我們的緩存是否合理。理想中我們是要永遠(yuǎn)的存儲(chǔ)資源(CSS、js、 字體、圖片),只有當(dāng)這些文件被修改時(shí)才需要更新。當(dāng)請(qǐng)求的URL是唯一時(shí),緩存就會(huì)失效。每更新一個(gè)版本,我們都會(huì)用 git tag 打個(gè)標(biāo)簽。所以最簡(jiǎn)單的方式就是給我們請(qǐng)求的URL加上一個(gè)參數(shù)(代碼版本號(hào)),如https://www.voorhoede.nl/assets/css/main-8af99277a6.css?v=1.0.4.。
但是,這種做法的缺點(diǎn)就是當(dāng)我們要寫(xiě)一個(gè)新的博客post(這也是我們代碼庫(kù)的一部分,并沒(méi)有永久地存儲(chǔ)在CMS),原來(lái)緩存的資源將會(huì)失效,盡管沒(méi)有改變?cè)瓉?lái)那些資源。
就在我們嘗試去改善這種方法時(shí),我們發(fā)現(xiàn)了 gulp-rev 和 gulp-rev-replace 。這些腳本會(huì)自動(dòng)合理地在我們的文件名稱后面添加一竄hash值。這意味著只有實(shí)際上文件被改變時(shí),才會(huì)去改變請(qǐng)求的URL,這樣每個(gè)文件的緩存就會(huì)自動(dòng)失效。這種做法讓我興奮不已啊!
結(jié)果
如果你看到這里,你應(yīng)該是想要知道結(jié)果的。測(cè)試網(wǎng)頁(yè)的性能可以采用像 PageSpeed Insights 這樣的工具,它有很實(shí)用的提示。也可以使用 WebPagetest來(lái)測(cè)試,有擴(kuò)展性的網(wǎng)絡(luò)分析。我認(rèn)為測(cè)試網(wǎng)頁(yè)渲染性能的最好方法就是在瘋狂地遏制網(wǎng)絡(luò)通信時(shí)來(lái)觀察網(wǎng)頁(yè)的進(jìn)程。這意味著,用一種不切實(shí)際的方法來(lái)遏制通信。在谷歌瀏覽器,你可以這樣操作 (via the inspector > Network tab) 來(lái)限制通信,觀察網(wǎng)頁(yè)形成過(guò)程中,請(qǐng)求是如何緩慢加載的。
下面是我們的網(wǎng)頁(yè)在 50KB/s 的情況下的加載狀況。
這是 de Voorhoede site 首屏的網(wǎng)絡(luò)分析,是網(wǎng)頁(yè)第一次進(jìn)程的一個(gè)概覽。
注意到在50KB/s的網(wǎng)速中,我們是如何讓首屏的渲染只用了 2.27 秒的。也就是第一張幻燈片和瀑布圖里面的黃色線所代表的位置。黃線恰好繪在就是HTML已經(jīng)加載完的時(shí)間位置。HTML包含了關(guān)鍵CSS,保證頁(yè)面的可觀性。所有其他的CSS都是用懶加載,所以我們可以等到全部資源加載完時(shí)才與頁(yè)面進(jìn)行交互。這也是我們想要的效果!
另一個(gè)值得注意的就是自定義字體從來(lái)不在這緩慢的鏈接上加載。 font face 觀察器會(huì)自動(dòng)注意到這一點(diǎn)。但是,如果我們不異步加載字體,你注視大多數(shù)瀏覽器,都會(huì)出現(xiàn) FOIT(不可見(jiàn)文本的閃現(xiàn),上文有提及)的情況。
所有的CSS文件僅在8s后就都加載完畢。相反,如果我們不采用加載關(guān)鍵CSS的方式,而是采用加載全部CSS,我們?cè)谇?秒看到的將會(huì)是空白的頁(yè)面。
如果你感到好奇,想與那些不太注重性能的網(wǎng)站對(duì)比一下加載時(shí)間,那趕緊試試吧。那個(gè)時(shí)間肯定是飛漲啊!
用上面介紹的工具測(cè)試了我們的網(wǎng)站,結(jié)果也是讓人滿意的。 PageSpeed insights 在移動(dòng)性能方面給了我們100分,多么了不起啊!
PageSpeed insights 對(duì) voorhoede.nl的測(cè)試結(jié)果! 速度100分!
當(dāng)我們查看 WebPagetest 時(shí),我們得到下面這樣的結(jié)果:
WebPagetest 對(duì) voorhoede.nl的檢測(cè)結(jié)果
可以看出,我們的服務(wù)器運(yùn)行良好,首屏的速度指標(biāo)是693。 這意味著我們的頁(yè)面在693毫秒后就可以在寬屏纜線下被使用了。
技術(shù)路線
我們這樣還不算完成,還會(huì)不斷地重復(fù)我們的方法。我不久的將來(lái),我們會(huì)主要關(guān)注以下內(nèi)容:
HTTP/2
目前我們正在試驗(yàn)HTTP/2。本文所描述的大多數(shù)東西都是基于 HTTP/1.1 權(quán)限內(nèi)的最好實(shí)踐。簡(jiǎn)言之,HTTP/1.1 要追述到1999年,那時(shí) table布局和行內(nèi)樣式都如火如荼。HTTP/1.1 從沒(méi)為 2.6MB的網(wǎng)頁(yè)要接受200個(gè)請(qǐng)求而設(shè)計(jì)。為了減輕舊版協(xié)議帶來(lái)的痛楚,我們結(jié)合JS、CSS、關(guān)鍵性CSS,還為小圖片設(shè)置數(shù)據(jù)源URI等。用各種方法來(lái)節(jié)省請(qǐng)求。自從 HTTP/2 可以在同一個(gè)TCP鏈接上平行地運(yùn)行多個(gè)請(qǐng)求后,所有的這些聯(lián)結(jié)使用和減少請(qǐng)求的做法都可能成為反面模式了。當(dāng)我們跑完這個(gè)實(shí)驗(yàn)后,我們將會(huì)采用 HTTP/2 協(xié)議。
Service Workers
這是一個(gè)在后臺(tái)運(yùn)行的現(xiàn)代瀏覽器的 JavaScript API。它擁有很多特性,這些特性在以前的網(wǎng)站上都是沒(méi)有的,如離線支持、消息推送、背景同步等。我們現(xiàn)在正嘗試用 Service Worker, 但還是得在我們自己的網(wǎng)站上實(shí)現(xiàn)先。我向你保證,我們會(huì)做到的!
CDN
因此,我們想要自己控制和部署我們的網(wǎng)站。而且現(xiàn)在我們也要采用CDN來(lái)擺脫由服務(wù)端和客戶端實(shí)際距離所帶來(lái)的網(wǎng)絡(luò)問(wèn)題。盡管我們的用戶基本上都是荷蘭的,我們也想向世界的前端社區(qū)反映我們?cè)谫|(zhì)量、性能和推動(dòng)網(wǎng)絡(luò)發(fā)展方面做的最好。
網(wǎng)站名稱:如何運(yùn)用新技術(shù)提升網(wǎng)頁(yè)速度和性能
文章轉(zhuǎn)載:http://m.fisionsoft.com.cn/article/dpceccp.html


咨詢
建站咨詢
