2017年WEB開發知識分享會議

做者:縱橫
連接:https://www.zhihu.com/question/64300184/answer/231367777
來源:知乎
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。

什麼作分享的大佬回答了我還要出來回答呢:由於大佬們講的太好了!javascript

聽完以後以爲應該寫下來,否則之後就忘了。css


上午場

0x0000

騰訊副總Rose在conf開始以前發表了開幕詞,回顧了他的光榮歷史。2003年是Windows客戶端的天下(電腦版QQ)。2005年Web開始發力(QQ空間、QQ郵箱),性能優化這些問題開始受到重視。2009年達到巔峯,前端團隊規模達到幾十人。2012年,隨着APP的興起,Web日漸衰落。可是在今天Web仍有立錐之地,敏捷開發、混合開發、H5,造成了一股新熱潮。html

感受低頭走路的時候也要擡頭看看,時代在進步,變亦變,不變亦變。在最後的時候一位導師說的話挺讓人有感觸:大家首先是工程師,而後纔是前端工程師。

0x0001

第一場是W3C交互技術負責人Philippe分享的《Now and the Future》。這位大佬一口純正的英國口音,表示理解無能,只能看着PPT勉強理解一下了。Philippe回顧了W3C歷史上的豐功偉績。還順便科普了一下草案的制定過程,聽得半懂:前端

  • Working Draft(打算推動)
  • Candidate Recommendation(收集資料)
  • Proposed Recommendation(定稿)
  • W3C Recommendation(你們承認)

以後Philippe從幾個方面,講了一下如今(已經被支持)及將來的發展方向。我印象比較深的是渲染、安全、媒體、通訊還有新應用這些。vue

  • 性能:
    • requestAnimateFrame(幀級別的定時器)
    • will-change(CSS動畫的預加載)
    • Web assembly(前端使用匯編)
    • 生命週期(參見vue等)
  • 安全:
    • refer(預防csrf)
    • httpOnly(預防XSS)
    • authorization(存放身份信息)
    • secure content(不太懂)
  • 通訊
    • service worker(後面有PWA講到了,感受是個代理)
    • 消息推送(服務端主動推送消息)
  • 應用
    • VR、AR等

Philippe還鼓勵在座的大佬們共同參與W3C的制定,並給出了github地址java

在提問中有一個頗有意思的問題:前端發展愈來愈快,W3C會不會跟不上前端界的發展。Philippe老爺子很自信的回答:不會的,瀏覽器廠商一直在抱怨咱們的標準制定的太快了,他們來不及實現。年輕人,先有標準,纔有瀏覽器實現。

0x0002

說實話,我以爲Michael Yeung的分享《PWA與AWP》帶給個人收穫最大,惋惜忘記給大佬點讚了。react

大佬一上來就指出了前端發展的幾個問題:android

  • APP的使用量遠遠大於Web
  • 用戶在top3的APP上花了80%的時間(28定律)
  • 世界目前APP的月均每人下載量爲0

這樣一來Web不是沒救了。不甘寂寞的前端程序員提出了AMP。AMP是一種規範,用來提升網頁加載速度,想要給用戶帶來和原生APP同樣的體驗。webpack

他的原理其實就是經過約束程序員隨意的代碼,犧牲少部分功能,提升加載速度。AMP必須遵照下面幾條規範:ios

  • 使用圖片、視頻資源,必須指定長寬,防止迴流(從新渲染)形成的卡頓
  • 不容許使用同步JS
  • 不容許在頁面直接引用第三方JS(能夠封裝組件)
  • 只容許內聯CSS

而後,大佬介紹了AMP的進階版PWA。PWA比他的老爸更像原生APP。想要具備原生APP的如下特色:

  • 可靠(斷網也能加載出來)
  • 快速(一次下載就能飛起來)
  • 吸引(和原生同樣豐富的API,大佬說這個目前有點虛)

