還要多少年, 前端開發才能像後端那樣輕鬆

原貼地址php

咱們來分析一下究竟哪些因素讓前端開發這麼困擾。html

先看看界面部分吧。前端

#1. 命令式仍是聲明式
毫無疑問,就寫界面來講,聲明式的代碼編寫效率遠高於命令式:git

<Panel title="Test">
  <Button label="Click me"/>
</Panel>

Panel p = new Panel();
p.title = "Test";
Button b = new Button();
b.label = "Click me";
p.add(b);

第一種容易寫,容易理解。程序員

#2. 控件標籤集
無論你的軟件面向什麼行業,至少都要一些控件,或者是基本的表單輸入,或者是複雜的好比樹形表格,裏面還能夠跨行跨列渲染的。github

若是咱們有一套映射到控件的標籤,那麼寫代碼是確定會簡單不少的,好比說,在HTML裏面沒有原生的Panel,那麼,剛纔第一段代碼可能就要變成:後端

<div class="panel panel-default">
  <div class="panel-heading">
    <h3 class="panel-title">Simple HTML Loader</h3>
  </div>
  <div class="panel-body">
    <button>Click me</button>
  </div>
</div>

咱們爲了使得界面代碼編寫更高效,毫無疑問會傾向於把這麼一堆東西簡化成一個Panel標籤,這樣就會逐步創建一套面向本身行業的標籤集。瀏覽器

#3. 帶邏輯的控件緩存

剛纔這個例子爲何簡單呢,由於它只是一個普通容器,靜態的,不帶邏輯,因此即便你用什麼靜態模板也能解決問題。若是複雜一點,是一個TabNavigator,就要考慮切換的事件,再複雜一些是個樹形表格,那就更麻煩了。架構

咱們來看jQuery提供的插件方式實現TabNaviator:

<div id="tabs">
  <ul>
    <li><a href="#tabs-1">Nunc tincidunt</a></li>
    <li><a href="#tabs-2">Proin dolor</a></li>
    <li><a href="#tabs-3">Aenean lacinia</a></li>
  </ul>
  <div id="tabs-1">
  </div>
  <div id="tabs-2">
  </div>
  <div id="tabs-3">
  </div>
</div>

  <script>
  $(function() {
    $( "#tabs" ).tabs();
  });
  </script>

從我我的的角度看,這種代碼很愚蠢。蠢在何處呢?HTML這類聲明式的界面描述語言,寫起來原本應當直觀一些的,可是被這麼一搞,又往命令式的方向去了。並且兩種東西混雜,聲明和渲染竟然分了兩處,又增長了維護的成本。

難道就沒有別的辦法來解決這個問題嗎?

咱們看看其餘語言和框架,好比Flex和Silverlight。

<mx:TabNavigator id="tn"  width="100%" height="100%">
  <!-- Define each panel using a VBox container. -->
  <mx:VBox label="Panel 1">
    <mx:Label text="TabNavigator container panel 1"/>
  </mx:VBox>

  <mx:VBox label="Panel 2">
    <mx:Label text="TabNavigator container panel 2"/>
  </mx:VBox>

  <mx:VBox label="Panel 3">
    <mx:Label text="TabNavigator container panel 3"/>
  </mx:VBox>
</mx:TabNavigator>

上面這段是Flex裏面的TabNavigator,在這個連接底部有運行結果:TabNavigator

爲何它能夠看不到邏輯的代碼,可是又確實能有動做呢,由於它的實現類是mx.containers.TabNavigator,在這個代碼裏,能夠本身手動去處理一切內部實現,可是暴露給業務開發人員的就是這麼簡單的標籤。

咱們看看在HTML和JS這個體系裏用什麼辦法去解決。不要提JSF這類服務端技術,由於它的思路也是很差的,展現代碼的生成和渲染都不在一個地方,會有不少問題。

#4. Polymer與Angular

早期IE裏有HTC,也就是HTML Components,由於別的瀏覽器廠商不喜歡,因此快要消亡了。在W3C新的HTML規範裏,有一個Web Components,參見這裏:Introduction to Web Components

這個東西跟HTC的思想本出同源,它引入了Custom Elements和Shadow DOM這兩個概念,也就是說,我能夠自定義一個標籤,而後在內部隨便怎麼折騰,用這個標籤的人能夠很方便。

很美好,是否是,可是隻適用於比較新的瀏覽器,基於這個理念架構的框架Polymer的目標也只是支持一些比較新的瀏覽器。Polymer

那麼怎麼辦呢?咱們還有Angular,它也能夠自定義標籤,而後用directive的方式寫內部實現。

<tabs>
  <pane title="Localization">
  </pane>
  <pane title="Pluralization">
  </pane>
</tabs>

