h 5ハイブリッド開発ロード最適化問題

6382 ワード

1、問題の説明
プロジェクトでは、微信公衆番号(すなわち、H 5ページ)とアンドロイドとiOSの2種類のappが存在し、appではH 5ページの一部の業務コードと関連機器の詳細ページが呼び出されたが、appでWebViewキャッシュを設定すると、ページを切り替えたときにデータがタイムリーに更新されていないことに気づき、appがwebviewキャッシュを放棄した.その結果,appからH 5に入るたびにH 5関連リソースがロードされ,ロードが遅くなる.
WebViewの4つのキャッシュ・メカニズム:
// LOAD_CACHE_ONLY:      ,         

// LOAD_NO_CACHE:      ,        .

// LOAD_DEFAULT: (  )  cache-control           。

// LOAD_CACHE_ELSE_NETWORK,     ,      ,  no-cache,         。

2、方向の最適化
1、H 5ページオンデマンドロード
まず、WebViewがH 5ページをロードする場合、できるだけ必要なページリソースだけをロードし、webpack構成とvue-routerに合わせて、より便利に実現することができます.
vue-routerが提供するルーティングの怠惰なロードは主にwebpackのコード分割とvueの非同期コンポーネントに依存し、webpackは2つの方式の分離方式を提供した:1、es 6が提供するimport()すなわちvue-routerが推薦する方法、2、webpack特定のrequire.ensure.
具体的には次のように使用します.
const chunkname1 = r => require.ensure([], () => r(require('@/components/chunkname1.vue')), 'chunkname-1')

ここでchunkname-1は入力されたchunkNameであり、本当に各chunkを独立させるには、各chunk名に異なる名前を付ける必要があります.chunkNameが同じであると、同じ名前のchunkが同じjsに打たれます.
Webpack構成のoutputに設定、すなわち出力と命名し、chunkFilename:utils.assetsPath( js/[id].[hash].js )
idについて
ここでidはwebpackのモジュールidであり、読みにくいのでnameに置き換えることができ、
すなわちchunkFilename:utils.assetsPath(js/[name].[hash].js)、この名前はchunk nameであり、値は上の「chunkname-1」である.
hashについて
utils.assetsPath(js/[name].[hash].js)のhashには、次の3つの値があります.
1、hash、エンジニアリングレベル、すなわち、いずれかのファイルを変更するたびに、すべてのファイル名のhash至が変更されます.
2、chunkhashは、異なるエントリファイル(Entry)に基づいて依存ファイル解析を行い、対応するchunkを構築し、対応するハッシュ値を生成する.
3、contenthashはファイルの内容レベルに対して、あなた自身のモジュールの内容が変わっただけで、hash値は変わります
2.WebViewロードブロックについて
一部の共通のサードパーティ製ライブラリファイルでは、変更することは少なく、静的リソースとしてパッケージ化してappローカルに直接配置することができます.appアクセス時に、このリソースの一部をブロックしてローカルリソースを直接使用し、最初のロードを高速化します.
具体的な実現構想は以下の通りである.
1.Dll pluginを使用して、事前に第三者の資源を梱包し、新しいdllを生成する.jsとmanifest.jsonファイル、dll.jsはパッケージ化されたサードパーティリソースであり、jsonはその依存ファイルである.参照:https://blog.csdn.net/cjvalue/article/details/100083323
2、npm run buildで生産バージョンコードを構築する時、DllReferencePluginプラグインの構成を加えて、すでにDllでパッケージ化した第三者資源ファイルを排除して、生産のvendor-asyncを減少する.js体積
new webpack.DllReferencePlugin({
        context: path.resolve(__dirname, '..'), 
        manifest: require('../static/dll/vendor-manifest.json')
    }),

*dll.jsはindexを導入する.htmlではscriptタグを直接使用するかadd-asset-html-webpack-pluginプラグインでdllを導入することができる.jsファイル3、dllパッケージを開発環境に適用することで、開発中にプロジェクトを構築する時間を節約でき、webpack-bundle-analyzerは現在の構築を分析改善することができる.
3、nginxキャッシュの問題について
WebViewで独自のキャッシュを使用するとデータに異常が発生しますが、nginxでは静的リソースファイルのみがキャッシュされます.jsとcssファイルの設定に関連する有効期限を一致させることで、できるだけ大きな時間を設定します.
location ~.*\.(js|css)$
{
    root  /nginx/dist/;
    expires    30d; ##        max,           
}

