少妇放荡的呻吟干柴烈火免费视频,80S国产成年女人毛片,日本真人边吃奶边做爽免费视频 ,最近最新的字幕mv

歡迎來到海淘科技官網(wǎng) 官方微信 官方微博 平面活動官網(wǎng)
微信

網(wǎng)絡(luò)傳播媒介服務(wù)提供商

熱線電話

021-62677988

海淘新聞
首頁 > 新聞列表 > 2016年京東首頁改版前端回顧

2016年京東首頁改版前端回顧

發(fā)布時間: 2017-01-03 16:47

整體架構(gòu)

最初聽說要做新版京東首頁的時候,是懷有一絲惶恐的,畢竟是作為京東的門戶,其重要性和受關(guān)注程度自然不言而喻,一行代碼的失誤可能會造成不可挽回的后果,而且過去的首頁無論性能,還有體驗在業(yè)界都已經(jīng)是做得非常優(yōu)秀了,要再想有些出彩的地方,也是十分困難,所以綜上就是壓力山大。當(dāng)然,花開兩朵,咱們單表一枝,本文主要還是相對這次改版工作中提煉的工作方法和優(yōu)化方式做出一定的總結(jié)。

這次改版,在前端架構(gòu)上大體還是沿用過去的架構(gòu),使用 jQuery + Seajs 這種古老的開發(fā)方式,因為首頁還依賴著許多舊的系統(tǒng)與組件,無法在短時間內(nèi)對基礎(chǔ)架構(gòu)進行升級,當(dāng)然并不是說舊的就不好,要去盲目追求一些新的東西,而是這種架構(gòu)還是有可以提升的地方。

而整個項目的架構(gòu)是經(jīng)歷之前業(yè)務(wù)進行總結(jié)提煉出來的

Athena前端工程化工具,是我們團隊自己探索開發(fā)的一套基于NodeJs的命令行式前端工程化工具,解決了自動化編譯、代碼處理、依賴分析、文件壓縮等前端開發(fā)中的常規(guī)問題,有效地提升了我們的工作效率,解放生產(chǎn)力,目前已經(jīng)應(yīng)用于我們團隊的多個業(yè)務(wù)中,首頁改版也使用 Athena來進行開發(fā);

Athena管理平臺,是Athena工具配套的管理后臺,它會收集本地工具操作中上報的統(tǒng)計數(shù)據(jù),包括項目、模塊、頁面、組件創(chuàng)建的信息,文件、資源依賴關(guān)系的信息等,通過這些數(shù)據(jù)來進行項目和資源的管理,同時提供了項目模板,方便使用本地工具創(chuàng)建項目時選擇,具體可以參考之前的博文我們是如何做好前端工程化和靜態(tài)資源管理;

Athena組件平臺,是基于Athena總結(jié)的一套業(yè)務(wù)組件的平臺,可以很好地管理我們的業(yè)務(wù)組件,方便組件的復(fù)用和傳播;

Athena基礎(chǔ)庫及組件庫,是業(yè)務(wù)中總結(jié)出的基于jQuery + Seajs的js庫,簡化業(yè)務(wù)開發(fā),提供完整的框架;

Athena模擬接口,可以自由編輯生成指定接口的假數(shù)據(jù),用于開發(fā)時真實接口的替代,讓開發(fā)不再依賴后端接口;

Athena兜底接口服務(wù),可以指定接口生成一份兜底數(shù)據(jù)接口,平臺會定時去抓取指定接口數(shù)據(jù),然后生成兜底數(shù)據(jù)到CDN,從而生成對應(yīng)的兜底接口,這樣讓正常接口多一份兜底保障;

Athena前端監(jiān)控,通過在頁面中進行埋點上報的方式,我們可以在監(jiān)控系統(tǒng)中,實時地看到性能相關(guān)數(shù)據(jù)。我們進行上報的不止有頁面性能、速度相關(guān)的數(shù)據(jù),同時會上報用戶的環(huán)境信息,例如操作系統(tǒng)、瀏覽器、網(wǎng)速等,而且還會對頁面中錯誤信息進行上報,如模塊的隱藏等,通過這些數(shù)據(jù),對我們的業(yè)務(wù)進行實時地監(jiān)控與分析。