<script id="components.js">
  angular.module('components', [])

    .directive('tabs', function() {
      return {
        restrict: 'E',
        transclude: true,
        scope: {},
        controller: function($scope, $element) {
          var panes = $scope.panes = [];

          $scope.select = function(pane) {
            angular.forEach(panes, function(pane) {
              pane.selected = false;
            });
            pane.selected = true;
          }

          this.addPane = function(pane) {
            if (panes.length == 0) $scope.select(pane);
            panes.push(pane);
          }
        },
        template:
          '<div class="tabbable">' +
            '<ul class="nav nav-tabs">' +
              '<li ng-repeat="pane in panes" ng-class="{active:pane.selected}">'+
                '<a href="" ng-click="select(pane)">{{pane.title}}</a>' +
              '</li>' +
            '</ul>' +
            '<div class="tab-content" ng-transclude></div>' +
          '</div>',
        replace: true
      };
    })

    .directive('pane', function() {
      return {
        require: '^tabs',
        restrict: 'E',
        transclude: true,
        scope: { title: '@' },
        link: function(scope, element, attrs, tabsCtrl) {
          tabsCtrl.addPane(scope);
        },
        template:
          '<div class="tab-pane" ng-class="{active: selected}" ng-transclude>' +
          '</div>',
        replace: true
      };
    })
</script>

這麼一來,也就有些接近咱們的目標了,看到如今,咱們還記得目標是什麼嗎?是儘量精簡的面向領域的容器和控件標籤集,有了這個,寫界面代碼才能更簡單。

#5. 爲何HTML默認標籤集這麼小

事情結束了嗎?沒有呢。咱們的HTML體系爲何標籤集這麼小?由於他要解決的是通用領域的東西,怎樣才能通用呢?要的是儘量無歧義。

怎樣的東西會沒有歧義?那就是它的含義儘量少,好比說單行文本輸入框,總沒人對它有歧義吧,它無非就是能夠設置最大最小長度,是否只讀,是否禁用,最多經過某種規則來限制輸入字符,最多最多,也就這些可作的了,你們都認同。

Button就不一樣了,一開始他是<input type="button" value="Click"/>,後來你們想要各類各樣的button,因而開放了<button></button>這樣的標籤,能夠在裏面寫各類HTML,我記得當時不少人在中間加上下和左右兩層marquee,簡直玩壞了。

如今HTML裏面又有了數字輸入,日期時間輸入這樣的東西,數字的沒什麼疑問,就是最大最小值,步進值等等,日期時間這個就複雜了,它怎麼作,都有人不滿意。有人要日期排左邊,有人要時間排上面,有人只要年和月,有人只要分和秒。有人要點空白表示選中,有人要雙擊日期表示選中,還有人想用農曆、波斯歷、尼泊爾歷,簡直沒完了,還不如不作,誰要誰本身作……

因此,面向各領域的人們,本身動手,豐衣足食吧。

#6. 界面修飾

好了,控件集的問題解決了,咱們來看看界面的修飾。

大家發現沒有,無論用什麼非HTML的標籤體系,可能寫代碼會很快,可是有時候要修飾界面,好比只是調整一下全部容器的邊距,某些按鈕的圓角之類,就會生不如死。

這時候你會發現,HTML裏面的CSS真是神器,什麼都能幹,並且是面向切面的,只要你的HTML結構是良好的,徹底不須要調整這個層面的代碼。爲何其餘體系的CSS沒有這麼強呢?好比說Flex也能夠寫CSS,QT也能夠寫CSS。

由於CSS的部分實在是太複雜了,複雜到整個瀏覽器裏面絕大部分的代碼都在處理這方面的東西,像Google的Chrome團隊有1000多人,別的體系無法有這麼大投入,只能看着羨慕。

上次看到一個問題,近30年來軟件開發體系有哪些本質的改進?我以爲CSS真的能夠入選,這是一個把結構和展示徹底分離的典範,而且實現得很好。

咱們的前端開發通常都是面向某個領域的,無論什麼領域,CSS方向均可以有一個很獨立的規劃,由於它能夠不影響界面的結構。因此這個方面,其實不太會對前端開發形成太多壓力,壓力只集中在維護CSS的人羣身上。

好了,上面扯了那麼多,其實到如今還在界面的層次,一直沒有去談到真正的邏輯。那麼,最讓咱們困擾的部分是哪裏呢?

#7. 模塊化和加載

Web前端開發有個最苦悶的事情就是選型,由於HTML這個體系很開放,提供的默認能力又不是很足夠,若是要作複雜交互的東西,會須要不少額外的工做。有各類框架從各類角度來解決問題,但怎麼把這些東西整合到正好符合本身的須要,是一個很花精力的事情,不少時候巴不得本身把所有輪子都造一遍。

