負責任地編寫JavaScript代碼(三)

原文地址:alistapart.com/article/res… 原文做者:Jeremy Wagner 譯者:龔亮 聲明:本翻譯僅作學習交流使用,轉載請註明來源javascript

針對網站上存在的 JavaScript 問題,你已經嘗試了全部可能解決它的​方法。好比,儘量地依賴 Web 平臺避免使用 Babel 使用較小的框架替代方案,對應用程序代碼作極致化精簡。然而,速度仍是不夠快。當網站沒法像設計師和開發人員所指望的那樣發揮做用時,不可避省得讓咱們反思: 「咱們沒有作到什麼?」 「咱們寫的代碼能作什麼?」 「咱們架構的哪些部分沒有達到預期?」 至關一部分性能問題源於咱們本身的代碼,然而把責任所有歸咎於咱們本身會赤裸裸地忽略一個事實:至關大一部分性能問題是由外部因素致使的。css

當與第三方碰撞的時候

便利老是要付出代價的,咱們對 web 的集體偏好也破壞了它,特別是 JavaScript,它的使用方式代表了一種快速增加的趨勢,即外包咱們(第一方)不想作的任何事情。有時這是一個必要的決定。在許多狀況下,它具備完美的財務和運營意義。java

不要誤會,使用第三方 JavaScript 永遠不會便宜。這是一個魔鬼的交易,供應商使用能解決你問題的解決方案來誘惑你,卻沒有明確地提醒你,你幾乎沒法控制解決方案帶來的反作用。若是第三方供應商給他們的產品新增了功能或者改變了基礎架構,你將首當其衝受到這些變更的影響。那些使用你網站的人會感到沮喪,他們不會努力克服因爲糟糕的用戶體驗而帶來的煩惱。除非徹底移除供應商提供的解決方案,不然你只能減輕而非徹底消除使用它帶來的影響。web

在本篇文章中,咱們所採用的技術方法要比上一部分中略有減小。咱們將更多地談論第三方供應商的人性方面,而後咱們將介紹一些有關如何解決這類問題的技術途徑。跨域

便利性帶來的阻礙

當咱們談論當今 Web 糟糕的狀態時,咱們中的一些人很快指出了開發人員的便利性在致使此問題中的做用。雖然我贊成開發人員的便利性會損害用戶體驗,但這只是將網站變得遲緩、混亂的便利性之一。瀏覽器

操做上的便利性可能會成爲很是棘手的技術債務的先兆,當咱們沒法獨自解決一個廣泛存在的問題時,這些便利性就是咱們所追求的。它們表明了在缺少架構靈活性或足夠的開發資源的狀況下解決問題的第三方解決方案。bash

每當出現不便之處時,就應該討論如何以一種全面的方式解決它。因此,讓咱們從更人性化的角度來談談如何處理這種狀況。服務器

問題的關鍵是痛苦

第三方供應商介入的緣由是痛苦。當一個組織的決策者對某個問題感到足夠痛苦時,他們會作一件很是人性化的事情,那就是找到最快的方法讓痛苦消失。微信

市場老是會找到解決這些痛點的方法,即便這種方法是不可持續的,甚至毫無用處。Web 可訪問性覆蓋(旨在自動修復可訪問性問題的第三方腳本)是最嚴重的違法者。首先,你花錢去買一個解決不了任何問題的解決方案。而後,當該「解決方案」損害了你網站的可用性時,你須要付出的就遠不止以前那麼點了。這並非抹黑某些第三方供應商提供的工具的有用性,而是說明第三方解決方案的採用是如何發生的,即便那些客觀上很糟糕的工具也是如此。markdown

A Chrome performance trace of a long task kicked off by a third party’s web accessibility overlay script. The task occupies the main thread for roughly 600 ms on a 2017 Retina MacBook.

所以,當一個供應商承諾解決咱們面臨的很是痛苦的問題時,極可能有人會採納解決方案。若是這我的在公司的地位足夠高,且在決策過程當中沒徹底繞過他的話,他就會對其餘人施加下行壓力,迫使他們購買。相反,當那些處於壓力之下的人缺少足夠的資源來建立必要的特性時,也會出現採用第三方解決方案的狀況。

不管如何,把你的同事彙集在一塊兒,共同制定一個解決和減輕你面臨的問題的計劃是值得的。

建立一個緩解計劃

不管第三方解決方案多麼不明智,一旦組織中的人員採用了它,你在強制更改過程當中遇到的困難將取決於該解決方案的需求有多迫切。事實上,你不該該試圖讓解決方案的支持者相信他們的決定是錯誤的。這樣的努力幾乎老是拔苗助長,會讓人們以爲受到了攻擊,對你所說的話更加抵觸。更糟糕的是,這些努力可能會致使人們徹底不傾聽對方的意見,從而產生激烈的爭吵,從而滋生出更嚴重的問題。

