天天看點

Angular伺服器渲染常遇的坑

前言

由于官網有SEO需要,是以對現官網項目進行ssr的整改相容,在調試的過程中遇到了不少問題。本來在官網的demo項目中使用是比較順暢的,但是由于本項目比較大複雜性比較高,踩了不少的坑。以下是我在調試過程中遇到的一些問題彙總,希望其他人可以避開這些坑。

1. 使用浏覽器 API報錯問題

在運作服務的時候,通常會遇到一下的一些報錯

<code>ReferenceError: window is not defined</code>

或者

<code>ReferenceError: document is not defined</code>

由于 Universal 應用并沒有運作在浏覽器中,是以該伺服器上可能會缺少浏覽器的某些 API 和其它能力。比如,服務端應用不能引用浏覽器獨有的全局對象,比如 window、document、navigator 或 location。如果直接使用會導緻運作的時候出現報錯。是以,我們需要對使用浏覽器的API方法做好相容。

方案1:在server.ts,引入domino做相容

但是,domino并非相容了所有浏覽器的api,隻是相容了大部分方法但是如果是用到的api不多,可以考慮用這個方案。如果是一些複雜項目建議還是用下面官方推薦的方法比較好。

方案2:使用Angular官方推薦的方法

通過PLATFORM_ID令牌注入的對象來檢查目前平台是浏覽器還是伺服器,進而解決該問題。判斷是浏覽器環境,才執行使用到浏覽器方法的代碼片段。不過個人覺得有些麻煩,因為在用到浏覽器獨有API方法的地方都得做引入判斷相容。

2. 使用第三方庫,例如jq,echart,layer等等報錯

<code>ReferenceError: $ is not defined</code>

<code>ReferenceError: layer is not defined</code>

和上面一樣,檢查目前平台是浏覽器還是伺服器,執行相應的代碼。

**

懶加載路由無法加載問題**

由于我的項目原來是angular6版本的,後來更新到了angular9後路由寫法有所改變,在浏覽器模式下是沒有問題的,安裝官方例子改造ssr之後懶加載路由無法正常使用,這裡需要把路由改成v9版本推薦的寫法,修改如下:

修改前

修改後:

4. 打包node版本報錯

報錯資訊如下:

由于我更新了node到12版本,這個報錯是node12本身的bug官方暫時還沒有修複這個問題,是以需要把node復原到10.15.3版本,版本復原之後就沒有報錯了。

5. 響應時間TTFB過長問題

Angular Universal渲染過程中,如果代碼中有一些延遲異步任務,可能會阻塞渲染。

主要包括例如setTimeout、setInterval、全局調用Observables等方法的使用。在不取消它們的情況下調用它們,或者讓它們運作超過伺服器所需的時間可能會導緻渲染效果欠佳,進而使得首次加載響應時間過長。

是以需要檢查項目中是否用到以上方法,如有在用完之後需求做清除。

此外,如果需要執行的異步任務沒有必要在伺服器端使用的話,可以參考問題2的方式,使用isPlatformBrowser跳過伺服器執行。

小結

項目越複雜整改難度越大,在調試universal服務時需要注意以下幾個點:

伺服器沒有的api或者第三方庫需要用isPlatformBrowser跳過執行;

版本更新最好把一些相關的基本寫法調整到新版;

注意node版本問題;

使用定時器需要及時清除。