要有這些功能該怎麼辦呢,只能由瀏覽器放權,提供接口給Web。其實我的理解小程序或許就是一個PWA(提供了大量接口的Web)。當前瀏覽器(safari不支持)提供的接口有:

  • 獨立的任務詳情頁
  • 本地快捷圖標
  • 資源存儲可控

前兩個是瀏覽器提供的,和開發者沒什麼關係。因此詳細講了前端開發者如何控制資源的緩存和請求。這裏主要用到的是service worker。service worker實際上是一個用JS代碼實現的代理層。web要請求html、css、圖片資源的時候,都要通過service worker的代理。

  • service worker攔截到請求的時候,也能夠選擇從本地獲取緩存,若是有就返回給web。(又快又可靠,惋惜不是最新的)
  • service worker攔截到請求的時候,能夠選擇先從internet上獲取,若是獲取不到就讀取本地緩存,返回給web。(又新又快又可靠)

大佬爲了讓臺下的小白能快速上手,貼心的講解了一下service worker的生命週期。register的時候加載所要執行的js,install的時候緩存本地資源,active的時候實現代理邏輯(能夠先讀本地,也能夠先讀remote)。

Show me the code!首先要先判斷瀏覽器是否支持service worker。若是支持的話就能夠執行某個js文件了。

if (navigator.serviceWorker) {
    navigator.serviceWorker.register('worker.js').then(function(registration) {
        console.log('regist success');
    }).catch(function (err) {
        console.log('regist error')
    });
}

接着在worker文件裏定義install,緩存須要存儲的文件。

var cacheFiles = [
    'index.html'
];
self.addEventListener('install', function (evt) {
    evt.waitUntil(
        caches.open('my-test-cahce-v1').then(function (cache) {
            return cache.addAll(cacheFiles);
        })
    );
});

這時候斷開網絡,打開頁面,發現仍是顯示了404,這是由於咱們沒有攔截fetch請求。

self.addEventListener('fetch', function (evt) {
    evt.respondWith(
        caches.match(evt.request).then(function(response) {
            if (response) {
                return response;
            }
            var request = evt.request.clone();
            return fetch(request).then(function (response) {
                if (!response && response.status !== 200 && !response.headers.get('Content-type').match(/image/)) {
                    return response;
                }
                var responseClone = response.clone();
                caches.open('my-test-cache-v1').then(function (cache) {
                    cache.put(evt.request, responseClone);
                });
                return response;
            });
        })
    )
});

這樣就大功告成了。在用戶第二次打開頁面的時候,service worker就會直接代理請求,加載緩存在本地的文件了。

這裏有觀衆提問:這樣實現和long cache有什麼區別呢?Michael 的原話我記不太清了。大意是,這種實現方式是瀏覽器放權的一種思想,將資源加載徹底交由開發者處理。

0x0003

Limin zhu大佬帶來的是《Typescript》(這位大佬最終成了本期最佳講師)。Z老師安利的確實很棒,以前也有不少人推薦過ts,現在下定決心用一用了。

Z老師一上來就指出了前端開發的苦逼現狀,70%時間在讀代碼,25%時間在改bug,5%時間在寫需求。做爲一個大四的百度實習生,表示真的很對啊,真的很想去作新需求啊!Z老師一波安利,使用了ts和vscode可讓咱們65%的時間在讀代碼,20%的時間在改bug,15%的時間在寫需求。仍是至關的誘人的。

如何快速上手ts,Z老師的給出了一個從未見過、及其方便的方案。首先你要有一個vscode,換編輯器吧,騷年。而後你只須要在頭部註釋@ts-check 就能夠對全文進行檢驗了,你在編碼的時候編輯器就會提示你可能出現的錯誤。注意,類型的註釋格式必須和下面代碼同樣。

// @ts-check

/**
 *  @type {number}
 */

let test = 'hello world'
//提示:[js] Type '"hello world"' is not assignable to type 'number'.

大佬還演示瞭如何使用typescript工具編譯ts文件爲javascript 。直接上代碼吧,首先要安裝typescript。