在我們的架構(gòu)中,各種各樣的工具與系統(tǒng)相輔相成,覆蓋到了開發(fā)到上線的各個環(huán)節(jié),自成一套體系。這樣的架構(gòu)不止是針對首頁這個業(yè)務(wù)的,而是在基于對之前業(yè)務(wù)開發(fā)總結(jié)的基礎(chǔ)上進行完善、調(diào)整的架構(gòu),適用于我們各個業(yè)務(wù)。而這次首頁的改版中,我們對開發(fā)模式、性能優(yōu)化、體驗優(yōu)化都進行了一些新的探索,讓我們對于業(yè)務(wù)開發(fā)的整體解決方案又有了新的改進。

開發(fā)模式

Athena

開發(fā)效率的提升是我們一直追求的,工欲善其事,必先利其器,我們通過總結(jié)以往的開發(fā)工作,提出了各種手段來優(yōu)化我們的開發(fā)效率,前端工具Athena就是其中的一個產(chǎn)物,當(dāng)然它又不僅僅是為了提升開發(fā)效率而已,它是我們總結(jié)出的一套針對前端開發(fā)的完整解決方案,可以讓我們的整體開發(fā)流程更加簡單明了。

Athena提供了統(tǒng)一的項目架構(gòu),根據(jù)業(yè)務(wù)功能不同,我們將一個項目(app)拆分成不同的業(yè)務(wù)模塊(module),而每一個模塊都包含自身的頁面(page)以及構(gòu)成頁面所需要的組件(widget)。

項目架構(gòu)

在本地使用Athena創(chuàng)建完整的項目結(jié)構(gòu),隨后我們就可以只關(guān)注代碼邏輯的書寫,Athena提供了簡便的操作命令可以一鍵式地實時編譯預(yù)覽我們的頁面,從而讓我們不必去關(guān)心文件處理、代碼編譯等細節(jié),開發(fā)完后,可以通過Athena執(zhí)行完整的編譯步驟并同步到我們的服務(wù)器上方便進行瀏覽測試。

使用Athena,新版首頁開發(fā)模式大致如下:

前后端分離

基于Athena工具,我們目前已經(jīng)可以做到完全地本地開發(fā)調(diào)試了,但是還并不能做到完全的前后端分離,以過去首頁為例,頁面被拆分成首屏和樓層,首屏采用直出的方式以提升速度,樓層則使用異步加載的方式,拉取服務(wù)器上已經(jīng)渲染好的HTML字符串,如圖

整個頁面,包括首屏和樓層,都需要前端寫好靜態(tài)HTML,然后給后端開發(fā)同學(xué)來套用,轉(zhuǎn)成后端語言對應(yīng)的模板,這樣導(dǎo)致前后端耦合較深,HTML更新極不方便,開發(fā)成本較高。

為了解決這樣前后端耦合的問題,減少溝通成本,這次首頁改版我們使用了新的開發(fā)方式,為了保證首屏速度,首屏依然采用直出的方式,但對非首屏的樓層進行改進,使用前端模板 + 數(shù)據(jù)開發(fā)方式,將DOM字符串的渲染放到前端來做,后端只提供數(shù)據(jù)接口,以此來達到前后端分離的效果,同時在開發(fā)中使用假數(shù)據(jù)平臺模擬接口,讓前端工作不再依賴后端。

在最開始提出這樣前后端分離方案的時候還是受到了不少的質(zhì)疑,因為使用前端模板 + 數(shù)據(jù)開發(fā)方式,會使得每個樓層都多一個接口,并且需要依靠JS來動態(tài)渲染,會影響到樓層加載的性能,但經(jīng)過我們的測試證明在現(xiàn)代PC瀏覽器下兩種模式前端渲染和后端渲染并不會相差太多,并且在模板、數(shù)據(jù)雙重緩存下,這樣的差距更是微乎其微了,更關(guān)鍵的是能讓我們的開發(fā)效率有所提升。

當(dāng)然,我們對于性能的追求總是孜孜不倦,為了讓樓層的加載速度更快,減少請求,我們在后續(xù)將使用在服務(wù)端定時獲取數(shù)據(jù)編譯前端模板,然后生成靜態(tài)文件推送到CDN的方式來改進,和之前的由后端開發(fā)同學(xué)套模板生成靜態(tài)文件不同的是,我們將自己搭建這樣的中間層服務(wù),在服務(wù)端編譯前端模板,實現(xiàn)前后端同構(gòu),而前端可以隨時切換渲染方式,改成請求渲染好的 HTML 字符串來進行加載,以此來提升性能。