ここで注意したいのは、webpackのoutputのchunkFilenameに合わせて使用する必要があるので、使用をお勧めします
chunkFilename: utils.assetsPath(js/[name].[chunkhash].js)

*vueプロジェクトでは、ルート怠惰ロード方式でxxを変更する.vueファイルは少なくともappを引き起こす.chunkhash.js、manifest.chunkhash.jsとそのファイル自体が生成するxx.chunkhash.js.
app.chunkhash.jsはこのvueのxxを参照するためである.chunkhash.jsのchunkhashが変わります.
mainfest.chunkhash.jsが変わったのはmainfestのせいだ.chunkhash.jsにこのvueを含むjs生成時のchunkhash,参照名変更,mainfest.chunkhash.js変化
3、その他の方面の最適化
1、プリフェッチ/プリロードモジュール(prefetch/preload)
つまり、ネットワークの空き時間にユーザーがアクセスできるモジュールのリソースファイルをロードします.
prefetch(プリフェッチ):将来のナビゲーションに必要なリソース
preload(プリロード):現在のナビゲーションでリソースが必要になる場合があります
importメソッドを使用できます
const LoginModal = import(/* webpackPrefetch: true */ 'LoginModal');
const ChartingLibrary = import(/* webpackPreload: true */ 'ChartingLibrary');

2、iconfont
H 5では、ページをより美しく見せるために多くのアイコンを使用することができる、SVGやスプライトなどを使用すると、関連するファイルを変更するたびに、iconfontを使用するにはindexのみが必要になる.htmlで関連する参照アドレス名を変更しても、ピクチャキャッシュの問題を考慮する必要はありません.
3、第三発CDN資源を直接引用する
4、コード圧縮合併
Webpackプラグインuglifyjs-webpack-pluginを参照できます
5、serviceWorker
サービスWorkerの登録
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js').then(function(registration) {
    // Registration was successful
    console.log('ServiceWorker registration successful with scope: ',    registration.scope);
  }).catch(function(err) {
    // registration failed :(
    console.log('ServiceWorker registration failed: ', err);
  });
}

リソースのキャッシュ
var cacheName = 'v1';
var assetsToCache = [
  '/styles/main.css',
  '/script/main.js'
];

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(cacheName).then(function(cache) {
      return cache.addAll(assetsToCache);
    }).then(function() {
      return self.skipWaiting();
    })
  );
});

要求をブロックし、キャッシュからリソースを取得
self.addEventListener('fetch', function(event) {
  var requestUrl = new URL(event.request.url);
  if (requestUrl.origin === location.origin) {
      if (requestUrl.pathname === '/') {
      event.respondWith(
        caches.open(cacheName).then(function(cache) {
          return fetch(event.request).then(function(networkResponse) {
            cache.put(event.request, networkResponse.clone());
            return networkResponse;
          }).catch(function() {
            return cache.match(event.request);
          });
        })
      );
    }
  }

  event.respondWith(
    caches.match(event.request).then(function(response) {
      return response || fetch(event.request);
    })
  );
});

キャッシュ制御の更新
var OFFLINE_PREFIX = 'offline-';
var CACHE_NAME = 'main_v1.0.0';
self.addEventListener('activate', function(event) {
  var mainCache = [CACHE_NAME];
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          if ( mainCache.indexOf(cacheName) === -1 && cacheName.indexOf(OFFLINE_PREFIX) === -1 ) {
            // When it doesn't match any condition, delete it.
            console.info('SW: deleting ' + cacheName);
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
  return self.clients.claim();
});

*serviceWorkerは主にキャッシュの問題を処理し、web Workerは主に計算の問題を処理する(詳細は以下を参照:https://blog.csdn.net/cjvalue/article/details/97921396)