真正的開發工做中,跨瀏覽器,踩各類坑應該是最煩悶的事,其餘部分,若是有作好本身領域裏標籤的定義,或者不用標籤用其餘方式,應該不算特別困難。

有人說JavaScript語言自己比較鬆散,因此寫業務邏輯比較頭疼,這不算大問題。基於B/S的開發,有一個大坑是你在運行的時候要先把代碼加載過來,而後才能跑。你看那些C/S軟件,有這困擾嗎?再看看後端程序員,誰還要關心本身的代碼執行以前要作的事情?

因此後端程序員寫前端代碼,都不由自主地會引入一大堆庫。咱們形象一點來描述一下這個過程:

嗯,你們都用jQuery,我也引入,抄了兩段代碼發現真不錯。咦,我要個樹控件,網上逛了一圈,拿了個zTree回來。再埋頭苦幹半個小時,缺數據表格控件,因而過了一會,jQuery UI被總體引入了。再埋頭苦幹,上網亂點了點,瀏覽器跳出個廣告,一看叫作Kendo UI,看看發現不錯,引進來再說,用裏面的某個控件。又過了一陣,據說最近Angular很火啊,看了看例子,表單功能怎麼那麼強,我也要用!搗鼓搗鼓又加進去了。項目裏又要用圖表庫,看了半天眼睛都花了,百度的ECharts不錯哦,引進來。哎呀我界面怎麼那麼醜,人家的怎麼那麼清爽,查看源碼,一看,Bootstrap,去官網一看,真乃神器,不用簡直對不起本身。

沒多久以後,這個界面已經融合了各類主流框架,代碼寫法五花八門,依賴了幾M的JS庫,更要命的是裏面某些JS有衝突,某些樣式也互相覆蓋,快瘋了。

這裏有哪些問題呢?

  • JS代碼要先加載到界面才能執行,而這麼幾M的代碼加載過來就要很久了,而後每一個框架還要把本身初始化,又耗很多時間,半分鐘以後本身寫的JS纔開始執行,用戶等得都快懷孕了。
  • 無論是JS仍是CSS,都應當控制基準的代碼,這件事的主要意義是避免衝突,由於整個體系都比較鬆散,若是不加控制,就會形成衝突。即便在服務端寫Java,也有類簽名一致性之類的問題,因此這個部分必需要重視。

剛纔這兩點,第二點暫時不是咱們要探討的範圍,第一點,引出的話題就是異步加載,這是一個能夠展開說不少的話題,也再也不說了。異步加載和緩存是面對複雜場景必作的優化措施。

可是這個裏面規範就有好幾種,具體實現方式就更多了。ES6的module也許能夠解決這個問題。harmony:modules [ES Wiki]

#8. 邏輯的分層

網站型和應用型Web程序對分層的需求是不同的。網站型的邏輯大部分都在處理UI,而應用型可能有不少業務邏輯,這部分須要更好的組織,以便複用,或者即便咱們的目標不包括複用,爲了這個代碼的可維護性,也須要有比較好的組織方式。

本質上這些組織方式與傳統的客戶端軟件開發沒什麼不一樣,主要要作的無非就是UI層的隔離,或者模板化,或者別的什麼方式。純邏輯的代碼你們都會寫,但這個邏輯怎麼跟界面產生關係,這是個問題。

有些框架經過在HTML元素上設置額外屬性,而後啓動的時候讀取,在框架內部作一些相關的事情,好比Angular、Avalon和Knockout。有的框架在視圖層中讓開發人員手動去處理界面,就像未引入框架的那樣,好比Backbone,二者是各有利弊的。

前面這種,通常功能是會很強大,可是它自身所作的東西必須足夠多,多得幫你作掉絕大部分原本該本身作的事,你纔會特別爽。因此,用這類框架來作表單型應用的時候,是會很是舒服的,由於這些需求他作框架的時候能預見,因此好比校驗、聯動、存取之類的都會處理掉。假如你要作一個繪圖類應用,這就麻煩了,無論你是用Canvas仍是SVG,它所能幫到的都很少。這時候,後面這類可能反而適合一些。

這些數據分層框架的原理是什麼呢?是要作一層表單與數據的對應關係,因此他要檢測數據的變更,好比一個Object,它某個值變動了,要去把對應的界面更改之類。這裏面也有不少的坑,能夠一步一步踩過來。。。

到如今,我大體能夠回答你的問題,什麼狀況下前端開發會比較輕鬆呢?

  • 針對本身領域的界面標籤庫比較完善,或者易於擴展
  • 樣式容易調整,而且獨立於界面元素
  • 邏輯模塊化,井井有條,在某種統一規範上存在大量可用庫

咦,我這三點好像在說微軟的WPF體系嗎?

相關文章
相關標籤/搜索