對性能優(yōu)化的探索

性能永遠是前端工程師追求的主題,過去首頁在性能優(yōu)化上已經(jīng)做得非常極致了,它已經(jīng)使用了各種手段來優(yōu)化性能,包括首屏直出、樣式直出來提升首屏速度,樓層按需加載,減少不必要的請求等等,所以在做新版首頁的時候,我們感覺戰(zhàn)戰(zhàn)兢兢,因為改版不能讓頁面受到影響,而且最好還能比原來更快,所以,這次改版中我們主要通過如下手段來進行性能的優(yōu)化。

首屏直出和精簡

首屏直出是讓首屏速度更快的最佳選擇,此次版本依然選擇了首屏直出的方式,直出的內(nèi)容包括首屏HTML,頁面樓層骨架,以及樣式和一些必須的腳本,看起來和之前的方式如出一轍,但此次改版我們還是做了很大的改進,那就是讓首屏更加精簡。

過去是將頁面引用的所有樣式都直出在頁面上,沒有外鏈的CSS,各種優(yōu)化手段都考慮進去了,那么新版首頁就只能在精簡大小上下功夫了,所以新版首頁的首屏只直出了首屏必須的樣式,同時只直出一小部分必須的腳本,而非首屏的樓層樣式拆分到各自樓層中,和樓層的模板放在一起,按需加載。

通過對Athena工具的改造,我們實現(xiàn)樣式、模板的統(tǒng)一抽離這一功能,并且是在項目編譯階段自動實現(xiàn)的,開發(fā)者勿需關(guān)心。由于Athena統(tǒng)一的項目結(jié)構(gòu),每一個樓層在我們的項目中對應(yīng)一個widget的組件,組件包含自己的HTML 、CSS、 JavaScript文件,同時widget的組件是可以繼續(xù)調(diào)用其他widget的組件的,所以在編譯時,工具會自動分析所有widget的依賴關(guān)系,然后把樓層的模板和所有引用到樣式打包到一個文件中。最后在樓層加載的時候去請求這個文件,然后解析加載。這樣的抽離工作會在最后的項目編譯階段進行,而進行本地開發(fā)預(yù)覽的時候并不會執(zhí)行,這樣保證了開發(fā)的效率。

// https://misc.360buyimg.com/mtd/pc/index/home/rec_tpl.min.jsjsonCallBack_rec_tpl({ dom: '{%var i,clstagPrefix = pageConfig.clstagPrefix + o.staticLogTag;var isWide = pageConfig.compatible && pageConfig.wideVersion;%}{% var len = o.list.length; len = Math.min(len, 3); %}{% if (len >= 1) { %}
{% for(i = 0; i < len; i++){ %}{% var item = o.list[i]; %}{% var imgUrl = isWide ? item.imgUrl : item.imgUrlB; %}
{%= item.title %}
{% } %}
{% } %} ', style: ".rec_list{overflow:hidden;height:100px}.rec_item{overflow:hidden;float:left;width:396px;height:100%}.rec_lk{display:block;height:100%}.rec_img{display:block;margin:auto}.o2_mini .rec_item{width:330px}.csstransitions .rec_img{-webkit-transition:opacity .2s;-moz-transition:opacity .2s;transition:opacity .2s}.csstransitions .rec_lk:hover .rec_img{opacity:.8}", time: 1479195351434, version: "ff78610a0ef9cdbb"});

通過上述手段,我們讓首屏變得更加精簡,從下面的對比中就可以看出

這是過去首頁首屏大小


過去首頁首屏

這是新版首頁首屏大小


新版首頁首屏

可以看出優(yōu)化精簡之后,新版的首屏的大小減小了非常之多。

首屏輪播第一幀直出

