有一個通用button(比如:推薦button)在任何頁面都有可能用到。問題包含:

1. 如何最快顯示出來。(假設它已經在頁面靠前的位置)2. button有點擊行為,如何儘快初始化(初始化依賴jquery)3. 作為通用組件,要考慮各種可能情況的影響(強調是各種可能情況!)給出一個最好的方案?

=================================(分割線)====================

問題點不僅僅是優化技巧,而是頁面上js, css等限制因素如何管理。


我總覺得這就好像42那個終極問題一樣,即使給出了精確的答案卻發現不知道問題是什麼。

如果想儘快看到那個Button,功能可用如果按照我的理解:
  1. Button用HTML直接渲染在那裡,HTML足夠簡潔,沒有阻塞性的HTML和CSS下載在它前面阻塞,渲染也不依賴CSS。
  2. Button的邏輯用經典的HTTP Post-Redirect實現,不依賴任何的javascript。
  3. Loader/Intitializer負責增強這個Button行為,前後基本行為一致,按照漸進增強的基本方法來。

我猜想其實問題需要的不是這樣的答案,而是很多最佳實踐(奇技淫巧)在這個方案的應用。不過就好像終極問題反過來:
  • 你需要問為什麼最上面有一個Button?
  • 為什麼不需要閱讀就點擊那個Button?
  • 我期望那個Button產生什麼樣的後果?
  • 為什麼要這樣設計,這真的是理性的需求么?

不過很不幸,一般我們還是只有終極答案但是終極問題卻無法計算 :D

BTW:知乎這個編輯器實在是……逼瘋我了(不過不排除是我的Chrome抽風了)


受邀回答。

根據需求,這是一個(或一組)常用的交互控制項,並且希望讓用戶儘快可用。

1. HTML方面,基本上就是將button的html代碼插入到頁面盡量前面的地方,並且不要犯一些低級錯誤(比如弄出很大的table來做layout並將button納入其中)。至於語義化要求(使用合適的tag,如button/a之類的),以及其帶來的好處(在CSS未正確載入時也能讓用戶辨識出其作用),乃是一般法則,不贅述。

2. CSS代碼方面,其實按照一般用CSS來指定樣式的方式,也已經OK。因為我們通常也不會延遲載入樣式表,所以當HTML代碼ready的時候,樣式可以立即起作用,不會影響呈現的時機。唯一可能要考慮的是button的外觀如果涉及圖片,要做好圖片沒有載入時的fallback(而且以當前瀏覽器普遍實現的CSS3特性來說,不用圖片也已經可以實現出很漂亮的按鈕),或者乾脆像@ytzong 說的,圖片用data協議。

【儘快顯示的需求也可能涉及許多其他一般性的問題。例如假如button的html代碼之前有許多其他伺服器端生成的內容,使用bigpipe之類的技術有助於避免延遲。再如button如採用絕對定位或fixed定位,即不在文檔flow之內,則對應html代碼的位置有更大的靈活性,設計上也確保了所處視覺區域的精確。不過這些其實取決於架構或者設計等通常並非由前端工程師決定的因素。】

3. 按鈕行為的儘快可用,這一條相信是主要挑戰所在。目前而言,要儘快附加行為,就只有在按鈕的html代碼之後馬上插入事件監聽器和相關的腳本。(因為DOM缺乏element ready之類的事件。)

【有些同志提出優雅退化/漸進增強的方案,即以超鏈接或者表單提交方式進行伺服器端交互,這當然是很好的。但是我認為優雅退化和漸進增強的主要著眼點是針對特殊的UA、無腳本支持、或者某些極罕見情況的。頁面尚未完全載入完畢時就發生點擊還是比較常見的,應該盡量避免直接退化到伺服器交互。】

但是使用inline script或者直接在tag後插入&

如果按鈕的行為所相關的腳本很複雜, 我們可以考慮將UI的響應和其他邏輯分開,UI的響應部分用同步方式,確保響應無延遲,而其他邏輯可以非同步延遲載入和執行。舉例來說,常見button為狀態切換(類似於本頁面右上角的「關注」按鈕),則不同狀態顯示的切換僅僅是css樣式的切換,用簡單的腳本修改class即可做到。

補充,本題需求沒有明確,這是僅供站內使用的功能,還是可能提供給第三方使用的功能(例如jiathis那樣的)。

如果是站內使用的,html可以由後端產生,css和js也可以任何分開或合併,所以並不存在特別的部署考量因素。假如是給第三方使用的,則在部署上一般希望是能引用一個腳本就可以搞定。這樣,按鈕的創建、樣式和事件的綁定通常都是由腳本完成,如無特殊情況,也不會採用諸如延遲載入之類的手段,所以事情通常反倒比較簡單。當然之前提到的各種可能性也仍然是適用的。
減少依賴,盡量把這個按鈕的結構,表現,行為都和依賴的東西分開。就算依賴沒載入也可用。樣式style之html flush,放到body最頂層,最好絕對定位一個固定位置。js 寫到標籤屬性里,相應邏輯,能寫下的就寫onxx里,寫不下放到button上的script里

看具體環境了,目的只有一個:讓瀏覽器儘快渲染這個按鈕。

那麼,「渲染按鈕」的任務優先順序就顯得特別高。你可以讓它儘早的處理,並把優先順序較低的任務,放在「渲染按鈕」的「完成」事件中處理。

也就是說,在渲染按鈕時,其它任務可以暫停,或先不執行。


如果希望button跟頁面同步出現的話就只能選擇同步script了,但如果這個button的同步script在大並發下伺服器響應速度不理想將會卡著整個頁面的載入,不論同步非同步,保證伺服器的響應速度是必須的;若選擇jQuery的非同步載入,那就要讓button的非同步執行次序盡量靠前,也就是非同步執行腳本盡量放在其他非同步腳本之前,不然等待頁面其他非同步腳本的執行將會影響此button的初始化;還有需要調用動態數據就要考慮跨域問題了,這個用jsonp可以解決。不知問題所說的button是不是指google +1這種按鈕設計,我覺得google +1這種按鈕重度的JS加上國內這樣的網路環境還是十分之慢的。
克軍想要的是data flush吧?第一次flush&&&&
相关文章