npm install -g typescript

我這裏就使用官網的示例文件了,你也能夠本身編寫一個ts文件。

// 注意看person後面的string類型聲明
function greeter(person: string) {
    return "Hello, " + person;
}

var user = "Jane User";

document.body.innerHTML = greeter(user);

而後運行編譯就能夠咯,很簡單。

tsc greeter.ts

固然,實際項目中咱們不可能這樣使用,一般咱們會結合webpack打造一個自動化的工做流。使用ts-loader就能夠咯。固然還能夠輔助sourcemap這些工具進行調試。

module: {
    loaders: [
      { test: /\.ts$/, loader: 'ts-loader' }
    ]
  }

大佬還演示瞭如何在react項目中使用ts,這裏我就再也不粘貼代碼過來了,我對比了一下大佬的代碼,發現好像就是這個github的。

0x0004

喵喵喵?這個大佬在說啥。狂記了一波筆記,回來瞭解一下再寫。

上午過得仍是挺快的,進門就領了牌子、衣服、本子、筆。會場挺大的,坐在前面看的很清楚。總的來講舉辦的真不錯。不過一天下來真的困的要死啊,程序員爲什麼要爲難程序員呢。明天再來接着寫吧。

下午場

0x0000

聽完上午大牛的分享,就跑去樓下吃午飯。主辦安排的時間太緊湊了,吃完就又跑回分會場,準備聽下午的分享。下午分紅了三個分會場,Node.js、框架性能、綜合會場。其實仍是挺想聽Node.js的,可是感受框架性能分會場的比較適合個人業務場景,因此仍是去了框架性能分會場。

0x0001

百度外賣的林溪大佬爲咱們帶來的是《Tree-Shaking》。

什麼是tree shaking呢。直接翻譯過來應該是搖樹。把樹上枯萎的葉子、果子搖下來,樹就會變得更美觀、更容易把養料用在該用的地方。tree shaking就是搖代碼這棵樹,在編碼完成後,去掉沒有用的代碼。

tree shaking有什麼意義呢:

  • 減小網絡傳輸的體積
  • 提升加載速度
  • 減少代碼包

目前有三種tree shaking的工具:

  • roll up(開山)
  • webpack(uglify支持)
  • closure compiler(配置比較複雜)

tree shaking的原理是這樣的:

  • 消除Dead code(不會執行或者結果不會用到)
  • 消除無用模塊

消除無用模塊是基於ES6來講的,因爲ES6模塊具備如下特徵,因此能夠在靜態檢驗的時候就能夠肯定依賴,消除不須要引用的部分。

  • 只能在頂層做用域出現(通常寫在最前面)
  • 名稱只能是常量不可更改

這裏大佬特別指出,對於那些函數式編程的庫,消除模塊的做用比較明顯。由於函數式編程能夠規避動態訪問,tree shaking能夠放心的去掉靜態檢驗中沒有引用的函數。

這裏我按照大佬的講解配置了一下webpack.config.js

new webpack.optimize.UglifyJsPlugin({
      beautify: false,
      comments: false,
      compress: {
        warnings: false,
        drop_console: true,
        collapse_vars: true,
        reduce_vars: true
      }
})

若是你使用了antd大佬還給你提供了babel-plugin-import-fix

import {Button} from 'antd';

主要實現的功能就是把上面的內容變成下面的。

import {Button} from 'antd/lib/button';
import 'antd/lib/button/style'

不只js能夠tree shaking,css也能夠。大佬好像是基於postcss的解析作的。根據大佬所說,他只對class和id作了tree shaking,而沒有動僞類等等。其實我的感受,有的時候我也會拼接class,這樣來看應該是會有反作用報錯的吧。下載插件後這樣使用。

var ExtractTextPlugin = require('extract-text-webpack-plugin')
const CssTreeShakingPlugin = require("webpack-css-treeshaking-plugin")