一直以來輪播都是靠頁面最后加載的JS來進行渲染的,因為輪播圖有隨機渲染圖片的邏輯需要依賴JS,但在一段時間的觀察之后發(fā)現(xiàn),如果CDN出現(xiàn)抖動,或者用戶的網(wǎng)速較慢,那么首屏輪播這一塊位置就會一直空著,給人的體驗非常不好。所以在這一版的首頁中我們將輪播圖第一幀的數(shù)據(jù)直出在頁面上,同時也將第一幀的渲染邏輯也直出在頁面上,這樣一來,首屏輪播出來得就非常快,減少用戶的等待時間。

樓層按需加載與滾動優(yōu)化

首屏直出后,非首屏的內(nèi)容肯定也不會一次性全部加載,因為像首頁這樣的頁面樓層非常之多,一次性加載全部不僅僅慢,而且對接口來說也是一種損耗,所以我們考慮將樓層按需加載。

在我們新的方案中,已經(jīng)采用了前端模板+數(shù)據(jù)的開發(fā)模式,所以在開發(fā)中我們想用直接書寫前端模板的方式來進行開發(fā),然后在本地進行預(yù)覽,而在項目編譯時能將我們的模板編譯成獨立的文件,方便渲染邏輯進行加載。所幸Athena工具已經(jīng)支持了這樣的功能,在開發(fā)中我們以編寫前端模板的方式去開發(fā)整個頁面,隨后通過編譯工具,在代碼編譯階段自動將樓層的模板和樣式抽離成一個與組件同名的獨立JS文件,通過頁面加載邏輯去按需拉取模板文件,再進行渲染。

下面例子揭示了樓層模板生成的過程

直接書寫前端模板,編寫模板時我們給模板加上標(biāo)記位 o2-out-tpl

在編譯時掃描依賴關(guān)系,生成模板JS文件依賴組件的關(guān)系表

