移動端H5預加載方案

移動端H5預加載方案

最近對移動端預加載方案進行了一些調研整理此文備忘分享css

prefetch

prefetch是一種瀏覽器機制,其利用瀏覽器空閒時間來下載或預取用戶在不久的未來可能訪問的文檔。網頁向瀏覽器提供一組預取提示,並在瀏覽器完成當前頁面的加載後開始靜默地拉取指定的文檔並將其存儲在緩存中。當用戶訪問其中一個預取文檔時,即可以快速的從瀏覽器緩存中獲得。html

<link rel="prefetch" href="/images/big.jpeg">
複製代碼

Can I usereact

preload

<link> 元素的 rel 屬性的屬性值preload可以讓你在你的HTML頁面中 <head>元素內部書寫一些聲明式的資源獲取請求,能夠指明哪些資源是在頁面加載完成後即刻須要的。對於這種即刻須要的資源,你可能但願在頁面加載的生命週期的早期階段就開始獲取,在瀏覽器的主渲染機制介入前就進行預加載。這一機制使得資源能夠更早的獲得加載並可用,且更不易阻塞頁面的初步渲染,進而提高性能。本文提供了一個如何有效使用preload機制的基本說明。webpack

<link rel="preload" href="style.css" as="style">
<link rel="preload" href="main.js" as="script">
複製代碼

Can I useweb

prefetch & preload 小結

上文主要截取了MDN上的文章簡要介紹一下prefetch和preload的特性,看起來其實都還不錯可是兼容性有些堪憂對於多數的業務開發看起來是並不能投入使用的,若是想了解更多關於 prefetch和 preload 的細節能夠閱讀文章底部的參考連接chrome

webpack對prefetch 和 preload的支持

如今大多數人都是使用webpack作爲構建工具若是你所參與的項目只須要兼容較高的版本的瀏覽器那麼你能夠輕鬆的依靠webpack 完成預加載功能,webpack 魔法註釋就能夠完成向引用的頁面自動添加 preload & prefetch link 標籤的能力。json

webpack 魔法註釋

經過添加內聯的註釋賦予import()動態加載語法更多實用的特性,好比給chunk命名,使用不一樣的webpackMode,prefetch,preload 等。瀏覽器

import(
  /* webpackInclude: /\.json$/ */
  /* webpackExclude: /\.noimport\.json$/ */
  /* webpackChunkName: "my-chunk-name" */  `賦予 chunk 指定的名字`
  /* webpackMode: "lazy" */  `這個是默認值使用import()你什麼也不加默認就是這個mode`
  /* webpackPrefetch: true */ `賦予 chunk prefetch能力`
  /* webpackPreload: true */`賦予 chunk preload能力`
  `./locale/${language}`
);
複製代碼

webpack魔法註釋佔位符

在 webpack 2.6.0 支持倆個佔位符[index][request]一個是自增id,一個是變量匹配的文件名緩存

import(/* webpackChunkName: "[request]" */ `../${component}/index`)//最終生成的chunkname就是對應組件的目錄名稱相似這種'_some-component_index-[hash].js`
複製代碼

react-loadable 預加載

由於咱們使用的react技術棧且同時也正在使用react-loadable加載異步組件,且react-loadable也自帶預加載功能因此最終選擇的使用react-loadable的預加載功能。react-router

react-loadable預加載跟webpack自動插入link標籤的方式不一樣它是在觸發preload方法時直接將對應的script標籤插入body下,下載完畢直接執行,好處能就是這個不須要考慮兼容性穩穩的均可以,美中不足呢就是直接執行了js不過影響不大由於只是執行的異步組件的定義,而組件的生命週期函數並無執行(稍微解釋一下爲何只執行定義而不執行生命週期,由於在使用異步加載組件必然都會配合react-router使用,因此在A頁面預加載B可是並不會執行B生命週期函數)

// 官方DEMO
const LoadableBar = Loadable({
  loader: () => import('./Bar'),
  loading: Loading,
});

class MyComponent extends React.Component {
  state = { showBar: false };

  onClick = () => {
    this.setState({ showBar: true });
  };

  onMouseOver = () => {
    LoadableBar.preload();
  };

  render() {
    return (
      <div> <button onClick={this.onClick} onMouseOver={this.onMouseOver}> Show Bar </button> {this.state.showBar && <LoadableBar/>} </div>
    )
  }
}
複製代碼

總結

preload & prefetch 等等新標準看起來都很美好只是瀏覽器支持狀況不是那麼理想很難直接投入使用,網上介紹這些特性的文章蠻多的不過讀的時候要注意時效性。

webpack 內置支持了preload & prefetch相信不久的未來經過webpack輕鬆的完成預加載會是最普遍簡單的作法

react-loadable 插件解決了當前的燃眉之急能夠兼容低版本的瀏覽器做爲項目預加載方案使用

參考

一籮筐的預加載技術

prefetch和預加載實踐

preload,prefetch 和它們在chrome中的優先級

react代碼分割

相關文章
相關標籤/搜索