module.exports = {
  plugins: [
    new CssTreeShakingPlugin({
      remove: false,
      ignore: ['state-\d']
    }),
    new ExtractTextPlugin({
      filename: 'build/style.css'
    })
  ]
};

大佬最後總結了一波他的探索過程,大佬在對比結果的時候使用的工具頗有意思,你們能夠從這裏下載,在每次打包以後能夠分析各個文件大小,繪製出交互圖像。

最後,要保證tree shaking的效果,請遵循如下兩點建議:

  • 使用eslint作檢查
  • 函數式編程
最後有一個大佬提問:咱們也在作tree-shaking,發現對於有些庫效果不明顯,只能減小10+kb,應該怎樣處理。回答是這樣的:tree-shaking如今還處於實踐階段,可是總有一天咱們能夠消除無用的代碼。(膜)

0x0002

徐傑大佬講解的是《RN在QQ空間中的應用》。其實這幾天React真的很不太平,先是Wordpress改版成React,而後React又不給用了。接着百度內部全面剔除React。想着聽聽算了,不過徐傑大佬應該是架構師這一層面的吧,給出了不少本身的考慮和思路,大團隊使用RN的考慮仍是很讓人耳目一新的。

徐傑大佬主要講的是一個在手Q中(ios)的頁面。一上來大佬就先分析了在用RN改版前的加載耗時狀況:

  • Webview啓動耗時(最多,然而H5不可控)
  • 請求資源耗時
  • 頁面渲染耗時

爲了突破webview耗時過多的瓶頸,才把H5重構成RN的。聽說每多等一秒,就有不少轉化率流失。(說服產品的好理由啊,彰顯前端價值)。

然而使用RN也有如下的顧慮:

  • 性能
  • 可靠性(紅屏)
  • 組件化(可複用)

最後大佬提出了兩種解決思路:

  • 業務拆包
    • base bundle一併下發
    • task bundle按需下發
  • 降級方案
    • 默認使用RN方案(成功率有96%,其他好像都是網絡環境的緣由失敗)
    • 若是失敗使用H5降級方案(這裏須要原生同窗幫忙)
效率問題是全部前端開發者注重的大問題。爲了提升加載速度,不斷折騰,或許是前端最有趣的事情之一吧。

0x0003

王躍大佬帶來的是《小程序核心架構剖析》。同行的小夥伴原本是不想聽的,結果聽了以後的評價是:這是本次conf乾貨最多的一個分享(他好像也沒來的及投票)。

根據大佬的解說,初步瞭解了小程序的盛況,騰訊內部有100+小程序,外部有?(這裏保密了)個小程序,小程序的入口就有50多個(應該是算上了各類卡片、推送等等的吧)。接着大佬分享了對小程序的分析。

小程序編譯後的靜態文件分爲如下幾部分:

  • WAService(邏輯)
  • WAWebview(視圖)
  • WAConsole(調試)
  • app-config(全部配置項,包括一些默認的)
  • app-service(全局邏輯,包括global這些)
  • page_frame.html(模板)
  • pages(css樣式)

他們是這樣編譯來的:

  • WXML ==> page_frame
  • WXSS ==> page
  • js ==> WXService
  • json ==> app-config

在運行時,小程序開了2兩個webview(感受像是兩個線程),他們之間的通訊經過jsBridge傳遞到native,再由native傳遞迴jsBridge。主要的傳遞方法我就記住了webkit上的postmessage和addEventlist。

WAwebview主要以webkit爲內核,主要跑瞭如下文件:

  • WAWebview.js
  • page-frame.html
  • page

WAwebview主要提供瞭如下服務:(感受就是react的做用)

  • component
  • API(主要是給component調用的)
  • render
  • event
  • jsBridge
  • reporter

WAservice在PC上是webkit內核,在ios上是JScore內核,在android上是V8內核,這樣作的目的是精簡內核,畢竟webkit裏有不少用不到的東西。而PC主要用於調試,選以前的技術棧就能夠了。主要跑瞭如下文件:

  • WAservice.js
  • app-config.js
  • app-service.js