"dependency": { "elevator_tpl.js": [], "entry_tpl.js": [ { "widgetName": "spetit", "module": "home", "moduleId": "f1c9d790-765a-11e6-927d-63ab47c8eeb2", "widgetType": "widget", "exists": true } ], "fbt_tpl.js": [ { "widgetName": "find", "module": "home", "moduleId": "f1c9d790-765a-11e6-927d-63ab47c8eeb2", "widgetType": "widget", "exists": true }, { "widgetName": "brand", "module": "home", "moduleId": "f1c9d790-765a-11e6-927d-63ab47c8eeb2", "widgetType": "widget", "exists": true }, { "widgetName": "top", "module": "home", "moduleId": "f1c9d790-765a-11e6-927d-63ab47c8eeb2", "widgetType": "widget", "exists": true } ]}
通過關(guān)系表去合并處理CSS樣式,再和前端模板一起計算出MD5,生成獨立的JS文件
jsonCallBack_rec_tpl({dom:'{%var i,clstagPrefix = pageConfig.clstagPrefix + o.staticLogTag;var isWide = pageConfig.compatible && pageConfig.wideVersion;%}{% var len = o.list.length; len = Math.min(len, 3); %}{% if (len >= 1) { %}
{% for(i = 0; i < len; i++){ %}{% var item = o.list[i]; %}{% var imgUrl = isWide ? item.imgUrl : item.imgUrlB; %}
{%= item.title %}
{% } %}
{% } %} ',style:".rec_list{overflow:hidden;height:100px}.rec_item{overflow:hidden;float:left;width:396px;height:100%}.rec_lk{display:block;height:100%}.rec_img{display:block;margin:auto}.o2_mini .rec_item{width:330px}.csstransitions .rec_img{-webkit-transition:opacity .2s;-moz-transition:opacity .2s;transition:opacity .2s}.csstransitions .rec_lk:hover .rec_img{opacity:.8}",time:1479466862559,version:"ff78610a0ef9cdbb"});

同時會在邏輯腳本入口位置自動加入模板的版本號


{ "elevator_tpl": "e4d5dbaa3ecd12d2", "entry_tpl": "e3150fce4b2b332a", "fbt_tpl": "18f8bff18188a453", "floor_coupon_tpl": "1559694cb962e0d6", "floor_ract_tpl": "13b92d16fb6e2f7a", "mod_footer_tpl": "49142394d0e7f24e", "more_tpl": "d300081dd7f13f78", "portal_tpl": "68fae801a032cf93", "rec_tpl": "ff78610a0ef9cdbb", "seckill_tpl": "f11d04fd7eabc0e6"}


模板文件通過系統(tǒng)發(fā)布到CDN后,我們就需要有一套加載邏輯來進行加載。通過監(jiān)聽滾動事件,我們判斷讓處于瀏覽器視窗內(nèi)的樓層進行加載,由于監(jiān)聽了滾動事件,為了讓滾動更加流暢,我們必然要對滾動中做的操作進行優(yōu)化。為了避免滾動操作不斷被觸發(fā),需要對滾動進行節(jié)流處理。我們的原則是盡量避免在滾動的時候進行DOM操作與復(fù)雜計算,所以在渲染邏輯初始化的時候,我們就已經(jīng)收集好了樓層的相關(guān)信息,包括樓層高度、樓層的offsetTop等,這樣在滾動的時候就不再需要進行任何DOM操作了,讓滾動的效率有所提升。而當(dāng)樓層的數(shù)據(jù)例如樓層高度發(fā)生變化時,則通過消息通知的機制來實時地更新樓層信息即可。

腳本延后加載執(zhí)行

除了樓層是按需加載的,頁面中用到的一些腳本文件也是盡量延后加載、執(zhí)行。Athena工具在代碼打包的時候,會對每個獨立的文件進行單獨處理,同時生成一份靜態(tài)資源的線上對應(yīng)表,在編譯的最后會將引用的資源替換成配置的線上絕對地址。我們可以使用Seajs提供的require.asyncAPI來進行異步加載資源,這樣讓資源加載更加合理。


// 開發(fā)中的代碼require.async(__uri('APP_JS_ROOT/header.js'))// 編譯后require.async('//misc.360buyimg.com/mtd/pc/index/js/header.js')



同時,還有業(yè)務(wù)上一些統(tǒng)計上報等邏輯,可以放到 window onload 事件之后再執(zhí)行,這樣可以避免由于類似統(tǒng)計這樣的請求占用到頁面加載資源,從而降低頁面 onload 時間。

模板、數(shù)據(jù)分離緩存

每個樓層都按需加載之后,每次去加載這個樓層是否都要重新去請求這個樓層的模板和數(shù)據(jù)呢?答案當(dāng)然是否定的。

目前大部分瀏覽器已經(jīng)提供了許多前端緩存的解決方案,而其中兼容性最好,易用性最強的非localStorage莫屬。利用localStorage我們可以對模板和數(shù)據(jù)進行緩存,這樣當(dāng)用戶第二次加載的時候就可以不用再去請求網(wǎng)絡(luò)資源,而可以直接從本地獲取了。

但緩存之后如何進行更新呢?我們可以通過進行MD5校驗版本來實現(xiàn)。

對數(shù)據(jù)來說,數(shù)據(jù)是由后端給出的,我們可以讓后端同學(xué)將可以緩存的接口數(shù)據(jù)計算出一個MD5值作為版本號,然后直出在頁面上,同時在接口中返回這個版本號,這樣當(dāng)前端去加載是首先判斷版本號是否一致,以此來判斷是直接讀緩存還是從網(wǎng)絡(luò)請求資源。

接口版本號

而對于模板來說,則可以通過Athena工具,在每次編譯的時候自行計算出版本號,寫入模板文件和入口JS文件中,這樣在模板加載的時候也可以進行比對。

單個模板文件


// https://misc.360buyimg.com/mtd/pc/index/home/rec_tpl.min.jsjsonCallBack_rec_tpl({ dom: '{%var i,clstagPrefix = pageConfig.clstagPrefix + o.staticLogTag;var isWide = pageConfig.compatible && pageConfig.wideVersion;%}{% var len = o.list.length; len = Math.min(len, 3); %}{% if (len >= 1) { %}
{% for(i = 0; i < len; i++){ %}{% var item = o.list[i]; %}{% var imgUrl = isWide ? item.imgUrl : item.imgUrlB; %}
{%= item.title %}
{% } %}
{% } %} ', style: ".rec_list{overflow:hidden;height:100px}.rec_item{overflow:hidden;float:left;width:396px;height:100%}.rec_lk{display:block;height:100%}.rec_img{display:block;margin:auto}.o2_mini .rec_item{width:330px}.csstransitions .rec_img{-webkit-transition:opacity .2s;-moz-transition:opacity .2s;transition:opacity .2s}.csstransitions .rec_lk:hover .rec_img{opacity:.8}", time: 1479195351434, version: "ff78610a0ef9cdbb"});

