在手百咱們使用了一種動態管理靜態資源的方式,在開發中一般打包工具在打包構建的時候根據頁面依賴將全部的js或者css打成一個app.js
或者app.css
,這樣的打包方式咱們稱之爲「靜態打包」,由於只能在項目發佈構建的過程當中一次性將頁面用到的js或者css打包成一個文件,上完線以後就不能在拆分。php
這種「靜態打包」的方式有個弊端:若是在多個view的頁面,是不可以充分利用不一樣頁面之間的公用代碼(模塊)。因而增強版就是在線統計一個網站(項目)模塊依賴和公用的代碼,而後設置一個閾值,利用統計的數據,分析出多個頁面高頻使用的公共代碼,再下次上線的時候,將這部分代碼打包在一塊兒。這種方式百度內部也有相似的解決方案,可是這種方案也沒有充分發揮出細粒度模塊的做用,並且實現相對來講比較麻煩,須要長期數據統計支持。css
今天我介紹下手百中咱們實現的一種動態管理靜態資源的方式,我將它稱之爲「前端資源動態渲染模式」,簡稱「渲染模式」。這種方式是基於手百現有業務出發的,解決了手百不一樣平臺(安卓、ios、winphone)的代碼差別,並且充分利用緩存、combo服務,作到可配方便調試的目的。html
代碼永遠只寫一份,不須要編寫特殊邏輯前端
咱們實現的渲染模式,對於代碼開發者來講,不須要作特殊的邏輯編寫,只須要按照正常編碼要求來寫代碼,剩下的就交給打包工具和上線流程,對於初學者不須要任何的學習門檻,並且支持本地靜態資源和外部靜態資源混用。android
可以根據不一樣平臺,不一樣後端業務邏輯,動態打包不一樣代碼ios
後端業務邏輯不通,則須要的js或者css文件不通,以前的作法是一個js裏面包含了全部的代碼邏輯,如今只須要以下代碼:json
{% if($isiOS) %}
{%require name="life:ios/invoke.js"%}
{%else%}
{%require name="life:android/invoke.js"%}
{% endif%}複製代碼
這個是動態邏輯解析後的執行,因此編譯階段的靜態打包是徹底解決不了這個問題的。後端
結合combo服務或者localstorage作緩存優化瀏覽器
利用靜態資源的combo服務和瀏覽器的localstorage存儲,咱們能夠把渲染模式進一步優化,最簡單的方式是combo渲染模式,動態分析完頁面依賴以後,將url拼接成combo url一次輸出
緩存
多種渲染模式,能夠適用不一樣的應用業務場景
在不一樣的業務場景下,須要的代碼組織形式不一樣,好比2G下,應該儘可能少的http請求,這時候須要inline模式,將js和css分別放在<script>
和 <style>
標籤內,而咱們寫代碼不須要這樣寫,仍是使用正常的{%require %}
語法
可結合用戶設備特徵,自動智能選擇不一樣的渲染模式
對於不一樣的用戶、設備和網絡環境,可以自動識別出來最適合的渲染模式,例如對於2G用戶,推薦使用http請求少的inline模式,對於3G、4G用戶可以使用combo模式,對於支持localstorage的用戶使用seed模式,這些修改只須要在父模板設置渲染模式便可:
{%if $network==='slow'%}
{%html rendermode='inline'%}
{%elseif $isSuportLS%}
{%html rendermode='seed'%}
{%else%}
{%html rendermode='combo'%}
{%endif%}複製代碼
下面列下大概的技術要點:
map.json
,裏面有每一個靜態資源的信息,能夠利用打包工具,對這個表進行擴展,增長想要的信息,好比release以後的cdn url,發佈上線後到路徑,文件的MD5值map.json
內靜態資源配置,好比combo須要讀取去掉combo url的cdn url,拼接最終的url;tag模式須要單個的cdn url;seed須要讀取MD5值;inline須要知道線上部署的路徑,能夠讀取出來文件內容塞到<script>
或<style>
標籤內本篇文章主要從整體對動態渲染模式作了介紹,基於smarty的語言擴展實現的動態解析依賴關係,充分利用網絡環境、用戶設備特性和server服務實現最優的性能優化和靜態資源代碼管理方式。若是是其餘動態語言,能夠參考本文的思想進行改造實驗。接下來兩篇文章重點介紹如今手百使用的兩種渲染模式:combo和seed。