WAservice主要提供瞭如下服務:(感受就是redux的做用)

  • API(全局)
  • module
  • global
  • reporter

接着大佬根據原理,講解了一些小技巧:

  • page:通常不超過5個,超事後小程序就會自動複用
  • size: 通常不超過2M
  • Dom: 通常不超過16000
  • Data: 會佔用內存,數據傳輸jsBridge會耗時,只要setData本身有用的資源就能夠了
  • 動畫:能夠用css3解決
  • 請求:小程序使用的是service worker
  • 渲染:diff算法
  • 預加載優化
    • 小程序會在打開一個頁面的時候,先加載下一個頁面的page_frame,加載時會自動拷貝page對象,所以,咱們能夠提早在page對象裏注入數據。
    • 開發者能夠本身預測用戶可能會點擊的下一個頁面,並將數值緩存到localstorage
    • 對媒體資源如圖片等設定長寬,防止reflow的時候畫面閃動(AMP)

 

良心之做,會後給大佬微信,沒想到大佬竟然回我了,終於找到了小程序源碼。原來大佬是android翻的文件,雙擊666。難怪我在PC上硬是沒找到編譯後的文件,不知道攔截上傳行不行。

0x0004

林子傑大佬分享的是《頁面性能體系的評估》,這位大佬很像個人一個師兄,好年輕啊。

大佬首先推薦了scrat框架,包含了腳手架、測試等不少功能。接着,大佬演示瞭如何使用scrat和UC瀏覽器進行性能優化。在例子中主要用的技巧是:

  • require.sync
  • settimeout(balabala,0)

那麼性能測試應該包含哪些維度呢:

  • 谷歌瀏覽器
    • FP 首次繪製時間
    • FMP 關鍵內容繪製時間(這個比較難以測量)
    • TTI 可交互時間(全部都加載完,用戶能夠點擊)
  • UC瀏覽器
    • responsetime T0 (服務器返回)
    • 首次繪製內容 T1 (有東西顯示)
    • 繪製滿屏內容 T2 (html和css完成)
    • 加載完全部資源 T3 (圖片和媒體資源)

根據頁面種類不一樣,所須要重視的維度也有所不一樣:

  • 營銷遊戲:T三、FPS(流暢度)
  • Feed流: T一、T2
  • 長列表: T一、T二、FPS

根據網絡環境不一樣,對指標的要求也有所不一樣:

  • WIFI環境
    • 普通頁面在1000ms以內
    • 視頻等富媒體頁面在2000ms以內
  • 2G/3G/4G(因爲網絡環境不穩定,通常看比例)
    • 1s佔比
    • 2s佔比
    • 3s佔比

性能優化後如何進行調試:

  • 線下
    • 真機調試
    • 內核工具
    • 測試平臺
  • 線上
    • API
window.chrome.loadTimes() //谷歌

幾種常見的優化方法:

  • 優化圖片佔比
  • 優化整體size
  • T1/T2分析
    • 能夠將部分T1資源後置到T2
    • 能夠考慮localstorage是否合適
  • JS耗時分析(斷點調試長耗時算法)
  • 排版渲染(防止迴流等)
  • 提升緩存命中機率
之前沒注意到還有這麼多接口能夠查看統計數據,UC瀏覽器的接口好像比chrome多封裝了一些,有空用用看。有個嘉賓提問:UC封裝了這麼多統計接口,會不會影響頁面加載?回答:不會的,能夠切換實驗環境和實際環境。

0x0006

好了,到這裏就基本結束了。中間的茶點和充電寶很棒。很感謝IMWeb提供了這個機會,讓咱們向大佬們學習。建議你明年一塊兒去咯~說不定還能見面呢,一塊兒學習。能力有限,記得很少(也不必定準),很差意思了。

相關文章
相關標籤/搜索