JS入口文件

// https://misc.360buyimg.com/mtd/pc/index/home/index_focus.min.jswindow.tplVersion = { "1212_tpl": "ce7dcd7cd0beacb2", elevator_tpl: "e4d5dbaa3ecd12d2", entry_tpl: "2caa7cd543c322ea", fbt_tpl: "18f8bff18188a453", floor_coupon_tpl: "b98cf33be84aae98", floor_ract_tpl: "13b92d16fb6e2f7a", mod_footer_tpl: "072072ffc47778be", more_tpl: "25dcb060800c503a", portal_tpl: "68fae801a032cf93", rec_tpl: "ff78610a0ef9cdbb", seckill_tpl: "4fee56c5b073e5e1"};

通過上述方式,我們實現(xiàn)了模板、數(shù)據(jù)的分離緩存,由于樓層類似的關(guān)系,頁面中的模板大多數(shù)是重復(fù),這樣子模板緩存起來就能大大提高模板的利用率,當(dāng)用戶第二次訪問的時候?qū)⒉粫佼a(chǎn)生請求,在加速訪問的同時,減少網(wǎng)絡(luò)帶寬消耗,并且如果數(shù)據(jù)發(fā)生更新,用戶只需要更新數(shù)據(jù)即可,大大減少流量消耗。

大量使用WebP格式圖片

在這次改版中,很多的圖片我們都使用了WebP格式來減小圖片大小。

WebP格式,是谷歌開發(fā)的一種旨在加快圖片加載速度的圖片格式,圖片壓縮體積大約只有JPEG的2/3,并能節(jié)省大量的服務(wù)器帶寬資源和數(shù)據(jù)空間。但WebP的兼容性不太好,目前基本只有Chrome瀏覽器可以支持,不過這對我們的首頁來說,使用WebP還是會有很大的收益,因為通過我們的統(tǒng)計數(shù)據(jù)可知,首頁Chrome用戶已經(jīng)占到了60%左右。

體驗優(yōu)化探索

在努力提升頁面性能的同時,還要讓頁面的用戶體驗有所提升,這需要我們能站在用戶和前端的角度提出合理的優(yōu)化方案。

高清屏適配方案

人類的社會在發(fā)展,人類的社會在進步,現(xiàn)如今高清分辨率屏幕的應(yīng)用已經(jīng)越來越多,高冷的Mac自不必說,現(xiàn)在許多新型號的Windows電腦也配備了高清分辨率的顯示器,所以為了提升這一部分用戶的瀏覽體驗,我們需要在高清屏上啟用高清素材。

但頁面中素材圖基本都是運營上傳的,如果傳兩套圖對運營來說未免太過麻煩,但如果只傳一套高清圖,直接展示的話對非高清屏沒有必要,會造成流量損耗。這時候京東給力的圖片服務(wù)就發(fā)揮作用了。

圖片服務(wù)支持按一定規(guī)則改變URL來等比縮放圖片,例如原圖是一張800X340的圖片

//img13.360buyimg.com/cms/jfs/t3412/357/1332248120/113691/f29c2f1e/58244d4dN08b89f9e.jpg!q90.webp

我們可以通過這樣設(shè)置來得到一樣等比縮放400X170的圖片

//img13.360buyimg.com/cms/s400x170_jfs/t3412/357/1332248120/113691/f29c2f1e/58244d4dN08b89f9e.jpg!q90.webp

這樣的話,運營同學(xué)只需要上傳一張高清圖片,我們通過判斷是否高清屏,來動態(tài)改變URL,使用圖片服務(wù)來得到一張等比縮放的非高清素材,而且CDN會根據(jù)圖片URL進行緩存,也就是說只要第一次訪問過縮放的圖片就好,這樣性能也不會有什么損耗。

強制webkit內(nèi)核渲染

很多國產(chǎn)瀏覽器都是雙內(nèi)核,例如360、QQ瀏覽器等,而它們都提供了強制使用Webkit內(nèi)核渲染的開啟方式,這樣可以讓用戶獲得更好的瀏覽體驗。