若是有必要的話,我本身也常常這麼作,在你的同事之間發牢騷表示同情,但把你的不滿放在一邊,拿出一個緩解計劃,引導你的同事走向更好的結果。具體方法的具體細節將取決於第三方自己和組織的結構,但其實質可能相似於如下一系列問題。

該解決方案解決什麼問題?

選擇第三方解決方案是有緣由的,這個問題將幫助你肯定採用該解決方案的理由是否合理。有些決策是在全部必要的人都不在的時候作出的。你可能處於這樣一種境地:你必須對那個決策的後果作出反應。這個問題的答案會引導你天然而然地跟進。

咱們打算使用該解決方案多長時間?

該問題將幫助你肯定解決方案的保質期。它是以臨時解決方案的形式引入,在解決了問題後(例如在可訪問性覆蓋的狀況下)將其移除嗎?仍是以長期解決方案的形式引入,例如A / B測試套件提供的數據?另外一種可能性是解決方案永遠沒法完全的移除,由於它起着相當重要的做用,就像分析腳本同樣。這就像在游泳池裏扔牀墊:扔進去容易,但拖出來幾乎是不可能的。

在任何狀況下,若是你不詢問便沒法肯定第三方腳本是否會繼續存在。實際上,若是你發現解決方案是臨時的,則能夠制定計劃,一旦解決了問題,便最終將其從網站中刪除。

若是出現問題,誰是聯絡人?

當第三方解決方案就位時,在出現問題時必須有人做爲聯絡人。

我已經看到了第三方腳本失控時會發生的事情(太常見了)。例如,因爲市場營銷人員沒有清除舊的標記或完成A / B測試致使標記管理器或A / B測試框架的 JavaScript 緩慢且隱式地增加。正是因爲這些緣由,你的網站上目前使用的第三方解決方案的責任須要由組織中的特定人員承擔。在每種狀況下,該責任人承擔的責任都會有所不一樣,但可能包括:

  • 按期監視第三方腳本的佔用空間;
  • 進行維護以確保第三方腳本不會失控;
  • 偶爾舉行會議,討論該供應商與你的組織的關係的將來;
  • 識別多個第三方之間的功能重疊,以及是否能夠消除潛在的冗餘;
  • 關注正在進行的研究,特別是鑑別速度更快的替代方案,這些替代方案能夠更好地替代速度較慢的第三方腳本。

在這種狀況下,責任感毫不是同事所承擔麻煩的、苛刻的義務,而應該是一種鼓勵同事保持優秀思想道德素質的練習。由於若是沒有責任感,第三方腳本對你網站的不良影響將被忽略,直到它變成房間裏使人不快的食人魔,再也沒法忽略。爲第三方解決方案分配責任人能夠幫助防止這種狀況的發生。

確保負責任地使用第三方解決方案

若是你可以制定一個緩解計劃,並讓每一個人都參與進來,那麼確保負責任地使用第三方解決方案的工做就能夠開始了。幸運的是,實際的技術工做將比試圖與人爭論更容易。因此,若是你已經作到了這一步,你所須要的就是時間和堅持。

僅加載必要的內容

這看起來是顯而易見的,僅加載必要的內容。從我看到的未使用的第一方 JavaScript 的加載量(更不用說第三方 JavaScript)來看,這顯然是一個問題。這就像試圖經過將雜物塞入壁櫥來打掃房間同樣。不管是否實際須要它們,在每一個頁面上都加載第三方腳本的狀況並很多見,所以請聯繫你的聯絡人以找出哪些頁面須要哪些第三方腳本。

例如,我一個老客戶使用一個流行的第三方工具在多個品牌網站上得到一個指定產品的零售商列表。它展現了清晰的價值,但該腳本只須要出如今網站的產品詳細信息頁面上。實際上,它經常被加載到每一個頁面。從不屬於此腳本的頁面中剔除此腳本能夠顯著提升非產品詳細信息頁面的性能。

弄清楚哪些頁面須要哪些第三方腳本須要你作一些非技術性的工做。實際上,你必須從辦公桌前站起來,與被指派負責你正在處理的第三方解決方案的人進行交談。這對我來講是一項很是困難的工做,但當真誠的合做發生,並最終實現良好的結果時,這是值得的。

自託管你的第三方腳本

這個建議絕對不是祕密。我甚至在本系列的前一篇文章中提到過它,在這裏我仍然建議:你應該儘量多地自行託管第三方資源。這是否可行取決於所討論的第三方腳本。

你是從Google的託管庫cdnjs或其它相似的託管庫中獲取某個框架嗎?如今就自我託管那個資源。

Casper找到了一種方法來自我託管他們的優化腳本,並顯着減小了開始渲染時間。這確實令人們意識到,第三方資源的一個主要危害是,它們僅存在於其餘服務器上,這是咱們遇到的最糟糕的性能瓶頸之一。

若是你但願自託管分析解決方案或相似類型的腳本,則自託管它的難度更高。你可能會發現,有些第三方腳本根本沒法自託管,但這並不意味着不值得花時間去解決。若是你發現自託管不是第三方腳本的選項,不要擔憂,你還能夠嘗試其餘緩解方法。