OpenSearch

現(xiàn)在很多網(wǎng)站都能實現(xiàn)在瀏覽器搜索框內(nèi)直接調(diào)用網(wǎng)站內(nèi)部搜索的功能,這是通過 OpenSearch 來做到的,而京東之前一直是沒有的,這樣顯然是不合適,而且有一些習(xí)慣于使用地址欄搜索的用戶不能滿足。在這次改版中,我們加上了這一功能,使得用戶可以在瀏覽器地址欄就能直達京東搜索。

使用Icon Font

使用Icon Font可以提升設(shè)計師的發(fā)揮空間,在頁面上使用一些特殊字體以提升頁面的美觀程度,讓頁面看起來更具有設(shè)計感,更加細膩,從而提升用戶的瀏覽體驗。

而且Icon Font兼容性非常好,可以讓不同瀏覽器的用戶獲得一致的瀏覽體驗,并且通過字體壓縮工具,壓縮后的字體文件也可以非常小,不會有太多的性能損耗。

空閑時間自動加載樓層及圖片

前文提到,我們使用了按需加載來提升頁面性能,但這樣帶來的問題就是只有當(dāng)用戶滾動樓層到瀏覽器視窗內(nèi),樓層才會開始加載,這樣用戶滾動得稍微快一點就會出現(xiàn)很多l(xiāng)oading動畫。


為了減少這種情況的發(fā)生,讓用戶覺得樓層也加載很快,在不影響頁面滾動、加載性能的前提下我們在用戶操作的空閑時間自動加載剩余的樓層和圖片。

將樓層的加載操作放入一個隊列中,我們可以在用戶停止?jié)L動操作3s后開始自動加載這個隊列中的樓層,而當(dāng)用戶開始滾動的時候清空這個加載隊列,停止?jié)L動3秒后又重新開始加載。通過這樣處理可以合理利用用戶瀏覽的空閑時間來加載頁面,讓用戶感覺頁面加載更快。


var scrollTimer = null;var isScrolling = false;$(window).bind('scroll.loadFloor', function (e) { isScrolling = true; clearTimeout(autoLoadTimer); clearTimeout(scrollTimer); autoLoadingQueue = []; resourceLoader && resourceLoader.pause(); scrollTimer = setTimeout(function () { isScrolling = false; if (pageConfig.idleTimeLoad) { autoLoadTimer = setTimeout(autoLoad, 3000); } }, 200);});function autoLoad () { if (!isScrolling) { runFloorLoadQueue(); }}


頁面可用性保障和監(jiān)控

災(zāi)備策略

對于像京東首頁這種大流量的網(wǎng)站,后端接口可能偶爾會出現(xiàn)錯誤,或者直接掛掉,特別是在雙11這種可能會達到流量峰值的時候,但是不能因為接口出錯的原因而使得頁面顯示出現(xiàn)錯誤。這就需要前端來配合給出一套合理的災(zāi)備方案。

通常,我們通過接口緩存、超時、重試來進行災(zāi)備處理。目前首頁大部分接口、及所有模板請求,在請求成功后都會存入本地緩存,第二次請求,假如緩存沒有過期將直接使用緩存,假如緩存過期將會重新請求,而一次正常的請求,都會經(jīng)過超時或異常重試的邏輯,來保證用戶能盡量訪問到正常的數(shù)據(jù),在正常接口無法獲取數(shù)據(jù)之后又會有兜底接口來保障數(shù)據(jù)來源,這樣的層層保障,很好地保證了頁面的完整性。而且,針對所有接口,前端均有數(shù)據(jù)校驗邏輯,每一個后端接口都要經(jīng)過前端的數(shù)據(jù)校驗,來驗證接口的可用性,假如接口數(shù)據(jù)異常,前端將主動調(diào)用兜底接口來替代,這樣來保證頁面不至于錯亂。

綜上所述,首頁的接口和模板正常請求流程如下


接口請求流程

這樣一套復(fù)雜的流程下,每一個接口、模板請求都是統(tǒng)一的,所以需要對此進行封裝,以便調(diào)用。首頁是通過封裝改造$.ajax來實現(xiàn)的,使用$.ajaxPrefilter和$.ajaxTransport方法對每個異步請求進行捕獲處理,將接口、模板請求的重試、超時、緩存、兜底調(diào)用等封裝起來,對調(diào)用者透明,使用起來變得非常容易,而不需要關(guān)心以上災(zāi)備策略的實現(xiàn)。


var ajax = require('load_async');// 本質(zhì)就是$.ajax方法ajax({ url: '//f.3.cn/index-floor/?argv=aggr', jsonpCallback: 'jsonpCallbakcAggr', // jsonp回調(diào)函數(shù)名 params: {}, // 參數(shù) needStore: true, // 是否需要緩存 storeSign: '3aad2efsdf', //用戶判斷緩存是否過期的標(biāo)記 timeout: 3000, //接口超時 times: 2, // 超時重試次數(shù) backup: '//www.3.cn/bak/aggr', // 兜底接口 dataCheck: function (result) { // 接口數(shù)據(jù)校驗,校驗接口返回數(shù)據(jù),若為true則走正常邏輯,為false則自動調(diào)用兜底邏輯 if (result && result.code === 0) { return true; } return false; }});


數(shù)據(jù)統(tǒng)計驅(qū)動改進

在這次首頁改版項目中我們接入了Athena測速系統(tǒng)用于收集首頁各種性能以及用戶環(huán)境相關(guān)的數(shù)據(jù),因為有了數(shù)據(jù)統(tǒng)計,我們才能知道用戶端具體的情況信息,有了數(shù)據(jù)統(tǒng)計,我們才能對頁面進行實時監(jiān)控,有了數(shù)據(jù)統(tǒng)計,我們才能掌握我們做性能優(yōu)化的成果,所有的分析都是要基于數(shù)據(jù)來進行,否則就是在自己在YY了。

目前我們主要收集了,用戶網(wǎng)速、操作系統(tǒng)、瀏覽器分布、分辨率分布等各種信息,同時對于頁面加載情況也有一定的監(jiān)控,如頁面測速打點上報、數(shù)據(jù)接口出現(xiàn)調(diào)用兜底接口的情況上報、樓層接口失敗導(dǎo)致樓層隱藏的情況上報等。

通過以上數(shù)據(jù)統(tǒng)計,我們可以靈活地對我們的頁面進行優(yōu)化,同時及時發(fā)現(xiàn)問題,避免損失。例如我們通過統(tǒng)計發(fā)現(xiàn)用戶在網(wǎng)速低于一定值時頁面樓層隱藏數(shù)增多,這樣我們就可以通過設(shè)置更長的超時時間來減少這一情況的發(fā)生,還有就是假如某時刻開始發(fā)現(xiàn)某接口調(diào)用兜底請求數(shù)暴增,可以判定接口出現(xiàn)問題而及時反饋給后端同學(xué)。

更長遠的探索

新版首頁已經(jīng)上線小一個月了,表現(xiàn)一直還算良好,我們做出的性能以及體驗優(yōu)化也得到了體現(xiàn),在此基礎(chǔ)上,我們思考了更多的可以做的工作,來提升首頁的表現(xiàn)。

靜態(tài)資源預(yù)加載

首頁承載著許多頁面的入口,如頻道頁還有活動頁,在雙11的時候,首頁會有很多直達活動的入口,如果我們能在首頁預(yù)加載某些重要的活動頁面的資源的話,當(dāng)用戶去訪問這些活動頁面就能更加迅速地打開瀏覽了。


靜態(tài)資源預(yù)加載

架構(gòu)升級

jQuery + Seajs或許讓人感到老舊且沮喪,我們考慮在首頁上漸漸使用一些新的技術(shù),例如去Seajs化,提供更優(yōu)的打包方式,讓頁面性能進一步提升。

中間層探索

目前首頁雖然差不多實現(xiàn)了前后端分離,但是首屏這里前后端依然存在耦合,假如前端可以介入到中間層的開發(fā),那問題就迎刃而解了,接入中間層后,我們還可以將頁面部分樓層做服務(wù)端渲染,以減少前端渲染的性能損耗,可以在實現(xiàn)前后端分離的基礎(chǔ)上,讓頁面性能更好,還是有一定意義的。

相關(guān)文章:

版權(quán)所有 @ 2007-2023上海海淘信息科技有限公司 滬ICP備11050025號-4