減小跨域鏈接的延遲

若是你不能自託管第三方腳本,那麼最好是預先鏈接到託管它們的服務器。WebPageTest 的鏈接視圖很是出色地向你展現了網站從哪些服務器收集資源,以及與這些服務器創建鏈接所需的延遲。

WebPageTest’s Connection View shows all the different servers a page requests resources from during load.

預鏈接是讓瀏覽器在發現它們以前就創建了到第三方服務器的鏈接,可以有效的減小延遲。解析HTML須要時間,並且解析器常常被樣式表和其餘腳本阻塞。若是你不能自託管第三方腳本,那麼預鏈接就很是有意義。

也許不預加載第三方腳本

正如Andy Davies所指出的,資源預加載一開始聽起來很難以想象,直到你考慮到它可能會拔苗助長。若是你不熟悉預加載,那麼它與預鏈接相似,它指示瀏覽器更快地獲取特定的資源。

預加載的缺點是,雖然它能夠確保儘快加載資源,但它會更改該資源的發現順序。每當咱們這樣作時,咱們都在暗指其餘資源不那麼重要,包括對渲染甚至核心功能相當重要的資源。

能夠確定的是,你的大多數第三方代碼對網站功能的重要性不如你本身的代碼。也就是說,若是必須預加載第三方資源,請確保僅對頁面呈現起到相當重要的第三方腳本執行此操做。

若是你發現你的網站的初始呈現依賴於第三方腳本,請參考你的緩解計劃,看看你能夠作些什麼來消除或改善你對它的依賴。依靠第三方來實現核心功能歷來都不是一個好主意,由於你將大量控制權交給了那些可能並不關心你的最佳利益的人。

延遲加載非必需的第三方腳本

最好的請求就是沒有請求。若是你有一個不須要當即加載的第三方腳本,請考慮使用Intersection Observer來延遲加載它。這是滾動到 viewport 中時延遲加載Facebook Like按鈕的示例:

let loadedFbScript = false;

const intersectionListener = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    if ((entry.isIntersecting || entry.intersectionRatio) && !loadedFbScript) {
      const scriptEl = document.createElement("script");

      scriptEl.defer = true;
      scriptEl.crossOrigin = "anonymous";
      scriptEl.src = "https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v3.0";
      scriptEl.onload = () => {
        loadedFbScript = true;
      };
      
      document.body.append(scriptEl);
    }
  });
});

intersectionListener.observe(document.querySelector(".fb-like"));
複製代碼

在上面的代碼片斷中,咱們首先設置一個變量來跟蹤是否加載了Facebook SDK JavaScript。而後,建立一個IntersectionListener來檢查觀察到的元素是否在 viewport 中,以及 Facebook SDK 是否已經加載。若是 SDK JavaScript 沒有被加載,對它的引用將被注入到DOM中,這將引起對它的請求。

你不能延遲加載每一個第三方腳本。其中一些須要在頁面加載時執行。不管如何,請作一些檢查工做,看看是否能夠延遲加載一部分第三方JavaScript。

當我建議延遲加載第三方腳本時,我從同事那裏聽到的一個常見問題是,它會延遲第三方提供的任何交互。這是一個合理的問題,由於當你延遲加載任何內容時,資源加載可能會出現明顯的延遲。在某種程度上,你能夠經過資源預取來解決這個問題。這與咱們前面討論過的預加載不一樣。預取會消耗至關數量的數據,可是預取資源的優先級較低,而且不太可能與關鍵資源爭奪帶寬。

在這個問題上

密切關注第三方 JavaScript 須要一種近乎高度警戒的責任感。當你意識到技術債務的糟糕表現時,你會很天然地陷入這樣一種狀態:你會像對待其餘技術債務同樣對待它。

依靠第三方來進行重構是一項須要你按期執行的工做,好比清理標記管理器和A/B測試、整合第三方解決方案、移除任何再也不須要的解決方案,以及應用上面討論的編碼技術。此外,你須要與你的團隊合做,以循環的方式解決這個技術債務。這種工做不能被自動化,須要你與實際的人進行面對面、同步的對話。

若是你已經習慣於週期性地執行「cleanup sprints」制度,那麼這就是你處理與性能相關的技術債務的時間和空間,無論它涉及到第三方代碼仍是第一方代碼。特性開發是有時間的,但這段時間不該該包含你的所有工做時間。只專一於功能開發的開發團隊註定會被技術債務徹底消耗掉,這是不可避免的。

所以,在本系列的第四部分(也是最後一部分)中,咱們將討論在流程的上下文中負責地使用JavaScript意味着什麼。在這裏,咱們將探討如何將您的組織聯合起來,使您的網站更快、更容易訪問,從而使每一個人、任何地方都更容易使用。


若是你以爲這篇內容對你有價值,請點贊,並關注咱們的官網和咱們的微信公衆號(WecTeam),每週都有優質文章推送:

WecTeam

img10.360buyimg.com/wq/jfs/t1/4…

相關文章
相關標籤/搜索